rayzee 7.10.2 → 7.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -141,7 +141,7 @@
141
141
  return seed;
142
142
 
143
143
  }
144
- `,[ae,ie]),_e={ALWAYS:`always`,PER_CYCLE:`per_cycle`,PER_TILE:`per_tile`,CONDITIONAL:`conditional`},ve=class{constructor(e,t={}){this.name=e,this.enabled=t.enabled!==!1,this.executionMode=t.executionMode||_e.ALWAYS,this.context=null,this.eventBus=null}initialize(e,t){this.context=e,this.eventBus=t,this.setupEventListeners()}setupEventListeners(){}shouldExecuteThisFrame(e){if(!this.enabled)return!1;let t=e.getState(`renderMode`)||0,n=e.getState(`tileRenderingComplete`);switch(this.executionMode){case _e.ALWAYS:return!0;case _e.PER_CYCLE:return t===0?!0:n===!0;case _e.PER_TILE:return!0;case _e.CONDITIONAL:return this.shouldExecute(e);default:return this.warn(`Unknown execution mode: ${this.executionMode}`),!0}}shouldExecute(e){return!0}render(e,t){throw Error(`render() must be implemented in ${this.name}`)}reset(){}setSize(e,t){}dispose(){}emit(e,t){this.eventBus&&this.eventBus.emit(e,t)}on(e,t){this.eventBus&&this.eventBus.on(e,t)}once(e,t){this.eventBus&&this.eventBus.once(e,t)}off(e,t){this.eventBus&&this.eventBus.off(e,t)}enable(){this.enabled||(this.enabled=!0,this.emit(`stage:enabled`,{stage:this.name}))}disable(){this.enabled&&(this.enabled=!1,this.emit(`stage:disabled`,{stage:this.name}))}toggle(){this.enabled?this.disable():this.enable()}isEnabled(){return this.enabled}log(...e){console.log(`[${this.name}]`,...e)}warn(...e){console.warn(`[${this.name}]`,...e)}error(...e){console.error(`[${this.name}]`,...e)}},ye=class{constructor(e,t,n={}){this.renderer=e,this.material=t,this.interactionModeEnabled=n.enabled===void 0?!0:n.enabled,this.interactionDelay=n.delay||100,this.interactionMode=!1,this.interactionTimeout=null,this.originalValues={},this.wasAccumulationEnabled=!0,this.interactionQualitySettings={maxBounceCount:1,useEnvMapIS:!1,enableAccumulation:!1,...n.qualitySettings},this.onEnterCallback=n.onEnter||null,this.onExitCallback=n.onExit||null,this.onResetCallback=n.onReset||null}enterInteractionMode(){this.interactionModeEnabled&&(this.interactionMode?clearTimeout(this.interactionTimeout):(this.interactionMode=!0,this.originalValues={},this.material.uniforms.enableAccumulation&&(this.wasAccumulationEnabled=this.material.uniforms.enableAccumulation.value),Object.keys(this.interactionQualitySettings).forEach(e=>{e===`pixelRatio`?(this.originalValues.dpr=this.renderer.getPixelRatio(),this.renderer.setPixelRatio(this.interactionQualitySettings.pixelRatio)):e===`enableAccumulation`||this.material.uniforms[e]&&(this.originalValues[e]=this.material.uniforms[e].value,this.material.uniforms[e].value=this.interactionQualitySettings[e])}),this.material.uniforms.enableAccumulation&&(this.originalValues.enableAccumulation=this.material.uniforms.enableAccumulation.value,this.material.uniforms.enableAccumulation.value=!1),this.material.uniforms.cameraIsMoving&&(this.originalValues.cameraIsMoving=this.material.uniforms.cameraIsMoving.value,this.material.uniforms.cameraIsMoving.value=!0),this.onEnterCallback&&this.onEnterCallback()),this.interactionTimeout=setTimeout(()=>{this.exitInteractionMode()},this.interactionDelay))}exitInteractionMode(){this.interactionMode&&(Object.keys(this.originalValues).forEach(e=>{e===`dpr`?this.renderer.setPixelRatio(this.originalValues.dpr):this.material.uniforms[e]&&(this.material.uniforms[e].value=this.originalValues[e])}),this.interactionMode=!1,this.originalValues={},this.onExitCallback&&this.onExitCallback(),this.onResetCallback&&this.onResetCallback())}updateInteractionMode(e){e&&this.enterInteractionMode()}setInteractionModeEnabled(e){this.interactionModeEnabled=e,!e&&this.interactionMode&&(clearTimeout(this.interactionTimeout),this.exitInteractionMode())}updateQualitySettings(e){Object.assign(this.interactionQualitySettings,e),this.interactionMode&&Object.keys(e).forEach(t=>{t===`pixelRatio`?this.renderer.setPixelRatio(e.pixelRatio):this.material.uniforms[t]&&(this.material.uniforms[t].value=e[t])})}setInteractionDelay(e){this.interactionDelay=e}getState(){return{interactionMode:this.interactionMode,interactionModeEnabled:this.interactionModeEnabled,interactionDelay:this.interactionDelay,hasTimeout:this.interactionTimeout!==null,qualitySettings:{...this.interactionQualitySettings},originalValues:{...this.originalValues},wasAccumulationEnabled:this.wasAccumulationEnabled}}forceExitInteractionMode(){this.interactionTimeout&&=(clearTimeout(this.interactionTimeout),null),this.exitInteractionMode()}isInInteractionMode(){return this.interactionMode}setCallbacks(e){e.onEnter&&(this.onEnterCallback=e.onEnter),e.onExit&&(this.onExitCallback=e.onExit),e.onReset&&(this.onResetCallback=e.onReset)}static createQualityPreset(e){let t={"ultra-low":{maxBounceCount:1,useEnvMapIS:!1,pixelRatio:.125,enableAccumulation:!1},low:{maxBounceCount:1,useEnvMapIS:!1,pixelRatio:.25,enableAccumulation:!1},medium:{maxBounceCount:2,useEnvMapIS:!0,pixelRatio:.5,enableAccumulation:!1},high:{maxBounceCount:3,useEnvMapIS:!0,pixelRatio:.75,enableAccumulation:!0}};return t[e]||t.low}dispose(){this.interactionTimeout&&=(clearTimeout(this.interactionTimeout),null),this.interactionMode&&this.forceExitInteractionMode(),this.onEnterCallback=null,this.onExitCallback=null,this.onResetCallback=null}},F={RENDER_COMPLETE:`engine:renderComplete`,RENDER_RESET:`engine:renderReset`,FRAME:`engine:frame`,DENOISING_START:`engine:denoisingStart`,DENOISING_END:`engine:denoisingEnd`,UPSCALING_START:`engine:upscalingStart`,UPSCALING_PROGRESS:`engine:upscalingProgress`,UPSCALING_END:`engine:upscalingEnd`,LOADING_UPDATE:`engine:loadingUpdate`,LOADING_RESET:`engine:loadingReset`,STATS_UPDATE:`engine:statsUpdate`,OBJECT_SELECTED:`engine:objectSelected`,OBJECT_DESELECTED:`engine:objectDeselected`,OBJECT_DOUBLE_CLICKED:`engine:objectDoubleClicked`,SELECT_MODE_CHANGED:`engine:selectModeChanged`,OBJECT_TRANSFORM_START:`engine:objectTransformStart`,OBJECT_TRANSFORM_END:`engine:objectTransformEnd`,TRANSFORM_MODE_CHANGED:`engine:transformModeChanged`,AUTO_FOCUS_UPDATED:`engine:autoFocusUpdated`,AUTO_EXPOSURE_UPDATED:`engine:autoExposureUpdated`,AF_POINT_PLACED:`engine:afPointPlaced`,SETTING_CHANGED:`engine:settingChanged`,ANIMATION_STARTED:`engine:animationStarted`,ANIMATION_PAUSED:`engine:animationPaused`,ANIMATION_STOPPED:`engine:animationStopped`,ANIMATION_FINISHED:`engine:animationFinished`,VIDEO_RENDER_PROGRESS:`engine:videoRenderProgress`,VIDEO_RENDER_COMPLETE:`engine:videoRenderComplete`,DISPOSE:`engine:dispose`,DEVICE_LOST:`engine:deviceLost`},be=null;function xe(e){be=e}var Se=()=>be?.({type:F.LOADING_RESET}),I=e=>{be?.({type:F.LOADING_UPDATE,...e})},Ce=e=>{be?.({type:F.STATS_UPDATE,...e})};function L(e){return e.frameCount||0}function we(e){if(Array.isArray(e))e.forEach(e=>{e.userData&&e.userData.isFallback||(Te(e),e.dispose())});else{if(e.userData&&e.userData.isFallback)return;Te(e),e.dispose()}}function Te(e){e&&[`alphaMap`,`aoMap`,`bumpMap`,`clearcoatMap`,`clearcoatNormalMap`,`clearcoatRoughnessMap`,`displacementMap`,`emissiveMap`,`envMap`,`gradientMap`,`lightMap`,`map`,`metalnessMap`,`normalMap`,`roughnessMap`,`specularMap`,`sheenColorMap`,`sheenRoughnessMap`,`specularIntensityMap`,`specularColorMap`,`thicknessMap`,`transmissionMap`].forEach(t=>{e[t]&&(e[t].dispose(),e[t]=null)})}function Ee({material:e,geometry:t,children:n}){if(e&&we(e),t&&t.dispose(),n.length>0)for(let e of n)Ee(e)}function R(e,t=[]){if(e&&!(t.includes(e.name)||e.isScene)){if(e.isMaterial){we(e);return}for(;e.children.length>0;)for(let t of e.children)R(t);Ee(e),e.removeFromParent(),e.clear()}}function De(e,t){return t}function Oe(e,t=!1){return t?1:1/(e+1)}function z(){let e=0,t=0,n=0,r=0;return{start(){e=performance.now()},end(){t=performance.now();let i=t-e;return r+=i,n++,i},getAverageFrameTime(){return n>0?r/n:0},getFPS(){let e=this.getAverageFrameTime();return e>0?1e3/e:0},reset(){n=0,r=0}}}var B={resolution:512,canvasWidth:512,canvasHeight:512,maxTextureSize:4096,toneMapping:4,exposure:1,saturation:1.2,enableEnvironment:!0,showBackground:!0,transparentBackground:!1,useImportanceSampledEnvironment:!0,environmentIntensity:1,backgroundIntensity:1,backgroundColor:`#000000`,backgroundBlurriness:0,backgroundBlurSamples:8,environmentRotation:270,groundProjectionEnabled:!1,groundProjectionRadius:100,groundProjectionHeight:15,groundProjectionLevel:0,enableGroundCatcher:!1,groundCatcherHeight:0,globalIlluminationIntensity:1,environmentMode:`hdri`,gradientZenithColor:`#0077BE`,gradientHorizonColor:`#87CEEB`,gradientGroundColor:`#654321`,solidSkyColor:`#87CEEB`,skySunAzimuth:90,skySunElevation:20,skySunIntensity:15,skyRayleighDensity:.9,skyTurbidity:.8,skyMieAnisotropy:.76,skyPreset:`clearMorning`,enableDOF:!1,fov:55,focusDistance:.8,aperture:5.6,focalLength:50,apertureScale:1,anamorphicRatio:1,autoFocusMode:`auto`,afScreenPoint:{x:.5,y:.5},afSmoothingFactor:.15,enablePathTracer:!0,enableAccumulation:!0,pauseRendering:!1,maxSamples:60,bounces:3,transmissiveBounces:5,maxSubsurfaceSteps:8,samplingTechnique:3,enableEmissiveTriangleSampling:!1,emissiveBoost:1,temporalVarianceWeight:.6,enableEarlyTermination:!0,earlyTerminationThreshold:.002,performanceModeAdaptive:`medium`,fireflyThreshold:3,wavefrontSortMaterials:!0,renderLimitMode:`frames`,renderTimeLimit:30,renderMode:0,enableAlphaShadows:!1,tilesHelper:!0,showLightHelper:!1,directionalLightIntensity:0,directionalLightColor:`#ffffff`,directionalLightPosition:[1,1,1],directionalLightAngle:0,filterStrength:.75,strengthDecaySpeed:.05,edgeThreshold:1,enableOIDN:!1,oidnQuality:`fast`,debugGbufferMaps:!1,enableUpscaler:!1,upscalerScale:2,upscalerQuality:`fast`,upscalerHdr:!0,debugMode:0,debugThreshold:100,debugModel:0,enableBloom:!1,bloomStrength:.2,bloomRadius:.15,bloomThreshold:.85,interactionModeEnabled:!0,debugVisScale:100,denoiserStrategy:`none`,enableASVGF:!1,asvgfTemporalAlpha:.1,asvgfAtrousIterations:8,asvgfPhiColor:10,asvgfPhiNormal:128,asvgfPhiDepth:1,asvgfVarianceBoost:1,asvgfMaxAccumFrames:32,asvgfGradientStrength:0,asvgfGradientSigmaScale:2,asvgfGradientNoiseFloor:0,asvgfDebugMode:0,asvgfQualityPreset:`medium`,showAsvgfHeatmap:!1,autoExposure:!1,autoExposureKeyValue:.18,autoExposureMinExposure:.1,autoExposureMaxExposure:20,autoExposureAdaptSpeedBright:3,autoExposureAdaptSpeedDark:.5},V=.01,H=2048,U={low:{temporalAlpha:.1,gradientStrength:.8,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:3,phiColor:1,phiNormal:64,phiDepth:.1,phiLuminance:6,maxAccumFrames:16,varianceBoost:.5},medium:{temporalAlpha:.03,gradientStrength:1,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:4,phiColor:.5,phiNormal:128,phiDepth:.05,phiLuminance:4,maxAccumFrames:64,varianceBoost:1},high:{temporalAlpha:0,gradientStrength:1,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:6,phiColor:.3,phiNormal:256,phiDepth:.02,phiLuminance:2,maxAccumFrames:128,varianceBoost:1.5}},ke={fov:{min:10,max:90,default:B.fov},focusDistance:{min:.3,max:100,default:B.focusDistance},aperture:{options:[1.4,2,2.8,4,5.6,8,11,16],default:B.aperture},focalLength:{min:0,max:200,default:B.focalLength}},Ae={clearMorning:{name:`Clear Morning`,sunAzimuth:90,sunElevation:20,sunIntensity:15,rayleighDensity:.9,turbidity:.8},clearNoon:{name:`Clear Noon`,sunAzimuth:0,sunElevation:75,sunIntensity:20,rayleighDensity:1,turbidity:.3},overcast:{name:`Overcast`,sunAzimuth:0,sunElevation:45,sunIntensity:6,rayleighDensity:.6,turbidity:4},goldenHour:{name:`Golden Hour`,sunAzimuth:270,sunElevation:10,sunIntensity:19,rayleighDensity:.8,turbidity:1.2},sunset:{name:`Sunset`,sunAzimuth:270,sunElevation:2,sunIntensity:18,rayleighDensity:.7,turbidity:2},dusk:{name:`Dusk`,sunAzimuth:270,sunElevation:-8,sunIntensity:8,rayleighDensity:.5,turbidity:1.5}},je={portrait:{name:`Portrait`,description:`Shallow depth of field, background blur`,fov:45,focusDistance:1.5,aperture:1.4,focalLength:135,apertureScale:1.5},landscape:{name:`Landscape`,description:`Maximum depth of field, everything in focus`,fov:65,focusDistance:10,aperture:16,focalLength:24,apertureScale:.5},macro:{name:`Macro`,description:`Extreme close-up with thin focus plane`,fov:40,focusDistance:.3,aperture:2,focalLength:100,apertureScale:2},product:{name:`Product`,description:`Sharp detail with subtle background separation`,fov:50,focusDistance:.8,aperture:2.8,focalLength:85,apertureScale:1},architectural:{name:`Architectural`,description:`Wide view with deep focus`,fov:75,focusDistance:5,aperture:11,focalLength:16,apertureScale:.5},cinematic:{name:`Cinematic`,description:`Dramatic depth separation with anamorphic bokeh`,fov:35,focusDistance:3,aperture:1.4,focalLength:200,apertureScale:1.8,anamorphicRatio:1.5}},Me={MANUAL:`manual`,AUTO:`auto`},Ne={SMOOTHING_FACTOR:.15,RESET_THRESHOLD:.05,FALLBACK_DISTANCE:10,SNAP_THRESHOLD:.5},W={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},G={SLOTS_PER_MATERIAL:30,FLOATS_PER_MATERIAL:120,IOR:0,TRANSMISSION:1,THICKNESS:2,EMISSIVE_INTENSITY:3,ATTENUATION_COLOR:4,ATTENUATION_DISTANCE:7,OPACITY:8,SIDE:9,TRANSPARENT:10,ALPHA_TEST:11,ALPHA_MODE:12,DEPTH_WRITE:13,NORMAL_SCALE:14,COLOR:16,METALNESS:19,EMISSIVE:20,ROUGHNESS:23,ALBEDO_MAP_INDEX:24,NORMAL_MAP_INDEX:25,ROUGHNESS_MAP_INDEX:26,METALNESS_MAP_INDEX:27,EMISSIVE_MAP_INDEX:28,BUMP_MAP_INDEX:29,CLEARCOAT:30,CLEARCOAT_ROUGHNESS:31,DISPERSION:32,VISIBLE:33,SHEEN:34,SHEEN_ROUGHNESS:35,SHEEN_COLOR:36,SPECULAR_INTENSITY:40,SPECULAR_COLOR:41,IRIDESCENCE:44,IRIDESCENCE_IOR:45,IRIDESCENCE_THICKNESS_RANGE:46,BUMP_SCALE:48,DISPLACEMENT_SCALE:49,DISPLACEMENT_MAP_INDEX:50,ALBEDO_TRANSFORM:52,NORMAL_TRANSFORM:60,ROUGHNESS_TRANSFORM:68,METALNESS_TRANSFORM:76,EMISSIVE_TRANSFORM:84,BUMP_TRANSFORM:92,DISPLACEMENT_TRANSFORM:100,SUBSURFACE_COLOR:108,SUBSURFACE:111,SUBSURFACE_RADIUS:112,SUBSURFACE_RADIUS_SCALE:115,SUBSURFACE_ANISOTROPY:116,SLOT:{IOR_TRANSMISSION:0,ATTENUATION:1,OPACITY_ALPHA:2,ALPHA_MODE:3,COLOR_METALNESS:4,EMISSIVE_ROUGHNESS:5,MAP_INDICES_A:6,MAP_INDICES_B:7,DISPERSION_SHEEN:8,SHEEN_COLOR:9,SPECULAR:10,IRIDESCENCE:11,BUMP_DISPLACEMENT:12,ALBEDO_TRANSFORM_A:13,ALBEDO_TRANSFORM_B:14,NORMAL_TRANSFORM_A:15,NORMAL_TRANSFORM_B:16,ROUGHNESS_TRANSFORM_A:17,ROUGHNESS_TRANSFORM_B:18,METALNESS_TRANSFORM_A:19,METALNESS_TRANSFORM_B:20,EMISSIVE_TRANSFORM_A:21,EMISSIVE_TRANSFORM_B:22,BUMP_TRANSFORM_A:23,BUMP_TRANSFORM_B:24,DISPLACEMENT_TRANSFORM_A:25,DISPLACEMENT_TRANSFORM_B:26,SUBSURFACE_A:27,SUBSURFACE_B:28,SUBSURFACE_C:29}},Pe={TRIANGLE_LEAF:-1,BLAS_POINTER_LEAF:-2},K={PIXELS_PER_MATERIAL:30,RGBA_COMPONENTS:4,VEC4_PER_TRIANGLE:8,VEC4_PER_BVH_NODE:4,FLOATS_PER_VEC4:4,MIN_TEXTURE_WIDTH:4,MAX_CONCURRENT_WORKERS:Math.min(typeof navigator<`u`&&navigator.hardwareConcurrency||4,6),BUFFER_POOL_SIZE:20,CANVAS_POOL_SIZE:12,CACHE_SIZE_LIMIT:50,MAX_TEXTURE_SIZE:8192,DEFAULT_MAX_TEXTURE_SIZE:4096,MAX_TEXTURES_LIMIT:128,MATERIAL_BUCKET_COUNT:4,BUCKET_LAYER_STRIDE:256};function q(e,t=K.MATERIAL_BUCKET_COUNT){let n=[];for(let r=t-1;r>=0;r--)n.push(Math.max(K.MIN_TEXTURE_WIDTH,Math.round(e/2**r)));return n}function Fe(e,t,n,r=K.MATERIAL_BUCKET_COUNT){let i=2**Math.ceil(Math.log2(Math.max(e||1,t||1))),a=q(n,r);for(let e=0;e<a.length;e++)if(i<=a[e])return e;return a.length-1}function Ie(e,t){return e*K.BUCKET_LAYER_STRIDE+t}var Le=[0,0,1,1,0,0,0,1],Re={maxSamples:30,bounces:20,transmissiveBounces:8,maxSubsurfaceSteps:64,renderMode:1,enableAlphaShadows:!0,enableOIDN:!0,oidnQuality:`balance`,interactionModeEnabled:!1},ze={maxSamples:B.maxSamples,bounces:B.bounces,renderMode:B.renderMode,enableAlphaShadows:B.enableAlphaShadows,transmissiveBounces:B.transmissiveBounces,maxSubsurfaceSteps:B.maxSubsurfaceSteps,enableOIDN:!1,oidnQuality:`fast`,interactionModeEnabled:!0},Be={MAX_BUFFER_MEMORY:1024*1024*1024,MAX_TEXTURE_MEMORY:2048*1024*1024,CLEANUP_THRESHOLD:.8,CHUNK_SIZE_THRESHOLD:64*1024*1024,STREAM_BATCH_SIZE:4};function Ve(){let e=new t.StorageTexture(H,H);return e.type=r.FloatType,e.format=r.RGBAFormat,e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e}var J=class{constructor(e,t){this.writeColor=null,this.writeNormalDepth=null,this.writeAlbedo=null,this.readTarget=null,this.currentTarget=0,this.renderWidth=0,this.renderHeight=0,this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),e>0&&t>0&&this.create(e,t)}create(e,n){this.dispose(),this.renderWidth=e,this.renderHeight=n,this.writeColor=Ve(),this.writeNormalDepth=Ve(),this.writeAlbedo=Ve(),this.readTarget=new t.RenderTarget(e,n,{type:r.FloatType,format:r.RGBAFormat,minFilter:r.NearestFilter,magFilter:r.NearestFilter,depthBuffer:!1,stencilBuffer:!1,count:3}),this.readTarget.textures[0].name=`gColor`,this.readTarget.textures[1].name=`gNormalDepth`,this.readTarget.textures[2].name=`gAlbedo`,console.log(`StorageTexturePool: Created ${e}x${n} (3 write StorageTextures + 1 MRT RenderTarget)`)}ensureSize(e,t){return this.writeColor?this.renderWidth!==e||this.renderHeight!==t?(this.setSize(e,t),!0):!1:(this.create(e,t),!0)}getReadTextures(){return{color:this.readTarget.textures[0],normalDepth:this.readTarget.textures[1],albedo:this.readTarget.textures[2]}}getWriteTextures(){return{color:this.writeColor,normalDepth:this.writeNormalDepth,albedo:this.writeAlbedo}}copyToReadTargets(e,t=!0){this._srcRegion.max.set(this.renderWidth,this.renderHeight),e.copyTextureToTexture(this.writeColor,this.readTarget.textures[0],this._srcRegion),t&&(e.copyTextureToTexture(this.writeNormalDepth,this.readTarget.textures[1],this._srcRegion),e.copyTextureToTexture(this.writeAlbedo,this.readTarget.textures[2],this._srcRegion))}clear(e){if(!this.readTarget||!e)return;let t=e.getRenderTarget();e.setRenderTarget(this.readTarget),e.clear(!0,!1,!1),e.setRenderTarget(t)}swap(){this.currentTarget=1-this.currentTarget}setSize(e,t){if(this.renderWidth=e,this.renderHeight=t,this.readTarget){this.readTarget.setSize(e,t);for(let e of this.readTarget.textures)e.needsUpdate=!0}}dispose(){this.writeColor?.dispose(),this.writeNormalDepth?.dispose(),this.writeAlbedo?.dispose(),this.readTarget?.dispose(),this.writeColor=null,this.writeNormalDepth=null,this.writeAlbedo=null,this.readTarget=null}},He={cameraViewMatrix:`ptCameraViewMatrix`,cameraProjectionMatrix:`ptCameraProjectionMatrix`},Ue=class{constructor(e=1920,t=1080){this._uniforms=new Map,this._booleans=new Set,this._lightBuffers={},this._initUniforms(e,t),this._nameAll()}get(e){return this._uniforms.get(e)}set(e,t){let n=this._uniforms.get(e);if(!n){console.warn(`UniformManager: Unknown uniform "${e}"`);return}this._booleans.has(e)?n.value=+!!t:typeof t==`object`&&t&&typeof n.value?.copy==`function`?n.value.copy(t):n.value=t}has(e){return this._uniforms.has(e)}keys(){return this._uniforms.keys()}getLightBufferNodes(){return this._lightBuffers}updateMany(e){let t=!1;for(let[n,r]of Object.entries(e)){let e=this._uniforms.get(n);e&&e.value!==r&&(e.value=r,t=!0)}return t}_initUniforms(e,t){let i=(e,t,r)=>{let i=(0,n.uniform)(t,r);return this._uniforms.set(e,i),i},a=(e,t)=>(this._booleans.add(e),i(e,+!!t,`int`));i(`frame`,0,`uint`),i(`maxBounces`,B.bounces,`int`),i(`maxSamples`,B.maxSamples,`int`),i(`transmissiveBounces`,B.transmissiveBounces,`int`),i(`maxSubsurfaceSteps`,B.maxSubsurfaceSteps,`int`),i(`visMode`,B.debugMode,`int`),i(`debugVisScale`,B.debugVisScale,`float`),a(`enableAccumulation`,!0),i(`accumulationAlpha`,0,`float`),a(`cameraIsMoving`,!1),a(`hasPreviousAccumulated`,!1),i(`environmentIntensity`,B.environmentIntensity,`float`),i(`backgroundIntensity`,B.backgroundIntensity,`float`),i(`backgroundColor`,new r.Color(0,0,0),`color`),i(`backgroundBlurriness`,B.backgroundBlurriness,`float`),i(`backgroundBlurSamples`,B.backgroundBlurSamples,`int`),a(`showBackground`,B.showBackground),a(`transparentBackground`,B.transparentBackground),a(`enableEnvironment`,B.enableEnvironment),i(`environmentMatrix`,new r.Matrix4,`mat4`),a(`useEnvMapIS`,B.useImportanceSampledEnvironment),i(`envTotalSum`,0,`float`),i(`envCompensationDelta`,0,`float`),i(`envResolution`,new r.Vector2(1,1),`vec2`),a(`groundProjectionEnabled`,B.groundProjectionEnabled),i(`groundProjectionRadius`,B.groundProjectionRadius,`float`),i(`groundProjectionHeight`,B.groundProjectionHeight,`float`),i(`groundProjectionLevel`,B.groundProjectionLevel,`float`),a(`enableGroundCatcher`,B.enableGroundCatcher),i(`groundCatcherHeight`,B.groundCatcherHeight,`float`),i(`sunDirection`,new r.Vector3(0,1,0),`vec3`),i(`sunAngularSize`,.0087,`float`),a(`hasSun`,!1),i(`globalIlluminationIntensity`,B.globalIlluminationIntensity,`float`),i(`exposure`,B.exposure,`float`),i(`numDirectionalLights`,0,`int`),i(`numAreaLights`,0,`int`),i(`numPointLights`,0,`int`),i(`numSpotLights`,0,`int`),this._lightBuffers={directional:(0,n.uniformArray)(new Float32Array(192),`float`),area:(0,n.uniformArray)(new Float32Array(256),`float`),point:(0,n.uniformArray)(new Float32Array(144),`float`),spot:(0,n.uniformArray)(new Float32Array(320),`float`)},i(`cameraWorldMatrix`,new r.Matrix4,`mat4`),i(`cameraProjectionMatrixInverse`,new r.Matrix4,`mat4`),i(`cameraViewMatrix`,new r.Matrix4,`mat4`),i(`cameraProjectionMatrix`,new r.Matrix4,`mat4`),a(`enableDOF`,B.enableDOF),i(`focusDistance`,B.focusDistance,`float`),i(`focalLength`,B.focalLength,`float`),i(`aperture`,B.aperture,`float`),i(`apertureScale`,1,`float`),i(`anamorphicRatio`,B.anamorphicRatio??1,`float`),i(`sceneScale`,1,`float`),this._uniforms.set(`samplingTechnique`,k),k.value=B.samplingTechnique,i(`fireflyThreshold`,B.fireflyThreshold,`float`),a(`enableEmissiveTriangleSampling`,B.enableEmissiveTriangleSampling),i(`emissiveBoost`,B.emissiveBoost,`float`),i(`emissiveTriangleCount`,0,`int`),i(`emissiveTotalPower`,0,`float`),i(`lightBVHNodeCount`,0,`int`),i(`emissiveVec4Offset`,0,`int`),i(`reverseMapVec4Offset`,0,`int`),i(`renderMode`,B.renderMode,`int`),a(`enableAlphaShadows`,B.enableAlphaShadows),i(`resolution`,new r.Vector2(e,t),`vec2`)}_nameAll(){for(let[e,t]of this._uniforms)t.name=He[e]||e}dispose(){this._disposed||(this._disposed=!0,this._uniforms.clear(),this._booleans.clear(),this._lightBuffers={})}},We=G.SLOTS_PER_MATERIAL,Ge=W.UV_C_MAT_OFFSET+2,Ke=W.NORMAL_C_OFFSET+3,qe=W.NORMAL_A_OFFSET+3,Je=new Set([`transmission`,`transparent`,`opacity`,`alphaMode`]),Ye=class{constructor(e){this.sdfs=e,this.materialStorageAttr=null,this.materialStorageNode=null,this.materialCount=0,this.srgbBuckets=null,this.linearBuckets=null,this._srgbTexPacked=null,this._linearTexPacked=null,this.compiledFeatures=null,this.callbacks={}}setMaterialData(e){if(!e)return;let r=e.length/4;this.materialStorageNode?(this.materialStorageAttr=new t.StorageInstancedBufferAttribute(e,4),this.materialStorageNode.value=this.materialStorageAttr,this.materialStorageNode.bufferCount=r):(this.materialStorageAttr=new t.StorageInstancedBufferAttribute(e,4),this.materialStorageNode=(0,n.storage)(this.materialStorageAttr,`vec4`,r).toReadOnly()),this.materialCount=Math.floor(r/We),console.log(`MaterialDataManager: ${this.materialCount} materials (storage buffer)`)}getStorageAttr(){return this.materialStorageAttr}getStorageNode(){return this.materialStorageNode}setMaterialTextures(e){e.srgbBuckets&&(this.srgbBuckets=e.srgbBuckets),e.linearBuckets&&(this.linearBuckets=e.linearBuckets)}setTexturePackMaps(e,t){this._srgbTexPacked=e||null,this._linearTexPacked=t||null}getPackedTextureIndex(e,t){if(!e)return-1;let n=e.source?.uuid??e.uuid,r=(t?this._srgbTexPacked:this._linearTexPacked)?.get(n);return r===void 0?-1:r}loadTexturesFromSdfs(){this.srgbBuckets=this.sdfs.srgbBucketTextures,this.linearBuckets=this.sdfs.linearBucketTextures,this.setTexturePackMaps(this.sdfs._srgbTexPacked,this.sdfs._linearTexPacked)}getTextureArrays(){return{srgbBuckets:this.srgbBuckets,linearBuckets:this.linearBuckets}}updateMaterialProperty(e,t,n){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let r=this.materialStorageAttr.array,i=e*G.FLOATS_PER_MATERIAL;switch(t){case`color`:n.r===void 0?Array.isArray(n)&&(r[i+G.COLOR]=n[0],r[i+G.COLOR+1]=n[1],r[i+G.COLOR+2]=n[2]):(r[i+G.COLOR]=n.r,r[i+G.COLOR+1]=n.g,r[i+G.COLOR+2]=n.b);break;case`metalness`:r[i+G.METALNESS]=n;break;case`emissive`:n.r===void 0?Array.isArray(n)&&(r[i+G.EMISSIVE]=n[0],r[i+G.EMISSIVE+1]=n[1],r[i+G.EMISSIVE+2]=n[2]):(r[i+G.EMISSIVE]=n.r,r[i+G.EMISSIVE+1]=n.g,r[i+G.EMISSIVE+2]=n.b);break;case`roughness`:r[i+G.ROUGHNESS]=n;break;case`ior`:r[i+G.IOR]=n;break;case`transmission`:r[i+G.TRANSMISSION]=n;break;case`thickness`:r[i+G.THICKNESS]=n;break;case`emissiveIntensity`:r[i+G.EMISSIVE_INTENSITY]=n;break;case`attenuationColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.ATTENUATION_COLOR]=n[0],r[i+G.ATTENUATION_COLOR+1]=n[1],r[i+G.ATTENUATION_COLOR+2]=n[2]):(r[i+G.ATTENUATION_COLOR]=n.r,r[i+G.ATTENUATION_COLOR+1]=n.g,r[i+G.ATTENUATION_COLOR+2]=n.b);break;case`attenuationDistance`:r[i+G.ATTENUATION_DISTANCE]=n;break;case`dispersion`:r[i+G.DISPERSION]=n;break;case`sheen`:r[i+G.SHEEN]=n;break;case`sheenRoughness`:r[i+G.SHEEN_ROUGHNESS]=n;break;case`sheenColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SHEEN_COLOR]=n[0],r[i+G.SHEEN_COLOR+1]=n[1],r[i+G.SHEEN_COLOR+2]=n[2]):(r[i+G.SHEEN_COLOR]=n.r,r[i+G.SHEEN_COLOR+1]=n.g,r[i+G.SHEEN_COLOR+2]=n.b);break;case`specularIntensity`:r[i+G.SPECULAR_INTENSITY]=n;break;case`specularColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SPECULAR_COLOR]=n[0],r[i+G.SPECULAR_COLOR+1]=n[1],r[i+G.SPECULAR_COLOR+2]=n[2]):(r[i+G.SPECULAR_COLOR]=n.r,r[i+G.SPECULAR_COLOR+1]=n.g,r[i+G.SPECULAR_COLOR+2]=n.b);break;case`iridescence`:r[i+G.IRIDESCENCE]=n;break;case`iridescenceIOR`:r[i+G.IRIDESCENCE_IOR]=n;break;case`iridescenceThicknessRange`:Array.isArray(n)&&(r[i+G.IRIDESCENCE_THICKNESS_RANGE]=n[0],r[i+G.IRIDESCENCE_THICKNESS_RANGE+1]=n[1]);break;case`clearcoat`:r[i+G.CLEARCOAT]=n;break;case`clearcoatRoughness`:r[i+G.CLEARCOAT_ROUGHNESS]=n;break;case`opacity`:r[i+G.OPACITY]=n;break;case`side`:r[i+G.SIDE]=n,this._patchTriangleSideForMaterial(e,n);break;case`transparent`:r[i+G.TRANSPARENT]=n;break;case`alphaTest`:r[i+G.ALPHA_TEST]=n;break;case`alphaMode`:r[i+G.ALPHA_MODE]=n;break;case`depthWrite`:r[i+G.DEPTH_WRITE]=n;break;case`normalScale`:n.x===void 0?typeof n==`number`&&(r[i+G.NORMAL_SCALE]=n,r[i+G.NORMAL_SCALE+1]=n):(r[i+G.NORMAL_SCALE]=n.x,r[i+G.NORMAL_SCALE+1]=n.y);break;case`bumpScale`:r[i+G.BUMP_SCALE]=n;break;case`displacementScale`:r[i+G.DISPLACEMENT_SCALE]=n;break;case`subsurface`:r[i+G.SUBSURFACE]=n;break;case`subsurfaceRadiusScale`:r[i+G.SUBSURFACE_RADIUS_SCALE]=n;break;case`subsurfaceAnisotropy`:r[i+G.SUBSURFACE_ANISOTROPY]=n;break;case`subsurfaceColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SUBSURFACE_COLOR]=n[0],r[i+G.SUBSURFACE_COLOR+1]=n[1],r[i+G.SUBSURFACE_COLOR+2]=n[2]):(r[i+G.SUBSURFACE_COLOR]=n.r,r[i+G.SUBSURFACE_COLOR+1]=n.g,r[i+G.SUBSURFACE_COLOR+2]=n.b);break;case`subsurfaceRadius`:Array.isArray(n)?(r[i+G.SUBSURFACE_RADIUS]=n[0],r[i+G.SUBSURFACE_RADIUS+1]=n[1],r[i+G.SUBSURFACE_RADIUS+2]=n[2]):n.x!==void 0&&(r[i+G.SUBSURFACE_RADIUS]=n.x,r[i+G.SUBSURFACE_RADIUS+1]=n.y,r[i+G.SUBSURFACE_RADIUS+2]=n.z);break;default:console.warn(`Unknown material property: ${t}`);return}this.materialStorageAttr.needsUpdate=!0,Je.has(t)&&this._recomputeOpaqueBlockerForMaterial(e),[`transmission`,`clearcoat`,`sheen`,`iridescence`,`dispersion`,`transparent`,`opacity`,`alphaTest`,`subsurface`].includes(t)&&this.rescanMaterialFeatures()&&this._notifyFeaturesChanged(),this._notifyReset()}updateMaterialDataFromObject(e,t){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let n=this.materialStorageAttr.array,r=e*G.FLOATS_PER_MATERIAL;t.color&&(n[r+G.COLOR]=t.color.r??t.color[0]??1,n[r+G.COLOR+1]=t.color.g??t.color[1]??1,n[r+G.COLOR+2]=t.color.b??t.color[2]??1),n[r+G.METALNESS]=t.metalness??0,t.emissive&&(n[r+G.EMISSIVE]=t.emissive.r??t.emissive[0]??0,n[r+G.EMISSIVE+1]=t.emissive.g??t.emissive[1]??0,n[r+G.EMISSIVE+2]=t.emissive.b??t.emissive[2]??0),n[r+G.ROUGHNESS]=t.roughness??1,n[r+G.IOR]=t.ior??1.5,n[r+G.TRANSMISSION]=t.transmission??0,n[r+G.THICKNESS]=t.thickness??.1,n[r+G.EMISSIVE_INTENSITY]=t.emissiveIntensity??1,t.attenuationColor&&(n[r+G.ATTENUATION_COLOR]=t.attenuationColor.r??t.attenuationColor[0]??1,n[r+G.ATTENUATION_COLOR+1]=t.attenuationColor.g??t.attenuationColor[1]??1,n[r+G.ATTENUATION_COLOR+2]=t.attenuationColor.b??t.attenuationColor[2]??1),n[r+G.ATTENUATION_DISTANCE]=t.attenuationDistance??1/0,n[r+G.DISPERSION]=t.dispersion??0,n[r+G.VISIBLE]=1,n[r+G.SHEEN]=t.sheen??0,n[r+G.SHEEN_ROUGHNESS]=t.sheenRoughness??1,t.sheenColor&&(n[r+G.SHEEN_COLOR]=t.sheenColor.r??t.sheenColor[0]??0,n[r+G.SHEEN_COLOR+1]=t.sheenColor.g??t.sheenColor[1]??0,n[r+G.SHEEN_COLOR+2]=t.sheenColor.b??t.sheenColor[2]??0),n[r+G.SPECULAR_INTENSITY]=t.specularIntensity??1,t.specularColor&&(n[r+G.SPECULAR_COLOR]=t.specularColor.r??t.specularColor[0]??1,n[r+G.SPECULAR_COLOR+1]=t.specularColor.g??t.specularColor[1]??1,n[r+G.SPECULAR_COLOR+2]=t.specularColor.b??t.specularColor[2]??1),n[r+G.IRIDESCENCE]=t.iridescence??0,n[r+G.IRIDESCENCE_IOR]=t.iridescenceIOR??1.3,t.iridescenceThicknessRange&&(n[r+G.IRIDESCENCE_THICKNESS_RANGE]=t.iridescenceThicknessRange[0]??100,n[r+G.IRIDESCENCE_THICKNESS_RANGE+1]=t.iridescenceThicknessRange[1]??400),n[r+G.ALBEDO_MAP_INDEX]=t.map??-1,n[r+G.NORMAL_MAP_INDEX]=t.normalMap??-1,n[r+G.ROUGHNESS_MAP_INDEX]=t.roughnessMap??-1,n[r+G.METALNESS_MAP_INDEX]=t.metalnessMap??-1,n[r+G.EMISSIVE_MAP_INDEX]=t.emissiveMap??-1,n[r+G.BUMP_MAP_INDEX]=t.bumpMap??-1,n[r+G.CLEARCOAT]=t.clearcoat??0,n[r+G.CLEARCOAT_ROUGHNESS]=t.clearcoatRoughness??0,n[r+G.OPACITY]=t.opacity??1,n[r+G.SIDE]=t.side??0,this._patchTriangleSideForMaterial(e,t.side??0),this._recomputeOpaqueBlockerForMaterial(e),n[r+G.TRANSPARENT]=t.transparent??0,n[r+G.ALPHA_TEST]=t.alphaTest??0,n[r+G.ALPHA_MODE]=t.alphaMode??0,n[r+G.DEPTH_WRITE]=t.depthWrite??1,n[r+G.NORMAL_SCALE]=t.normalScale?.x??(typeof t.normalScale==`number`?t.normalScale:1),n[r+G.NORMAL_SCALE+1]=t.normalScale?.y??(typeof t.normalScale==`number`?t.normalScale:1),n[r+G.BUMP_SCALE]=t.bumpScale??1,n[r+G.DISPLACEMENT_SCALE]=t.displacementScale??1,n[r+G.DISPLACEMENT_MAP_INDEX]=t.displacementMap??-1,n[r+G.SUBSURFACE]=t.subsurface??0,t.subsurfaceColor&&(n[r+G.SUBSURFACE_COLOR]=t.subsurfaceColor.r??t.subsurfaceColor[0]??1,n[r+G.SUBSURFACE_COLOR+1]=t.subsurfaceColor.g??t.subsurfaceColor[1]??1,n[r+G.SUBSURFACE_COLOR+2]=t.subsurfaceColor.b??t.subsurfaceColor[2]??1),t.subsurfaceRadius&&(n[r+G.SUBSURFACE_RADIUS]=t.subsurfaceRadius[0]??1,n[r+G.SUBSURFACE_RADIUS+1]=t.subsurfaceRadius[1]??.2,n[r+G.SUBSURFACE_RADIUS+2]=t.subsurfaceRadius[2]??.1),n[r+G.SUBSURFACE_RADIUS_SCALE]=t.subsurfaceRadiusScale??1,n[r+G.SUBSURFACE_ANISOTROPY]=t.subsurfaceAnisotropy??0;let i=[1,0,0,0,1,0,0,0,1],a=[{key:`mapMatrix`,offset:G.ALBEDO_TRANSFORM},{key:`normalMapMatrices`,offset:G.NORMAL_TRANSFORM},{key:`roughnessMapMatrices`,offset:G.ROUGHNESS_TRANSFORM},{key:`metalnessMapMatrices`,offset:G.METALNESS_TRANSFORM},{key:`emissiveMapMatrices`,offset:G.EMISSIVE_TRANSFORM},{key:`bumpMapMatrices`,offset:G.BUMP_TRANSFORM},{key:`displacementMapMatrices`,offset:G.DISPLACEMENT_TRANSFORM}];for(let{key:e,offset:o}of a){let a=t[e]??i;for(let e=0;e<9;e++)r+o+e<n.length&&(n[r+o+e]=a[e])}this.materialStorageAttr.needsUpdate=!0,this.rescanMaterialFeatures()&&this._notifyFeaturesChanged(),this._notifyReset()}updateMaterial(e,t){let n=this.sdfs.geometryExtractor.createMaterialObject(t);(this._srgbTexPacked||this._linearTexPacked)&&(n.map=this.getPackedTextureIndex(t.map,!0),n.emissiveMap=this.getPackedTextureIndex(t.emissiveMap,!0),n.normalMap=this.getPackedTextureIndex(t.normalMap,!1),n.bumpMap=this.getPackedTextureIndex(t.bumpMap,!1),n.roughnessMap=this.getPackedTextureIndex(t.roughnessMap,!1),n.metalnessMap=this.getPackedTextureIndex(t.metalnessMap,!1),n.displacementMap=this.getPackedTextureIndex(t.displacementMap,!1)),this.updateMaterialDataFromObject(e,n)}updateTextureTransform(e,t,n){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let r=this.materialStorageAttr.array,i=e*G.FLOATS_PER_MATERIAL,a={map:G.ALBEDO_TRANSFORM,normalMap:G.NORMAL_TRANSFORM,roughnessMap:G.ROUGHNESS_TRANSFORM,metalnessMap:G.METALNESS_TRANSFORM,emissiveMap:G.EMISSIVE_TRANSFORM,bumpMap:G.BUMP_TRANSFORM,displacementMap:G.DISPLACEMENT_TRANSFORM}[t];if(a===void 0){console.warn(`Unknown texture name for transform update: ${t}`);return}for(let e=0;e<9;e++)i+a+e<r.length&&(r[i+a+e]=n[e]);this.materialStorageAttr.needsUpdate=!0,this._notifyReset()}rescanMaterialFeatures(){if(!this.materialStorageAttr?.array)return console.warn(`[MaterialDataManager] Material storage buffer not available for feature scanning`),!1;let e=this.materialStorageAttr.array,t=this.sdfs.materialCount||1,n={hasClearcoat:!1,hasTransmission:!1,hasDispersion:!1,hasIridescence:!1,hasSheen:!1,hasTransparency:!1,hasSubsurface:!1,hasMultiLobeMaterials:!1,hasMRTOutputs:!0};for(let r=0;r<t;r++){let t=r*G.FLOATS_PER_MATERIAL,i=e[t+G.TRANSMISSION],a=e[t+G.DISPERSION],o=e[t+G.SHEEN],s=e[t+G.IRIDESCENCE],c=e[t+G.CLEARCOAT],l=e[t+G.OPACITY],u=e[t+G.TRANSPARENT],d=e[t+G.ALPHA_TEST],f=e[t+G.SUBSURFACE];c>0&&(n.hasClearcoat=!0),i>0&&(n.hasTransmission=!0),a>0&&(n.hasDispersion=!0),s>0&&(n.hasIridescence=!0),o>0&&(n.hasSheen=!0),(u>0||l<1||d>0)&&(n.hasTransparency=!0),f>0&&(n.hasSubsurface=!0),[c>0,i>0,s>0,o>0].filter(Boolean).length>=2&&(n.hasMultiLobeMaterials=!0)}let r=JSON.stringify(this.sdfs.sceneFeatures)!==JSON.stringify(n);return r&&(this.sdfs.sceneFeatures=n),r}injectMaterialFeatureDefines(){let e=this.sdfs.sceneFeatures;if(!e){console.warn(`[MaterialDataManager] No sceneFeatures detected, skipping define injection`);return}let t=JSON.stringify(e);(!this.compiledFeatures||this.compiledFeatures!==t)&&(console.log(`[MaterialDataManager] Material features:`,e),this.compiledFeatures=t)}_notifyReset(){this.callbacks.onReset&&this.callbacks.onReset()}_notifyFeaturesChanged(){this.injectMaterialFeatureDefines()}_recomputeOpaqueBlockerForMaterial(e){let t=this.materialStorageAttr?.array;if(!t)return;let n=e*G.FLOATS_PER_MATERIAL,r=t[n+G.ALPHA_MODE]|0,i=t[n+G.TRANSPARENT]|0,a=t[n+G.TRANSMISSION]||0,o=t[n+G.OPACITY]??1,s=+(r===0&&i===0&&a===0&&o>=1);this._patchTriangleFlagForMaterial(e,qe,s)}_patchTriangleFlagForMaterial(e,t,n){let r=this.callbacks.getTriangleData?.(),i=r?.array,a=r?.count|0;if(!i||a===0)return;let o=W.FLOATS_PER_TRIANGLE,s=0;for(let r=0;r<a;r++){let a=r*o;i[a+Ge]===e&&(i[a+t]=n,s++)}s>0&&this.callbacks.onTriangleDataChanged&&this.callbacks.onTriangleDataChanged()}_patchTriangleSideForMaterial(e,t){this._patchTriangleFlagForMaterial(e,Ke,t)}dispose(){this.materialStorageAttr=null,this.materialStorageNode=null,this.materialCount=0,this.srgbBuckets=null,this.linearBuckets=null,this._srgbTexPacked=null,this._linearTexPacked=null,this.compiledFeatures=null}};async function Xe(e){let t=e instanceof URL?e.href:e,n=await fetch(t);if(!n.ok)throw Error(`Failed to fetch worker script: ${n.status}`);let r=new Blob([await n.text()],{type:`application/javascript`});return new Worker(URL.createObjectURL(r),{type:`module`})}var Ze=``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/CDFWorker-BFQUr3By.js`).href:new URL(`assets/CDFWorker-BFQUr3By.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href);function Qe(e,t,n=0,r=e.length){let i=n,a=n+r-1;for(;i<a;){let n=i+a>>1;e[n]<t?i=n+1:a=n}return i-n}function $e(e,t,n){return .2126*e+.7152*t+.0722*n}function et(e){return e<=.04045?e/12.92:((e+.055)/1.055)**2.4}function tt(e){let{width:t,height:n}=e.image,i=e.image.data,a=!1;if(!i){let r=new OffscreenCanvas(t,n).getContext(`2d`);r.drawImage(e.image,0,0,t,n),i=r.getImageData(0,0,t,n).data,a=!0}let o;if(e.type===r.FloatType&&i instanceof Float32Array)o=new Float32Array(i);else if(e.type===r.HalfFloatType){o=new Float32Array(i.length);for(let e=0,t=i.length;e<t;e++)o[e]=r.DataUtils.fromHalfFloat(i[e])}else{let e;e=i instanceof Int8Array||i instanceof Int16Array||i instanceof Int32Array?2**(8*i.BYTES_PER_ELEMENT-1)-1:2**(8*i.BYTES_PER_ELEMENT)-1,o=new Float32Array(i.length);for(let t=0,n=i.length;t<n;t++)o[t]=i[t]/e}if(!a&&e.colorSpace===r.SRGBColorSpace&&(a=!0),a)for(let e=0,t=o.length;e<t;e+=4)o[e]=et(o[e]),o[e+1]=et(o[e+1]),o[e+2]=et(o[e+2]);if(e.flipY){let e=new Float32Array(o.length);for(let r=0;r<n;r++){let i=n-r-1,a=r*t*4,s=i*t*4;e.set(o.subarray(a,a+t*4),s)}o=e}return{floatData:o,width:t,height:n}}var nt=class e{constructor(){this.marginalData=new Float32Array([0,1]),this.conditionalData=new Float32Array([0,0,1,1]),this.totalSum=0,this.compensationDelta=0,this.width=0,this.height=0,this._worker=null}dispose(){this.marginalData=null,this.conditionalData=null,this._worker&&=(this._worker.terminate(),null)}updateFrom(t){let{floatData:n,width:r,height:i}=tt(t),a=e.computeCDF(n,r,i);this.marginalData=a.marginalData,this.conditionalData=a.conditionalData,this.totalSum=a.totalSum,this.compensationDelta=a.compensationDelta,this.width=r,this.height=i}async updateFromAsync(e){let{floatData:t,width:n,height:r}=tt(e);try{this._worker=new Worker(Ze,{type:`module`})}catch(e){if(e.name!==`SecurityError`)throw e;this._worker=await Xe(Ze)}try{let e=await new Promise((e,i)=>{this._worker.onmessage=t=>{t.data.error?i(Error(t.data.error)):e(t.data)},this._worker.onerror=i,this._worker.postMessage({floatData:t,width:n,height:r},[t.buffer])});this.marginalData=e.marginalData,this.conditionalData=e.conditionalData,this.totalSum=e.totalSum,this.compensationDelta=e.compensationDelta,this.width=e.width,this.height=e.height}finally{this._worker&&=(this._worker.terminate(),null)}}static computeCDF(e,t,n){let r=t*n,i=new Float32Array(r),a=0;for(let r=0;r<n;r++){let o=Math.sin(Math.PI*(r+.5)/n);for(let n=0;n<t;n++){let s=r*t+n,c=$e(e[4*s],e[4*s+1],e[4*s+2])*o;i[s]=c,a+=c}}let o=a/r,s=0;for(let e=0;e<r;e++)i[e]=Math.max(0,i[e]-o),s+=i[e];let c=s>0,l=c?s:a,u=c?o:0;if(!c)for(let r=0;r<n;r++){let a=Math.sin(Math.PI*(r+.5)/n);for(let n=0;n<t;n++){let o=r*t+n;i[o]=$e(e[4*o],e[4*o+1],e[4*o+2])*a}}let d=new Float32Array(r),f=new Float32Array(n),p=0;for(let e=0;e<n;e++){let n=0;for(let r=0;r<t;r++){let a=e*t+r;n+=i[a],d[a]=n}if(n!==0)for(let r=e*t,i=e*t+t;r<i;r++)d[r]/=n;p+=n,f[e]=p}if(p!==0)for(let e=0,t=f.length;e<t;e++)f[e]/=p;let m=new Float32Array(n),h=new Float32Array(r);for(let e=0;e<n;e++)m[e]=(Qe(f,(e+1)/n)+.5)/n;for(let e=0;e<n;e++)for(let n=0;n<t;n++){let r=e*t+n;h[r]=(Qe(d,(n+1)/t,e*t,t)+.5)/t}return{marginalData:m,conditionalData:h,totalSum:l,compensationDelta:u}}},rt=Math.PI,it=Math.PI*2,at=Math.E,ot=[5804542996261093e-21,13562911419845635e-21,30265902468824876e-21],st=[183999185144339.78,277980239196605.28,407904795438610.94],ct=1.6110731556870734,lt=1.5,ut=1e3,dt=8400,ft=1250,pt=.9999566769464484,mt=.05968310365946075,ht=.07957747154594767;function gt(e){return ut*Math.max(0,1-at**+(-(ct-Math.acos(Math.max(-1,Math.min(1,e))))/lt))}function _t(e){let t=.2*e*1e-17;return[.434*t*st[0],.434*t*st[1],.434*t*st[2]]}function vt(e){return mt*(1+e**2)}function yt(e,t){let n=t*t;return ht*((1-n)/(1-2*t*e+n)**1.5)}function bt(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function xt(e){let t=Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);return t===0?[0,0,0]:[e[0]/t,e[1]/t,e[2]/t]}function St(e,t,n,r,i,a,o,s){let c=(1-t)*rt,l=(e-.5)*it,u=Math.sin(c),d=xt([u*Math.sin(l),Math.cos(c),u*Math.cos(l)]),f=xt(n),p=gt(f[1])*r,m=i-1*(1-(1-Math.max(0,Math.min(1,1-Math.exp(f[1]/45e4))))),h=[ot[0]*m,ot[1]*m,ot[2]*m],g=_t(s),_=[g[0]*a,g[1]*a,g[2]*a],v=Math.acos(Math.max(0,d[1])),y=Math.cos(v)+.15*(93.885-180/rt*v)**-1.253,b=dt/y,x=ft/y,S=[Math.exp(-(h[0]*b+_[0]*x)),Math.exp(-(h[1]*b+_[1]*x)),Math.exp(-(h[2]*b+_[2]*x))],C=bt(d,f),w=vt(C*.5+.5),T=[h[0]*w,h[1]*w,h[2]*w],E=yt(C,o),D=[_[0]*E,_[1]*E,_[2]*E],O=[T[0]+D[0],T[1]+D[1],T[2]+D[2]],k=[h[0]+_[0],h[1]+_[1],h[2]+_[2]],A=[(p*(O[0]/k[0])*(1-S[0]))**1.5,(p*(O[1]/k[1])*(1-S[1]))**1.5,(p*(O[2]/k[2])*(1-S[2]))**1.5],j=Math.max(0,Math.min(1,1-(1-f[1])**5)),M=[Math.sqrt(p*(O[0]/k[0])*S[0]),Math.sqrt(p*(O[1]/k[1])*S[1]),Math.sqrt(p*(O[2]/k[2])*S[2])],N=1-j;for(let e=0;e<3;e++){let t=1*(1-N)+M[e]*N;A[e]*=t}let ee=[.1*S[0],.1*S[1],.1*S[2]],te=Ct(pt,pt+2e-5,C);for(let e=0;e<3;e++)ee[e]+=p*19e3*S[e]*te;let ne=65504;return[Math.min((A[0]+ee[0])*.04,ne),Math.min((A[1]+ee[1])*.04+3e-4,ne),Math.min((A[2]+ee[2])*.04+75e-5,ne),1]}function Ct(e,t,n){let r=Math.max(0,Math.min(1,(n-e)/(t-e)));return r*r*(3-2*r)}var wt=class{constructor(e=512,t=256){this.width=e,this.height=t,this.lastRenderTime=0,this._pixels=new Float32Array(e*t*4),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1}render(e){let t=performance.now(),n=[e.sunDirection.x,e.sunDirection.y,e.sunDirection.z],r=e.sunIntensity||1,i=e.rayleighDensity||2,a=e.mieDensity||.005,o=e.mieAnisotropy||.8,s=e.turbidity||2,{width:c,height:l}=this,u=this._pixels;for(let e=0;e<l;e++){let t=(e+.5)/l;for(let l=0;l<c;l++){let d=St((l+.5)/c,t,n,r,i,a,o,s),f=(e*c+l)*4;u[f]=d[0],u[f+1]=d[1],u[f+2]=d[2],u[f+3]=d[3]}}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}setResolution(e,t){this.width===e&&this.height===t||(this.width=e,this.height=t,this._pixels=new Float32Array(e*t*4),this._texture.dispose(),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1)}getLastRenderTime(){return this.lastRenderTime}dispose(){this._texture.dispose()}},Tt=class{constructor(e=512,t=256){this.width=e,this.height=t,this.lastRenderTime=0,this._pixels=new Float32Array(e*t*4),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1}renderGradient(e){let t=performance.now(),{width:n,height:r}=this,i=this._pixels,a=e.zenithColor.r,o=e.zenithColor.g,s=e.zenithColor.b,c=e.horizonColor.r,l=e.horizonColor.g,u=e.horizonColor.b,d=e.groundColor.r,f=e.groundColor.g,p=e.groundColor.b;for(let e=0;e<r;e++){let t=(e+.5)/r,m,h,g;if(t>.5){let e=(t-.5)*2;m=c+(a-c)*e,h=l+(o-l)*e,g=u+(s-u)*e}else{let e=t*2;m=d+(c-d)*e,h=f+(l-f)*e,g=p+(u-p)*e}for(let t=0;t<n;t++){let r=(e*n+t)*4;i[r]=m,i[r+1]=h,i[r+2]=g,i[r+3]=1}}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}renderSolid(e){let t=performance.now(),{width:n,height:r}=this,i=this._pixels,a=e.color.r,o=e.color.g,s=e.color.b;for(let e=0;e<r;e++)for(let t=0;t<n;t++){let r=(e*n+t)*4;i[r]=a,i[r+1]=o,i[r+2]=s,i[r+3]=1}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}setResolution(e,t){this.width===e&&this.height===t||(this.width=e,this.height=t,this._pixels=new Float32Array(e*t*4),this._texture.dispose(),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1)}getLastRenderTime(){return this.lastRenderTime}dispose(){this._texture.dispose()}},Et=class{constructor(e,t){this.scene=e,this.uniforms=t,this.equirectHdrInfo=new nt,this.proceduralSkyRenderer=null,this.simpleSkyRenderer=null,this._envPlaceholder=new r.DataTexture(new Float32Array([0,0,0,1]),1,1,r.RGBAFormat,r.FloatType),this._envPlaceholder.needsUpdate=!0,this.environmentTexture=this._envPlaceholder,this.envTexSize=new r.Vector2,this.envCDFTexture=null,this._initCDFTexture(),this.environmentRotationMatrix=new r.Matrix4,this.cdfBuildTime=0,this.envParams={mode:`hdri`,gradientZenithColor:new r.Color(B.gradientZenithColor),gradientHorizonColor:new r.Color(B.gradientHorizonColor),gradientGroundColor:new r.Color(B.gradientGroundColor),solidSkyColor:new r.Color(B.solidSkyColor),skySunDirection:this._calculateInitialSunDirection(),skySunIntensity:B.skySunIntensity,skyRayleighDensity:B.skyRayleighDensity,skyTurbidity:B.skyTurbidity,skyMieAnisotropy:B.skyMieAnisotropy},this.callbacks={},this._previousHDRI=null}async setMode(e){let t=this.envParams.mode;this.envParams.mode=e,e!==`hdri`&&t===`hdri`&&(this._previousHDRI=this.environmentTexture),e===`gradient`?await this.generateGradientTexture():e===`color`?await this.generateSolidColorTexture():e===`procedural`?await this.generateProceduralSkyTexture():e===`hdri`&&this._previousHDRI&&(await this.setEnvironmentMap(this._previousHDRI),this._previousHDRI=null),this.markDirty(),this.callbacks.onAutoExposureReset?.(),this._notifyReset()}markDirty(){this.environmentTexture&&(this.environmentTexture.needsUpdate=!0)}get params(){return this.envParams}get texture(){return this.environmentTexture}generateGradient(){return this.generateGradientTexture()}generateSolid(){return this.generateSolidColorTexture()}generateProcedural(){return this.generateProceduralSkyTexture()}_initCDFTexture(){this.envCDFTexture=new r.DataTexture(new Float32Array([0]),1,1,r.RedFormat,r.FloatType),this.envCDFTexture.needsUpdate=!0}_updateCDFTexture(){let e=this.equirectHdrInfo.marginalData,t=this.equirectHdrInfo.conditionalData;if(!e||!t)return;let n=this.equirectHdrInfo.width,i=this.equirectHdrInfo.height,a=n+1,o=new Float32Array(a*i);for(let r=0;r<i;r++){let i=r*a;o.set(t.subarray(r*n,r*n+n),i),o[i+n]=e[r]}this.envCDFTexture?.dispose?.(),this.envCDFTexture=new r.DataTexture(o,a,i,r.RedFormat,r.FloatType),this.envCDFTexture.needsUpdate=!0}setEnvironmentTexture(e){e&&(this.environmentTexture=e,this.envTexSize.set(e.image.width,e.image.height),console.log(`EnvironmentManager: Environment map ${e.image.width}x${e.image.height}`))}getEnvironmentTexture(){return this.environmentTexture}setEnvironmentRotation(e){let t=Math.PI/180*e;this.environmentRotationMatrix.makeRotationY(t),this.uniforms.get(`environmentMatrix`).value.copy(this.environmentRotationMatrix)}async buildEnvironmentCDF({useWorker:e=!0}={}){if(!this.scene.environment){this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0);return}try{let t=performance.now(),n=this.scene.environment;if(!n.image){this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0);return}e?await this.equirectHdrInfo.updateFromAsync(n):this.equirectHdrInfo.updateFrom(n),this.cdfBuildTime=performance.now()-t,this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,this.equirectHdrInfo.totalSum),this.uniforms.set(`envCompensationDelta`,this.equirectHdrInfo.compensationDelta),this.uniforms.set(`useEnvMapIS`,1);let{width:r,height:i}=this.equirectHdrInfo;r&&i&&this.uniforms.get(`envResolution`).value.set(r,i),console.log(`Environment CDF built in ${this.cdfBuildTime.toFixed(2)}ms (worker: ${e})`)}catch(e){console.error(`Error building environment CDF:`,e),this.uniforms.set(`useEnvMapIS`,0),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0)}}applyCDFResults(){let e=this.scene.environment,t=this.callbacks.getSceneTextureNodes?.();t&&e&&t.envTex&&(t.envTex.value=e),e&&!e._isGeneratedProcedural&&this.uniforms.set(`hasSun`,0)}async setEnvironmentMap(e){let t=this.environmentTexture;e&&t&&t!==e&&t!==this._envPlaceholder&&t!==this._previousHDRI&&t.dispose?.(),this.scene.environment=e,this.setEnvironmentTexture(e),e?await this.buildEnvironmentCDF():(this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0));let n=this.callbacks.getSceneTextureNodes?.();n&&e&&n.envTex&&(n.envTex.value=e),e&&!e._isGeneratedProcedural&&this.uniforms.set(`hasSun`,0),this._notifyReset()}async generateGradientTexture(){this.simpleSkyRenderer||=new Tt(512,256);let e={zenithColor:this.envParams.gradientZenithColor,horizonColor:this.envParams.gradientHorizonColor,groundColor:this.envParams.gradientGroundColor};try{let t=this.simpleSkyRenderer.renderGradient(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.set(`hasSun`,0)}catch(e){console.error(`Error generating gradient sky:`,e)}}async generateSolidColorTexture(){this.simpleSkyRenderer||=new Tt(512,256);let e={color:this.envParams.solidSkyColor};try{let t=this.simpleSkyRenderer.renderSolid(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.set(`hasSun`,0)}catch(e){console.error(`Error generating solid color sky:`,e)}}async generateProceduralSkyTexture(){this.proceduralSkyRenderer||=new wt(512,256);let e={sunDirection:this.envParams.skySunDirection.clone(),sunIntensity:this.envParams.skySunIntensity*.05,rayleighDensity:this.envParams.skyRayleighDensity*2,mieDensity:this.envParams.skyTurbidity*.005,mieAnisotropy:this.envParams.skyMieAnisotropy,turbidity:this.envParams.skyTurbidity*2};try{let t=this.proceduralSkyRenderer.render(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.get(`sunDirection`).value.copy(this.envParams.skySunDirection),this.uniforms.set(`sunAngularSize`,.0087),this.uniforms.set(`hasSun`,1),console.log(`Sun parameters synced: dir=${this.envParams.skySunDirection.toArray().map(e=>e.toFixed(2)).join(`,`)}`)}catch(e){console.error(`Error generating procedural sky:`,e)}}_calculateInitialSunDirection(){let e=B.skySunAzimuth*(Math.PI/180),t=B.skySunElevation*(Math.PI/180);return new r.Vector3(Math.cos(t)*Math.sin(e),Math.sin(t),Math.cos(t)*Math.cos(e)).normalize()}_notifyReset(){this.callbacks.onReset&&this.callbacks.onReset()}dispose(){this.proceduralSkyRenderer=null,this.simpleSkyRenderer=null,this.envCDFTexture?.dispose?.(),this.envCDFTexture=null,this.environmentTexture&&this.environmentTexture!==this._envPlaceholder&&this.environmentTexture.dispose?.(),this._envPlaceholder?.dispose(),this._envPlaceholder=null,this.environmentTexture=null,this._previousHDRI=null}},Dt=S({origin:`vec3`,direction:`vec3`}),Ot=S({color:`vec4`,emissive:`vec3`,emissiveIntensity:`float`,roughness:`float`,metalness:`float`,ior:`float`,transmission:`float`,thickness:`float`,clearcoat:`float`,clearcoatRoughness:`float`,opacity:`float`,transparent:`bool`,attenuationColor:`vec3`,attenuationDistance:`float`,dispersion:`float`,sheen:`float`,sheenRoughness:`float`,sheenColor:`vec3`,specularIntensity:`float`,specularColor:`vec3`,alphaTest:`float`,alphaMode:`int`,side:`int`,depthWrite:`int`,albedoMapIndex:`int`,emissiveMapIndex:`int`,normalMapIndex:`int`,bumpMapIndex:`int`,bumpScale:`float`,displacementScale:`float`,metalnessMapIndex:`int`,roughnessMapIndex:`int`,displacementMapIndex:`int`,normalScale:`vec2`,albedoTransform:`mat3`,emissiveTransform:`mat3`,normalTransform:`mat3`,bumpTransform:`mat3`,metalnessTransform:`mat3`,roughnessTransform:`mat3`,displacementTransform:`mat3`,iridescence:`float`,iridescenceIOR:`float`,iridescenceThicknessRange:`vec2`,subsurface:`float`,subsurfaceColor:`vec3`,subsurfaceRadius:`vec3`,subsurfaceRadiusScale:`float`,subsurfaceAnisotropy:`float`}),kt=S({color:`vec4`,ior:`float`,transmission:`float`,attenuationColor:`vec3`,attenuationDistance:`float`,albedoMapIndex:`int`,opacity:`float`,transparent:`bool`,alphaTest:`float`,alphaMode:`int`,albedoTransform:`mat3`}),At=S({shadowed:`vec3`,unoccluded:`vec3`});S({position:`vec3`,radius:`float`,material:Ot});var jt=S({didHit:`bool`,dst:`float`,hitPoint:`vec3`,normal:`vec3`,uv:`vec2`,materialIndex:`int`,meshIndex:`int`,triangleIndex:`int`,boxTests:`int`,triTests:`int`});S({posA:`vec3`,posB:`vec3`,posC:`vec3`,uvA:`vec2`,uvB:`vec2`,uvC:`vec2`,normalA:`vec3`,normalB:`vec3`,normalC:`vec3`,material:Ot,materialIndex:`int`,meshIndex:`int`}),S({color:`vec4`,samples:`int`});var Mt=S({direction:`vec3`,value:`vec3`,pdf:`float`}),Nt=S({specular:`float`,diffuse:`float`,sheen:`float`,clearcoat:`float`,transmission:`float`,iridescence:`float`}),Pt=S({diffuseImportance:`float`,specularImportance:`float`,transmissionImportance:`float`,clearcoatImportance:`float`}),Ft=S({NoL:`float`,NoV:`float`,NoH:`float`,VoH:`float`,LoH:`float`}),It=S({compensation:`vec3`,E_total:`vec3`}),Lt=S({albedo:`vec4`,emissive:`vec3`,metalness:`float`,roughness:`float`,normal:`vec3`,hasTextures:`bool`}),Rt=S({isMetallic:`bool`,isRough:`bool`,isSmooth:`bool`,isTransmissive:`bool`,hasClearcoat:`bool`,isEmissive:`bool`,complexityScore:`float`}),zt=S({albedoUV:`vec2`,normalUV:`vec2`,metalnessUV:`vec2`,emissiveUV:`vec2`,bumpUV:`vec2`,roughnessUV:`vec2`,normalBumpSameUV:`bool`,metalRoughSameUV:`bool`,albedoEmissiveSameUV:`bool`,allSameUV:`bool`}),Bt=S({F0:`vec3`,NoV:`float`,diffuseColor:`vec3`,isPurelyDiffuse:`bool`,alpha:`float`,k:`float`,alpha2:`float`,invRoughness:`float`,metalFactor:`float`,iorFactor:`float`,maxSheenColor:`float`}),Vt=S({envWeight:`float`,specularWeight:`float`,diffuseWeight:`float`,transmissionWeight:`float`,clearcoatWeight:`float`,totalWeight:`float`,useEnv:`bool`,useSpecular:`bool`,useDiffuse:`bool`,useTransmission:`bool`,useClearcoat:`bool`}),Ht=S({brdfWeight:`float`,lightWeight:`float`,envWeight:`float`,useBRDFSampling:`bool`,useLightSampling:`bool`,useEnvSampling:`bool`});S({traversals:`int`,transmissiveTraversals:`int`,rayType:`int`,isPrimaryRay:`bool`,actualBounceDepth:`int`});var Ut=3.14159,Wt=1/Ut,Gt=2*Ut,Kt=1e-6,qt=.05,Jt=.089,Yt=.001,Xt=(0,n.vec3)(.2126,.7152,.0722),Y=G.SLOTS_PER_MATERIAL,Zt=G.SLOT,X=Zt,Qt=(0,n.mat3)(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252);(0,n.wgslFn)(`
144
+ `,[ae,ie]),_e={ALWAYS:`always`,PER_CYCLE:`per_cycle`,PER_TILE:`per_tile`,CONDITIONAL:`conditional`},ve=class{constructor(e,t={}){this.name=e,this.enabled=t.enabled!==!1,this.executionMode=t.executionMode||_e.ALWAYS,this.context=null,this.eventBus=null}initialize(e,t){this.context=e,this.eventBus=t,this.setupEventListeners()}setupEventListeners(){}shouldExecuteThisFrame(e){if(!this.enabled)return!1;let t=e.getState(`renderMode`)||0,n=e.getState(`tileRenderingComplete`);switch(this.executionMode){case _e.ALWAYS:return!0;case _e.PER_CYCLE:return t===0?!0:n===!0;case _e.PER_TILE:return!0;case _e.CONDITIONAL:return this.shouldExecute(e);default:return this.warn(`Unknown execution mode: ${this.executionMode}`),!0}}shouldExecute(e){return!0}render(e,t){throw Error(`render() must be implemented in ${this.name}`)}reset(){}setSize(e,t){}dispose(){}emit(e,t){this.eventBus&&this.eventBus.emit(e,t)}on(e,t){this.eventBus&&this.eventBus.on(e,t)}once(e,t){this.eventBus&&this.eventBus.once(e,t)}off(e,t){this.eventBus&&this.eventBus.off(e,t)}enable(){this.enabled||(this.enabled=!0,this.emit(`stage:enabled`,{stage:this.name}))}disable(){this.enabled&&(this.enabled=!1,this.emit(`stage:disabled`,{stage:this.name}))}toggle(){this.enabled?this.disable():this.enable()}isEnabled(){return this.enabled}log(...e){console.log(`[${this.name}]`,...e)}warn(...e){console.warn(`[${this.name}]`,...e)}error(...e){console.error(`[${this.name}]`,...e)}},ye=class{constructor(e,t,n={}){this.renderer=e,this.material=t,this.interactionModeEnabled=n.enabled===void 0?!0:n.enabled,this.interactionDelay=n.delay||100,this.interactionMode=!1,this.interactionTimeout=null,this.originalValues={},this.wasAccumulationEnabled=!0,this.interactionQualitySettings={maxBounceCount:1,useEnvMapIS:!1,enableAccumulation:!1,...n.qualitySettings},this.onEnterCallback=n.onEnter||null,this.onExitCallback=n.onExit||null,this.onResetCallback=n.onReset||null}enterInteractionMode(){this.interactionModeEnabled&&(this.interactionMode?clearTimeout(this.interactionTimeout):(this.interactionMode=!0,this.originalValues={},this.material.uniforms.enableAccumulation&&(this.wasAccumulationEnabled=this.material.uniforms.enableAccumulation.value),Object.keys(this.interactionQualitySettings).forEach(e=>{e===`pixelRatio`?(this.originalValues.dpr=this.renderer.getPixelRatio(),this.renderer.setPixelRatio(this.interactionQualitySettings.pixelRatio)):e===`enableAccumulation`||this.material.uniforms[e]&&(this.originalValues[e]=this.material.uniforms[e].value,this.material.uniforms[e].value=this.interactionQualitySettings[e])}),this.material.uniforms.enableAccumulation&&(this.originalValues.enableAccumulation=this.material.uniforms.enableAccumulation.value,this.material.uniforms.enableAccumulation.value=!1),this.material.uniforms.cameraIsMoving&&(this.originalValues.cameraIsMoving=this.material.uniforms.cameraIsMoving.value,this.material.uniforms.cameraIsMoving.value=!0),this.onEnterCallback&&this.onEnterCallback()),this.interactionTimeout=setTimeout(()=>{this.exitInteractionMode()},this.interactionDelay))}exitInteractionMode(){this.interactionMode&&(Object.keys(this.originalValues).forEach(e=>{e===`dpr`?this.renderer.setPixelRatio(this.originalValues.dpr):this.material.uniforms[e]&&(this.material.uniforms[e].value=this.originalValues[e])}),this.interactionMode=!1,this.originalValues={},this.onExitCallback&&this.onExitCallback(),this.onResetCallback&&this.onResetCallback())}updateInteractionMode(e){e&&this.enterInteractionMode()}setInteractionModeEnabled(e){this.interactionModeEnabled=e,!e&&this.interactionMode&&(clearTimeout(this.interactionTimeout),this.exitInteractionMode())}updateQualitySettings(e){Object.assign(this.interactionQualitySettings,e),this.interactionMode&&Object.keys(e).forEach(t=>{t===`pixelRatio`?this.renderer.setPixelRatio(e.pixelRatio):this.material.uniforms[t]&&(this.material.uniforms[t].value=e[t])})}setInteractionDelay(e){this.interactionDelay=e}getState(){return{interactionMode:this.interactionMode,interactionModeEnabled:this.interactionModeEnabled,interactionDelay:this.interactionDelay,hasTimeout:this.interactionTimeout!==null,qualitySettings:{...this.interactionQualitySettings},originalValues:{...this.originalValues},wasAccumulationEnabled:this.wasAccumulationEnabled}}forceExitInteractionMode(){this.interactionTimeout&&=(clearTimeout(this.interactionTimeout),null),this.exitInteractionMode()}isInInteractionMode(){return this.interactionMode}setCallbacks(e){e.onEnter&&(this.onEnterCallback=e.onEnter),e.onExit&&(this.onExitCallback=e.onExit),e.onReset&&(this.onResetCallback=e.onReset)}static createQualityPreset(e){let t={"ultra-low":{maxBounceCount:1,useEnvMapIS:!1,pixelRatio:.125,enableAccumulation:!1},low:{maxBounceCount:1,useEnvMapIS:!1,pixelRatio:.25,enableAccumulation:!1},medium:{maxBounceCount:2,useEnvMapIS:!0,pixelRatio:.5,enableAccumulation:!1},high:{maxBounceCount:3,useEnvMapIS:!0,pixelRatio:.75,enableAccumulation:!0}};return t[e]||t.low}dispose(){this.interactionTimeout&&=(clearTimeout(this.interactionTimeout),null),this.interactionMode&&this.forceExitInteractionMode(),this.onEnterCallback=null,this.onExitCallback=null,this.onResetCallback=null}},F={RENDER_COMPLETE:`engine:renderComplete`,RENDER_RESET:`engine:renderReset`,FRAME:`engine:frame`,DENOISING_START:`engine:denoisingStart`,DENOISING_END:`engine:denoisingEnd`,UPSCALING_START:`engine:upscalingStart`,UPSCALING_PROGRESS:`engine:upscalingProgress`,UPSCALING_END:`engine:upscalingEnd`,LOADING_UPDATE:`engine:loadingUpdate`,LOADING_RESET:`engine:loadingReset`,STATS_UPDATE:`engine:statsUpdate`,OBJECT_SELECTED:`engine:objectSelected`,OBJECT_DESELECTED:`engine:objectDeselected`,OBJECT_DOUBLE_CLICKED:`engine:objectDoubleClicked`,SELECT_MODE_CHANGED:`engine:selectModeChanged`,OBJECT_TRANSFORM_START:`engine:objectTransformStart`,OBJECT_TRANSFORM_END:`engine:objectTransformEnd`,TRANSFORM_MODE_CHANGED:`engine:transformModeChanged`,AUTO_FOCUS_UPDATED:`engine:autoFocusUpdated`,AUTO_EXPOSURE_UPDATED:`engine:autoExposureUpdated`,AF_POINT_PLACED:`engine:afPointPlaced`,SETTING_CHANGED:`engine:settingChanged`,ANIMATION_STARTED:`engine:animationStarted`,ANIMATION_PAUSED:`engine:animationPaused`,ANIMATION_STOPPED:`engine:animationStopped`,ANIMATION_FINISHED:`engine:animationFinished`,VIDEO_RENDER_PROGRESS:`engine:videoRenderProgress`,VIDEO_RENDER_COMPLETE:`engine:videoRenderComplete`,DISPOSE:`engine:dispose`,DEVICE_LOST:`engine:deviceLost`},be=null;function xe(e){be=e}var Se=()=>be?.({type:F.LOADING_RESET}),I=e=>{be?.({type:F.LOADING_UPDATE,...e})},Ce=e=>{be?.({type:F.STATS_UPDATE,...e})};function L(e){return e.frameCount||0}function we(e){if(Array.isArray(e))e.forEach(e=>{e.userData&&e.userData.isFallback||(Te(e),e.dispose())});else{if(e.userData&&e.userData.isFallback)return;Te(e),e.dispose()}}function Te(e){e&&[`alphaMap`,`aoMap`,`bumpMap`,`clearcoatMap`,`clearcoatNormalMap`,`clearcoatRoughnessMap`,`displacementMap`,`emissiveMap`,`envMap`,`gradientMap`,`lightMap`,`map`,`metalnessMap`,`normalMap`,`roughnessMap`,`specularMap`,`sheenColorMap`,`sheenRoughnessMap`,`specularIntensityMap`,`specularColorMap`,`thicknessMap`,`transmissionMap`].forEach(t=>{e[t]&&(e[t].dispose(),e[t]=null)})}function Ee({material:e,geometry:t,children:n}){if(e&&we(e),t&&t.dispose(),n.length>0)for(let e of n)Ee(e)}function R(e,t=[]){if(e&&!(t.includes(e.name)||e.isScene)){if(e.isMaterial){we(e);return}for(;e.children.length>0;)for(let t of e.children)R(t);Ee(e),e.removeFromParent(),e.clear()}}function De(e,t){return t}function Oe(e,t=!1){return t?1:1/(e+1)}function z(){let e=0,t=0,n=0,r=0;return{start(){e=performance.now()},end(){t=performance.now();let i=t-e;return r+=i,n++,i},getAverageFrameTime(){return n>0?r/n:0},getFPS(){let e=this.getAverageFrameTime();return e>0?1e3/e:0},reset(){n=0,r=0}}}var B={resolution:512,canvasWidth:512,canvasHeight:512,maxTextureSize:4096,toneMapping:4,exposure:1,saturation:1.2,enableEnvironment:!0,showBackground:!0,transparentBackground:!1,useImportanceSampledEnvironment:!0,environmentIntensity:1,backgroundIntensity:1,backgroundColor:`#000000`,backgroundBlurriness:0,backgroundBlurSamples:8,environmentRotation:270,groundProjectionEnabled:!1,groundProjectionRadius:100,groundProjectionHeight:15,groundProjectionLevel:0,enableGroundCatcher:!1,groundCatcherHeight:0,globalIlluminationIntensity:1,environmentMode:`hdri`,gradientZenithColor:`#0077BE`,gradientHorizonColor:`#87CEEB`,gradientGroundColor:`#654321`,solidSkyColor:`#87CEEB`,skySunAzimuth:90,skySunElevation:20,skySunIntensity:15,skyRayleighDensity:.9,skyTurbidity:.8,skyMieAnisotropy:.76,skyPreset:`clearMorning`,enableDOF:!1,fov:55,focusDistance:.8,aperture:5.6,focalLength:50,apertureScale:1,anamorphicRatio:1,autoFocusMode:`auto`,afScreenPoint:{x:.5,y:.5},afSmoothingFactor:.15,enablePathTracer:!0,enableAccumulation:!0,pauseRendering:!1,maxSamples:60,bounces:3,transmissiveBounces:5,maxSubsurfaceSteps:8,samplingTechnique:3,enableEmissiveTriangleSampling:!1,emissiveBoost:1,temporalVarianceWeight:.6,enableEarlyTermination:!0,earlyTerminationThreshold:.002,performanceModeAdaptive:`medium`,fireflyThreshold:3,wavefrontSortMaterials:!0,renderLimitMode:`frames`,renderTimeLimit:30,renderMode:0,enableAlphaShadows:!1,tilesHelper:!0,showLightHelper:!1,directionalLightIntensity:0,directionalLightColor:`#ffffff`,directionalLightPosition:[1,1,1],directionalLightAngle:0,filterStrength:1,edgeAtrousIterations:5,edgePhiLuminance:4,edgePhiNormal:64,edgePhiDepth:.1,enableOIDN:!1,oidnQuality:`fast`,debugGbufferMaps:!1,enableUpscaler:!1,upscalerScale:2,upscalerQuality:`fast`,upscalerHdr:!0,debugMode:0,debugThreshold:100,debugModel:0,enableBloom:!1,bloomStrength:.2,bloomRadius:.15,bloomThreshold:.85,interactionModeEnabled:!0,debugVisScale:100,denoiserStrategy:`none`,enableASVGF:!1,asvgfTemporalAlpha:.1,asvgfAtrousIterations:8,asvgfPhiColor:10,asvgfPhiNormal:128,asvgfPhiDepth:1,asvgfVarianceBoost:1,asvgfMaxAccumFrames:32,asvgfGradientStrength:0,asvgfGradientSigmaScale:2,asvgfGradientNoiseFloor:0,asvgfDebugMode:0,asvgfQualityPreset:`medium`,showAsvgfHeatmap:!1,autoExposure:!1,autoExposureKeyValue:.18,autoExposureMinExposure:.1,autoExposureMaxExposure:20,autoExposureAdaptSpeedBright:3,autoExposureAdaptSpeedDark:.5},V=.01,H=2048,U={low:{temporalAlpha:.1,gradientStrength:.8,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:3,phiColor:1,phiNormal:64,phiDepth:.1,phiLuminance:6,maxAccumFrames:16,varianceBoost:.5},medium:{temporalAlpha:.03,gradientStrength:1,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:4,phiColor:.5,phiNormal:128,phiDepth:.05,phiLuminance:4,maxAccumFrames:64,varianceBoost:1},high:{temporalAlpha:0,gradientStrength:1,gradientSigmaScale:2.5,gradientNoiseFloor:.05,atrousIterations:6,phiColor:.3,phiNormal:256,phiDepth:.02,phiLuminance:2,maxAccumFrames:128,varianceBoost:1.5}},ke={fov:{min:10,max:90,default:B.fov},focusDistance:{min:.3,max:100,default:B.focusDistance},aperture:{options:[1.4,2,2.8,4,5.6,8,11,16],default:B.aperture},focalLength:{min:0,max:200,default:B.focalLength}},Ae={clearMorning:{name:`Clear Morning`,sunAzimuth:90,sunElevation:20,sunIntensity:15,rayleighDensity:.9,turbidity:.8},clearNoon:{name:`Clear Noon`,sunAzimuth:0,sunElevation:75,sunIntensity:20,rayleighDensity:1,turbidity:.3},overcast:{name:`Overcast`,sunAzimuth:0,sunElevation:45,sunIntensity:6,rayleighDensity:.6,turbidity:4},goldenHour:{name:`Golden Hour`,sunAzimuth:270,sunElevation:10,sunIntensity:19,rayleighDensity:.8,turbidity:1.2},sunset:{name:`Sunset`,sunAzimuth:270,sunElevation:2,sunIntensity:18,rayleighDensity:.7,turbidity:2},dusk:{name:`Dusk`,sunAzimuth:270,sunElevation:-8,sunIntensity:8,rayleighDensity:.5,turbidity:1.5}},je={portrait:{name:`Portrait`,description:`Shallow depth of field, background blur`,fov:45,focusDistance:1.5,aperture:1.4,focalLength:135,apertureScale:1.5},landscape:{name:`Landscape`,description:`Maximum depth of field, everything in focus`,fov:65,focusDistance:10,aperture:16,focalLength:24,apertureScale:.5},macro:{name:`Macro`,description:`Extreme close-up with thin focus plane`,fov:40,focusDistance:.3,aperture:2,focalLength:100,apertureScale:2},product:{name:`Product`,description:`Sharp detail with subtle background separation`,fov:50,focusDistance:.8,aperture:2.8,focalLength:85,apertureScale:1},architectural:{name:`Architectural`,description:`Wide view with deep focus`,fov:75,focusDistance:5,aperture:11,focalLength:16,apertureScale:.5},cinematic:{name:`Cinematic`,description:`Dramatic depth separation with anamorphic bokeh`,fov:35,focusDistance:3,aperture:1.4,focalLength:200,apertureScale:1.8,anamorphicRatio:1.5}},Me={MANUAL:`manual`,AUTO:`auto`},Ne={SMOOTHING_FACTOR:.15,RESET_THRESHOLD:.05,FALLBACK_DISTANCE:10,SNAP_THRESHOLD:.5},W={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},G={SLOTS_PER_MATERIAL:30,FLOATS_PER_MATERIAL:120,IOR:0,TRANSMISSION:1,THICKNESS:2,EMISSIVE_INTENSITY:3,ATTENUATION_COLOR:4,ATTENUATION_DISTANCE:7,OPACITY:8,SIDE:9,TRANSPARENT:10,ALPHA_TEST:11,ALPHA_MODE:12,DEPTH_WRITE:13,NORMAL_SCALE:14,COLOR:16,METALNESS:19,EMISSIVE:20,ROUGHNESS:23,ALBEDO_MAP_INDEX:24,NORMAL_MAP_INDEX:25,ROUGHNESS_MAP_INDEX:26,METALNESS_MAP_INDEX:27,EMISSIVE_MAP_INDEX:28,BUMP_MAP_INDEX:29,CLEARCOAT:30,CLEARCOAT_ROUGHNESS:31,DISPERSION:32,VISIBLE:33,SHEEN:34,SHEEN_ROUGHNESS:35,SHEEN_COLOR:36,SPECULAR_INTENSITY:40,SPECULAR_COLOR:41,IRIDESCENCE:44,IRIDESCENCE_IOR:45,IRIDESCENCE_THICKNESS_RANGE:46,BUMP_SCALE:48,DISPLACEMENT_SCALE:49,DISPLACEMENT_MAP_INDEX:50,ALBEDO_TRANSFORM:52,NORMAL_TRANSFORM:60,ROUGHNESS_TRANSFORM:68,METALNESS_TRANSFORM:76,EMISSIVE_TRANSFORM:84,BUMP_TRANSFORM:92,DISPLACEMENT_TRANSFORM:100,SUBSURFACE_COLOR:108,SUBSURFACE:111,SUBSURFACE_RADIUS:112,SUBSURFACE_RADIUS_SCALE:115,SUBSURFACE_ANISOTROPY:116,SLOT:{IOR_TRANSMISSION:0,ATTENUATION:1,OPACITY_ALPHA:2,ALPHA_MODE:3,COLOR_METALNESS:4,EMISSIVE_ROUGHNESS:5,MAP_INDICES_A:6,MAP_INDICES_B:7,DISPERSION_SHEEN:8,SHEEN_COLOR:9,SPECULAR:10,IRIDESCENCE:11,BUMP_DISPLACEMENT:12,ALBEDO_TRANSFORM_A:13,ALBEDO_TRANSFORM_B:14,NORMAL_TRANSFORM_A:15,NORMAL_TRANSFORM_B:16,ROUGHNESS_TRANSFORM_A:17,ROUGHNESS_TRANSFORM_B:18,METALNESS_TRANSFORM_A:19,METALNESS_TRANSFORM_B:20,EMISSIVE_TRANSFORM_A:21,EMISSIVE_TRANSFORM_B:22,BUMP_TRANSFORM_A:23,BUMP_TRANSFORM_B:24,DISPLACEMENT_TRANSFORM_A:25,DISPLACEMENT_TRANSFORM_B:26,SUBSURFACE_A:27,SUBSURFACE_B:28,SUBSURFACE_C:29}},Pe={TRIANGLE_LEAF:-1,BLAS_POINTER_LEAF:-2},K={PIXELS_PER_MATERIAL:30,RGBA_COMPONENTS:4,VEC4_PER_TRIANGLE:8,VEC4_PER_BVH_NODE:4,FLOATS_PER_VEC4:4,MIN_TEXTURE_WIDTH:4,MAX_CONCURRENT_WORKERS:Math.min(typeof navigator<`u`&&navigator.hardwareConcurrency||4,6),BUFFER_POOL_SIZE:20,CANVAS_POOL_SIZE:12,CACHE_SIZE_LIMIT:50,MAX_TEXTURE_SIZE:8192,DEFAULT_MAX_TEXTURE_SIZE:4096,MAX_TEXTURES_LIMIT:128,MATERIAL_BUCKET_COUNT:4,BUCKET_LAYER_STRIDE:256};function q(e,t=K.MATERIAL_BUCKET_COUNT){let n=[];for(let r=t-1;r>=0;r--)n.push(Math.max(K.MIN_TEXTURE_WIDTH,Math.round(e/2**r)));return n}function Fe(e,t,n,r=K.MATERIAL_BUCKET_COUNT){let i=2**Math.ceil(Math.log2(Math.max(e||1,t||1))),a=q(n,r);for(let e=0;e<a.length;e++)if(i<=a[e])return e;return a.length-1}function Ie(e,t){return e*K.BUCKET_LAYER_STRIDE+t}var Le=[0,0,1,1,0,0,0,1],Re={maxSamples:30,bounces:20,transmissiveBounces:8,maxSubsurfaceSteps:64,renderMode:1,enableAlphaShadows:!0,enableOIDN:!0,oidnQuality:`balance`,interactionModeEnabled:!1},ze={maxSamples:B.maxSamples,bounces:B.bounces,renderMode:B.renderMode,enableAlphaShadows:B.enableAlphaShadows,transmissiveBounces:B.transmissiveBounces,maxSubsurfaceSteps:B.maxSubsurfaceSteps,enableOIDN:!1,oidnQuality:`fast`,interactionModeEnabled:!0},Be={MAX_BUFFER_MEMORY:1024*1024*1024,MAX_TEXTURE_MEMORY:2048*1024*1024,CLEANUP_THRESHOLD:.8,CHUNK_SIZE_THRESHOLD:64*1024*1024,STREAM_BATCH_SIZE:4};function Ve(){let e=new t.StorageTexture(H,H);return e.type=r.FloatType,e.format=r.RGBAFormat,e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e}var J=class{constructor(e,t){this.writeColor=null,this.writeNormalDepth=null,this.writeAlbedo=null,this.readTarget=null,this.currentTarget=0,this.renderWidth=0,this.renderHeight=0,this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),e>0&&t>0&&this.create(e,t)}create(e,n){this.dispose(),this.renderWidth=e,this.renderHeight=n,this.writeColor=Ve(),this.writeNormalDepth=Ve(),this.writeAlbedo=Ve(),this.readTarget=new t.RenderTarget(e,n,{type:r.FloatType,format:r.RGBAFormat,minFilter:r.NearestFilter,magFilter:r.NearestFilter,depthBuffer:!1,stencilBuffer:!1,count:3}),this.readTarget.textures[0].name=`gColor`,this.readTarget.textures[1].name=`gNormalDepth`,this.readTarget.textures[2].name=`gAlbedo`,console.log(`StorageTexturePool: Created ${e}x${n} (3 write StorageTextures + 1 MRT RenderTarget)`)}ensureSize(e,t){return this.writeColor?this.renderWidth!==e||this.renderHeight!==t?(this.setSize(e,t),!0):!1:(this.create(e,t),!0)}getReadTextures(){return{color:this.readTarget.textures[0],normalDepth:this.readTarget.textures[1],albedo:this.readTarget.textures[2]}}getWriteTextures(){return{color:this.writeColor,normalDepth:this.writeNormalDepth,albedo:this.writeAlbedo}}copyToReadTargets(e,t=!0){this._srcRegion.max.set(this.renderWidth,this.renderHeight),e.copyTextureToTexture(this.writeColor,this.readTarget.textures[0],this._srcRegion),t&&(e.copyTextureToTexture(this.writeNormalDepth,this.readTarget.textures[1],this._srcRegion),e.copyTextureToTexture(this.writeAlbedo,this.readTarget.textures[2],this._srcRegion))}clear(e){if(!this.readTarget||!e)return;let t=e.getRenderTarget();e.setRenderTarget(this.readTarget),e.clear(!0,!1,!1),e.setRenderTarget(t)}swap(){this.currentTarget=1-this.currentTarget}setSize(e,t){if(this.renderWidth=e,this.renderHeight=t,this.readTarget){this.readTarget.setSize(e,t);for(let e of this.readTarget.textures)e.needsUpdate=!0}}dispose(){this.writeColor?.dispose(),this.writeNormalDepth?.dispose(),this.writeAlbedo?.dispose(),this.readTarget?.dispose(),this.writeColor=null,this.writeNormalDepth=null,this.writeAlbedo=null,this.readTarget=null}},He={cameraViewMatrix:`ptCameraViewMatrix`,cameraProjectionMatrix:`ptCameraProjectionMatrix`},Ue=class{constructor(e=1920,t=1080){this._uniforms=new Map,this._booleans=new Set,this._lightBuffers={},this._initUniforms(e,t),this._nameAll()}get(e){return this._uniforms.get(e)}set(e,t){let n=this._uniforms.get(e);if(!n){console.warn(`UniformManager: Unknown uniform "${e}"`);return}this._booleans.has(e)?n.value=+!!t:typeof t==`object`&&t&&typeof n.value?.copy==`function`?n.value.copy(t):n.value=t}has(e){return this._uniforms.has(e)}keys(){return this._uniforms.keys()}getLightBufferNodes(){return this._lightBuffers}updateMany(e){let t=!1;for(let[n,r]of Object.entries(e)){let e=this._uniforms.get(n);e&&e.value!==r&&(e.value=r,t=!0)}return t}_initUniforms(e,t){let i=(e,t,r)=>{let i=(0,n.uniform)(t,r);return this._uniforms.set(e,i),i},a=(e,t)=>(this._booleans.add(e),i(e,+!!t,`int`));i(`frame`,0,`uint`),i(`maxBounces`,B.bounces,`int`),i(`maxSamples`,B.maxSamples,`int`),i(`transmissiveBounces`,B.transmissiveBounces,`int`),i(`maxSubsurfaceSteps`,B.maxSubsurfaceSteps,`int`),i(`visMode`,B.debugMode,`int`),i(`debugVisScale`,B.debugVisScale,`float`),a(`enableAccumulation`,!0),i(`accumulationAlpha`,0,`float`),a(`cameraIsMoving`,!1),a(`hasPreviousAccumulated`,!1),i(`environmentIntensity`,B.environmentIntensity,`float`),i(`backgroundIntensity`,B.backgroundIntensity,`float`),i(`backgroundColor`,new r.Color(0,0,0),`color`),i(`backgroundBlurriness`,B.backgroundBlurriness,`float`),i(`backgroundBlurSamples`,B.backgroundBlurSamples,`int`),a(`showBackground`,B.showBackground),a(`transparentBackground`,B.transparentBackground),a(`enableEnvironment`,B.enableEnvironment),i(`environmentMatrix`,new r.Matrix4,`mat4`),a(`useEnvMapIS`,B.useImportanceSampledEnvironment),i(`envTotalSum`,0,`float`),i(`envCompensationDelta`,0,`float`),i(`envResolution`,new r.Vector2(1,1),`vec2`),a(`groundProjectionEnabled`,B.groundProjectionEnabled),i(`groundProjectionRadius`,B.groundProjectionRadius,`float`),i(`groundProjectionHeight`,B.groundProjectionHeight,`float`),i(`groundProjectionLevel`,B.groundProjectionLevel,`float`),a(`enableGroundCatcher`,B.enableGroundCatcher),i(`groundCatcherHeight`,B.groundCatcherHeight,`float`),i(`sunDirection`,new r.Vector3(0,1,0),`vec3`),i(`sunAngularSize`,.0087,`float`),a(`hasSun`,!1),i(`globalIlluminationIntensity`,B.globalIlluminationIntensity,`float`),i(`exposure`,B.exposure,`float`),i(`numDirectionalLights`,0,`int`),i(`numAreaLights`,0,`int`),i(`numPointLights`,0,`int`),i(`numSpotLights`,0,`int`),this._lightBuffers={directional:(0,n.uniformArray)(new Float32Array(192),`float`),area:(0,n.uniformArray)(new Float32Array(256),`float`),point:(0,n.uniformArray)(new Float32Array(144),`float`),spot:(0,n.uniformArray)(new Float32Array(320),`float`)},i(`cameraWorldMatrix`,new r.Matrix4,`mat4`),i(`cameraProjectionMatrixInverse`,new r.Matrix4,`mat4`),i(`cameraViewMatrix`,new r.Matrix4,`mat4`),i(`cameraProjectionMatrix`,new r.Matrix4,`mat4`),a(`enableDOF`,B.enableDOF),i(`focusDistance`,B.focusDistance,`float`),i(`focalLength`,B.focalLength,`float`),i(`aperture`,B.aperture,`float`),i(`apertureScale`,1,`float`),i(`anamorphicRatio`,B.anamorphicRatio??1,`float`),i(`sceneScale`,1,`float`),this._uniforms.set(`samplingTechnique`,k),k.value=B.samplingTechnique,i(`fireflyThreshold`,B.fireflyThreshold,`float`),a(`enableEmissiveTriangleSampling`,B.enableEmissiveTriangleSampling),i(`emissiveBoost`,B.emissiveBoost,`float`),i(`emissiveTriangleCount`,0,`int`),i(`emissiveTotalPower`,0,`float`),i(`lightBVHNodeCount`,0,`int`),i(`emissiveVec4Offset`,0,`int`),i(`reverseMapVec4Offset`,0,`int`),i(`renderMode`,B.renderMode,`int`),a(`enableAlphaShadows`,B.enableAlphaShadows),i(`resolution`,new r.Vector2(e,t),`vec2`)}_nameAll(){for(let[e,t]of this._uniforms)t.name=He[e]||e}dispose(){this._disposed||(this._disposed=!0,this._uniforms.clear(),this._booleans.clear(),this._lightBuffers={})}},We=G.SLOTS_PER_MATERIAL,Ge=W.UV_C_MAT_OFFSET+2,Ke=W.NORMAL_C_OFFSET+3,qe=W.NORMAL_A_OFFSET+3,Je=new Set([`transmission`,`transparent`,`opacity`,`alphaMode`]),Ye=class{constructor(e){this.sdfs=e,this.materialStorageAttr=null,this.materialStorageNode=null,this.materialCount=0,this.srgbBuckets=null,this.linearBuckets=null,this._srgbTexPacked=null,this._linearTexPacked=null,this.compiledFeatures=null,this.callbacks={}}setMaterialData(e){if(!e)return;let r=e.length/4;this.materialStorageNode?(this.materialStorageAttr=new t.StorageInstancedBufferAttribute(e,4),this.materialStorageNode.value=this.materialStorageAttr,this.materialStorageNode.bufferCount=r):(this.materialStorageAttr=new t.StorageInstancedBufferAttribute(e,4),this.materialStorageNode=(0,n.storage)(this.materialStorageAttr,`vec4`,r).toReadOnly()),this.materialCount=Math.floor(r/We),console.log(`MaterialDataManager: ${this.materialCount} materials (storage buffer)`)}getStorageAttr(){return this.materialStorageAttr}getStorageNode(){return this.materialStorageNode}setMaterialTextures(e){e.srgbBuckets&&(this.srgbBuckets=e.srgbBuckets),e.linearBuckets&&(this.linearBuckets=e.linearBuckets)}setTexturePackMaps(e,t){this._srgbTexPacked=e||null,this._linearTexPacked=t||null}getPackedTextureIndex(e,t){if(!e)return-1;let n=e.source?.uuid??e.uuid,r=(t?this._srgbTexPacked:this._linearTexPacked)?.get(n);return r===void 0?-1:r}loadTexturesFromSdfs(){this.srgbBuckets=this.sdfs.srgbBucketTextures,this.linearBuckets=this.sdfs.linearBucketTextures,this.setTexturePackMaps(this.sdfs._srgbTexPacked,this.sdfs._linearTexPacked)}getTextureArrays(){return{srgbBuckets:this.srgbBuckets,linearBuckets:this.linearBuckets}}updateMaterialProperty(e,t,n){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let r=this.materialStorageAttr.array,i=e*G.FLOATS_PER_MATERIAL;switch(t){case`color`:n.r===void 0?Array.isArray(n)&&(r[i+G.COLOR]=n[0],r[i+G.COLOR+1]=n[1],r[i+G.COLOR+2]=n[2]):(r[i+G.COLOR]=n.r,r[i+G.COLOR+1]=n.g,r[i+G.COLOR+2]=n.b);break;case`metalness`:r[i+G.METALNESS]=n;break;case`emissive`:n.r===void 0?Array.isArray(n)&&(r[i+G.EMISSIVE]=n[0],r[i+G.EMISSIVE+1]=n[1],r[i+G.EMISSIVE+2]=n[2]):(r[i+G.EMISSIVE]=n.r,r[i+G.EMISSIVE+1]=n.g,r[i+G.EMISSIVE+2]=n.b);break;case`roughness`:r[i+G.ROUGHNESS]=n;break;case`ior`:r[i+G.IOR]=n;break;case`transmission`:r[i+G.TRANSMISSION]=n;break;case`thickness`:r[i+G.THICKNESS]=n;break;case`emissiveIntensity`:r[i+G.EMISSIVE_INTENSITY]=n;break;case`attenuationColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.ATTENUATION_COLOR]=n[0],r[i+G.ATTENUATION_COLOR+1]=n[1],r[i+G.ATTENUATION_COLOR+2]=n[2]):(r[i+G.ATTENUATION_COLOR]=n.r,r[i+G.ATTENUATION_COLOR+1]=n.g,r[i+G.ATTENUATION_COLOR+2]=n.b);break;case`attenuationDistance`:r[i+G.ATTENUATION_DISTANCE]=n;break;case`dispersion`:r[i+G.DISPERSION]=n;break;case`sheen`:r[i+G.SHEEN]=n;break;case`sheenRoughness`:r[i+G.SHEEN_ROUGHNESS]=n;break;case`sheenColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SHEEN_COLOR]=n[0],r[i+G.SHEEN_COLOR+1]=n[1],r[i+G.SHEEN_COLOR+2]=n[2]):(r[i+G.SHEEN_COLOR]=n.r,r[i+G.SHEEN_COLOR+1]=n.g,r[i+G.SHEEN_COLOR+2]=n.b);break;case`specularIntensity`:r[i+G.SPECULAR_INTENSITY]=n;break;case`specularColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SPECULAR_COLOR]=n[0],r[i+G.SPECULAR_COLOR+1]=n[1],r[i+G.SPECULAR_COLOR+2]=n[2]):(r[i+G.SPECULAR_COLOR]=n.r,r[i+G.SPECULAR_COLOR+1]=n.g,r[i+G.SPECULAR_COLOR+2]=n.b);break;case`iridescence`:r[i+G.IRIDESCENCE]=n;break;case`iridescenceIOR`:r[i+G.IRIDESCENCE_IOR]=n;break;case`iridescenceThicknessRange`:Array.isArray(n)&&(r[i+G.IRIDESCENCE_THICKNESS_RANGE]=n[0],r[i+G.IRIDESCENCE_THICKNESS_RANGE+1]=n[1]);break;case`clearcoat`:r[i+G.CLEARCOAT]=n;break;case`clearcoatRoughness`:r[i+G.CLEARCOAT_ROUGHNESS]=n;break;case`opacity`:r[i+G.OPACITY]=n;break;case`side`:r[i+G.SIDE]=n,this._patchTriangleSideForMaterial(e,n);break;case`transparent`:r[i+G.TRANSPARENT]=n;break;case`alphaTest`:r[i+G.ALPHA_TEST]=n;break;case`alphaMode`:r[i+G.ALPHA_MODE]=n;break;case`depthWrite`:r[i+G.DEPTH_WRITE]=n;break;case`normalScale`:n.x===void 0?typeof n==`number`&&(r[i+G.NORMAL_SCALE]=n,r[i+G.NORMAL_SCALE+1]=n):(r[i+G.NORMAL_SCALE]=n.x,r[i+G.NORMAL_SCALE+1]=n.y);break;case`bumpScale`:r[i+G.BUMP_SCALE]=n;break;case`displacementScale`:r[i+G.DISPLACEMENT_SCALE]=n;break;case`subsurface`:r[i+G.SUBSURFACE]=n;break;case`subsurfaceRadiusScale`:r[i+G.SUBSURFACE_RADIUS_SCALE]=n;break;case`subsurfaceAnisotropy`:r[i+G.SUBSURFACE_ANISOTROPY]=n;break;case`subsurfaceColor`:n.r===void 0?Array.isArray(n)&&(r[i+G.SUBSURFACE_COLOR]=n[0],r[i+G.SUBSURFACE_COLOR+1]=n[1],r[i+G.SUBSURFACE_COLOR+2]=n[2]):(r[i+G.SUBSURFACE_COLOR]=n.r,r[i+G.SUBSURFACE_COLOR+1]=n.g,r[i+G.SUBSURFACE_COLOR+2]=n.b);break;case`subsurfaceRadius`:Array.isArray(n)?(r[i+G.SUBSURFACE_RADIUS]=n[0],r[i+G.SUBSURFACE_RADIUS+1]=n[1],r[i+G.SUBSURFACE_RADIUS+2]=n[2]):n.x!==void 0&&(r[i+G.SUBSURFACE_RADIUS]=n.x,r[i+G.SUBSURFACE_RADIUS+1]=n.y,r[i+G.SUBSURFACE_RADIUS+2]=n.z);break;default:console.warn(`Unknown material property: ${t}`);return}this.materialStorageAttr.needsUpdate=!0,Je.has(t)&&this._recomputeOpaqueBlockerForMaterial(e),[`transmission`,`clearcoat`,`sheen`,`iridescence`,`dispersion`,`transparent`,`opacity`,`alphaTest`,`subsurface`].includes(t)&&this.rescanMaterialFeatures()&&this._notifyFeaturesChanged(),this._notifyReset()}updateMaterialDataFromObject(e,t){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let n=this.materialStorageAttr.array,r=e*G.FLOATS_PER_MATERIAL;t.color&&(n[r+G.COLOR]=t.color.r??t.color[0]??1,n[r+G.COLOR+1]=t.color.g??t.color[1]??1,n[r+G.COLOR+2]=t.color.b??t.color[2]??1),n[r+G.METALNESS]=t.metalness??0,t.emissive&&(n[r+G.EMISSIVE]=t.emissive.r??t.emissive[0]??0,n[r+G.EMISSIVE+1]=t.emissive.g??t.emissive[1]??0,n[r+G.EMISSIVE+2]=t.emissive.b??t.emissive[2]??0),n[r+G.ROUGHNESS]=t.roughness??1,n[r+G.IOR]=t.ior??1.5,n[r+G.TRANSMISSION]=t.transmission??0,n[r+G.THICKNESS]=t.thickness??.1,n[r+G.EMISSIVE_INTENSITY]=t.emissiveIntensity??1,t.attenuationColor&&(n[r+G.ATTENUATION_COLOR]=t.attenuationColor.r??t.attenuationColor[0]??1,n[r+G.ATTENUATION_COLOR+1]=t.attenuationColor.g??t.attenuationColor[1]??1,n[r+G.ATTENUATION_COLOR+2]=t.attenuationColor.b??t.attenuationColor[2]??1),n[r+G.ATTENUATION_DISTANCE]=t.attenuationDistance??1/0,n[r+G.DISPERSION]=t.dispersion??0,n[r+G.VISIBLE]=1,n[r+G.SHEEN]=t.sheen??0,n[r+G.SHEEN_ROUGHNESS]=t.sheenRoughness??1,t.sheenColor&&(n[r+G.SHEEN_COLOR]=t.sheenColor.r??t.sheenColor[0]??0,n[r+G.SHEEN_COLOR+1]=t.sheenColor.g??t.sheenColor[1]??0,n[r+G.SHEEN_COLOR+2]=t.sheenColor.b??t.sheenColor[2]??0),n[r+G.SPECULAR_INTENSITY]=t.specularIntensity??1,t.specularColor&&(n[r+G.SPECULAR_COLOR]=t.specularColor.r??t.specularColor[0]??1,n[r+G.SPECULAR_COLOR+1]=t.specularColor.g??t.specularColor[1]??1,n[r+G.SPECULAR_COLOR+2]=t.specularColor.b??t.specularColor[2]??1),n[r+G.IRIDESCENCE]=t.iridescence??0,n[r+G.IRIDESCENCE_IOR]=t.iridescenceIOR??1.3,t.iridescenceThicknessRange&&(n[r+G.IRIDESCENCE_THICKNESS_RANGE]=t.iridescenceThicknessRange[0]??100,n[r+G.IRIDESCENCE_THICKNESS_RANGE+1]=t.iridescenceThicknessRange[1]??400),n[r+G.ALBEDO_MAP_INDEX]=t.map??-1,n[r+G.NORMAL_MAP_INDEX]=t.normalMap??-1,n[r+G.ROUGHNESS_MAP_INDEX]=t.roughnessMap??-1,n[r+G.METALNESS_MAP_INDEX]=t.metalnessMap??-1,n[r+G.EMISSIVE_MAP_INDEX]=t.emissiveMap??-1,n[r+G.BUMP_MAP_INDEX]=t.bumpMap??-1,n[r+G.CLEARCOAT]=t.clearcoat??0,n[r+G.CLEARCOAT_ROUGHNESS]=t.clearcoatRoughness??0,n[r+G.OPACITY]=t.opacity??1,n[r+G.SIDE]=t.side??0,this._patchTriangleSideForMaterial(e,t.side??0),this._recomputeOpaqueBlockerForMaterial(e),n[r+G.TRANSPARENT]=t.transparent??0,n[r+G.ALPHA_TEST]=t.alphaTest??0,n[r+G.ALPHA_MODE]=t.alphaMode??0,n[r+G.DEPTH_WRITE]=t.depthWrite??1,n[r+G.NORMAL_SCALE]=t.normalScale?.x??(typeof t.normalScale==`number`?t.normalScale:1),n[r+G.NORMAL_SCALE+1]=t.normalScale?.y??(typeof t.normalScale==`number`?t.normalScale:1),n[r+G.BUMP_SCALE]=t.bumpScale??1,n[r+G.DISPLACEMENT_SCALE]=t.displacementScale??1,n[r+G.DISPLACEMENT_MAP_INDEX]=t.displacementMap??-1,n[r+G.SUBSURFACE]=t.subsurface??0,t.subsurfaceColor&&(n[r+G.SUBSURFACE_COLOR]=t.subsurfaceColor.r??t.subsurfaceColor[0]??1,n[r+G.SUBSURFACE_COLOR+1]=t.subsurfaceColor.g??t.subsurfaceColor[1]??1,n[r+G.SUBSURFACE_COLOR+2]=t.subsurfaceColor.b??t.subsurfaceColor[2]??1),t.subsurfaceRadius&&(n[r+G.SUBSURFACE_RADIUS]=t.subsurfaceRadius[0]??1,n[r+G.SUBSURFACE_RADIUS+1]=t.subsurfaceRadius[1]??.2,n[r+G.SUBSURFACE_RADIUS+2]=t.subsurfaceRadius[2]??.1),n[r+G.SUBSURFACE_RADIUS_SCALE]=t.subsurfaceRadiusScale??1,n[r+G.SUBSURFACE_ANISOTROPY]=t.subsurfaceAnisotropy??0;let i=[1,0,0,0,1,0,0,0,1],a=[{key:`mapMatrix`,offset:G.ALBEDO_TRANSFORM},{key:`normalMapMatrices`,offset:G.NORMAL_TRANSFORM},{key:`roughnessMapMatrices`,offset:G.ROUGHNESS_TRANSFORM},{key:`metalnessMapMatrices`,offset:G.METALNESS_TRANSFORM},{key:`emissiveMapMatrices`,offset:G.EMISSIVE_TRANSFORM},{key:`bumpMapMatrices`,offset:G.BUMP_TRANSFORM},{key:`displacementMapMatrices`,offset:G.DISPLACEMENT_TRANSFORM}];for(let{key:e,offset:o}of a){let a=t[e]??i;for(let e=0;e<9;e++)r+o+e<n.length&&(n[r+o+e]=a[e])}this.materialStorageAttr.needsUpdate=!0,this.rescanMaterialFeatures()&&this._notifyFeaturesChanged(),this._notifyReset()}updateMaterial(e,t){let n=this.sdfs.geometryExtractor.createMaterialObject(t);(this._srgbTexPacked||this._linearTexPacked)&&(n.map=this.getPackedTextureIndex(t.map,!0),n.emissiveMap=this.getPackedTextureIndex(t.emissiveMap,!0),n.normalMap=this.getPackedTextureIndex(t.normalMap,!1),n.bumpMap=this.getPackedTextureIndex(t.bumpMap,!1),n.roughnessMap=this.getPackedTextureIndex(t.roughnessMap,!1),n.metalnessMap=this.getPackedTextureIndex(t.metalnessMap,!1),n.displacementMap=this.getPackedTextureIndex(t.displacementMap,!1)),this.updateMaterialDataFromObject(e,n)}updateTextureTransform(e,t,n){if(!this.materialStorageAttr){console.warn(`Material storage buffer not available`);return}let r=this.materialStorageAttr.array,i=e*G.FLOATS_PER_MATERIAL,a={map:G.ALBEDO_TRANSFORM,normalMap:G.NORMAL_TRANSFORM,roughnessMap:G.ROUGHNESS_TRANSFORM,metalnessMap:G.METALNESS_TRANSFORM,emissiveMap:G.EMISSIVE_TRANSFORM,bumpMap:G.BUMP_TRANSFORM,displacementMap:G.DISPLACEMENT_TRANSFORM}[t];if(a===void 0){console.warn(`Unknown texture name for transform update: ${t}`);return}for(let e=0;e<9;e++)i+a+e<r.length&&(r[i+a+e]=n[e]);this.materialStorageAttr.needsUpdate=!0,this._notifyReset()}rescanMaterialFeatures(){if(!this.materialStorageAttr?.array)return console.warn(`[MaterialDataManager] Material storage buffer not available for feature scanning`),!1;let e=this.materialStorageAttr.array,t=this.sdfs.materialCount||1,n={hasClearcoat:!1,hasTransmission:!1,hasDispersion:!1,hasIridescence:!1,hasSheen:!1,hasTransparency:!1,hasSubsurface:!1,hasMultiLobeMaterials:!1,hasMRTOutputs:!0};for(let r=0;r<t;r++){let t=r*G.FLOATS_PER_MATERIAL,i=e[t+G.TRANSMISSION],a=e[t+G.DISPERSION],o=e[t+G.SHEEN],s=e[t+G.IRIDESCENCE],c=e[t+G.CLEARCOAT],l=e[t+G.OPACITY],u=e[t+G.TRANSPARENT],d=e[t+G.ALPHA_TEST],f=e[t+G.SUBSURFACE];c>0&&(n.hasClearcoat=!0),i>0&&(n.hasTransmission=!0),a>0&&(n.hasDispersion=!0),s>0&&(n.hasIridescence=!0),o>0&&(n.hasSheen=!0),(u>0||l<1||d>0)&&(n.hasTransparency=!0),f>0&&(n.hasSubsurface=!0),[c>0,i>0,s>0,o>0].filter(Boolean).length>=2&&(n.hasMultiLobeMaterials=!0)}let r=JSON.stringify(this.sdfs.sceneFeatures)!==JSON.stringify(n);return r&&(this.sdfs.sceneFeatures=n),r}injectMaterialFeatureDefines(){let e=this.sdfs.sceneFeatures;if(!e){console.warn(`[MaterialDataManager] No sceneFeatures detected, skipping define injection`);return}let t=JSON.stringify(e);(!this.compiledFeatures||this.compiledFeatures!==t)&&(console.log(`[MaterialDataManager] Material features:`,e),this.compiledFeatures=t)}_notifyReset(){this.callbacks.onReset&&this.callbacks.onReset()}_notifyFeaturesChanged(){this.injectMaterialFeatureDefines()}_recomputeOpaqueBlockerForMaterial(e){let t=this.materialStorageAttr?.array;if(!t)return;let n=e*G.FLOATS_PER_MATERIAL,r=t[n+G.ALPHA_MODE]|0,i=t[n+G.TRANSPARENT]|0,a=t[n+G.TRANSMISSION]||0,o=t[n+G.OPACITY]??1,s=+(r===0&&i===0&&a===0&&o>=1);this._patchTriangleFlagForMaterial(e,qe,s)}_patchTriangleFlagForMaterial(e,t,n){let r=this.callbacks.getTriangleData?.(),i=r?.array,a=r?.count|0;if(!i||a===0)return;let o=W.FLOATS_PER_TRIANGLE,s=0;for(let r=0;r<a;r++){let a=r*o;i[a+Ge]===e&&(i[a+t]=n,s++)}s>0&&this.callbacks.onTriangleDataChanged&&this.callbacks.onTriangleDataChanged()}_patchTriangleSideForMaterial(e,t){this._patchTriangleFlagForMaterial(e,Ke,t)}dispose(){this.materialStorageAttr=null,this.materialStorageNode=null,this.materialCount=0,this.srgbBuckets=null,this.linearBuckets=null,this._srgbTexPacked=null,this._linearTexPacked=null,this.compiledFeatures=null}};async function Xe(e){let t=e instanceof URL?e.href:e,n=await fetch(t);if(!n.ok)throw Error(`Failed to fetch worker script: ${n.status}`);let r=new Blob([await n.text()],{type:`application/javascript`});return new Worker(URL.createObjectURL(r),{type:`module`})}var Ze=``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/CDFWorker-BFQUr3By.js`).href:new URL(`assets/CDFWorker-BFQUr3By.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href);function Qe(e,t,n=0,r=e.length){let i=n,a=n+r-1;for(;i<a;){let n=i+a>>1;e[n]<t?i=n+1:a=n}return i-n}function $e(e,t,n){return .2126*e+.7152*t+.0722*n}function et(e){return e<=.04045?e/12.92:((e+.055)/1.055)**2.4}function tt(e){let{width:t,height:n}=e.image,i=e.image.data,a=!1;if(!i){let r=new OffscreenCanvas(t,n).getContext(`2d`);r.drawImage(e.image,0,0,t,n),i=r.getImageData(0,0,t,n).data,a=!0}let o;if(e.type===r.FloatType&&i instanceof Float32Array)o=new Float32Array(i);else if(e.type===r.HalfFloatType){o=new Float32Array(i.length);for(let e=0,t=i.length;e<t;e++)o[e]=r.DataUtils.fromHalfFloat(i[e])}else{let e;e=i instanceof Int8Array||i instanceof Int16Array||i instanceof Int32Array?2**(8*i.BYTES_PER_ELEMENT-1)-1:2**(8*i.BYTES_PER_ELEMENT)-1,o=new Float32Array(i.length);for(let t=0,n=i.length;t<n;t++)o[t]=i[t]/e}if(!a&&e.colorSpace===r.SRGBColorSpace&&(a=!0),a)for(let e=0,t=o.length;e<t;e+=4)o[e]=et(o[e]),o[e+1]=et(o[e+1]),o[e+2]=et(o[e+2]);if(e.flipY){let e=new Float32Array(o.length);for(let r=0;r<n;r++){let i=n-r-1,a=r*t*4,s=i*t*4;e.set(o.subarray(a,a+t*4),s)}o=e}return{floatData:o,width:t,height:n}}var nt=class e{constructor(){this.marginalData=new Float32Array([0,1]),this.conditionalData=new Float32Array([0,0,1,1]),this.totalSum=0,this.compensationDelta=0,this.width=0,this.height=0,this._worker=null}dispose(){this.marginalData=null,this.conditionalData=null,this._worker&&=(this._worker.terminate(),null)}updateFrom(t){let{floatData:n,width:r,height:i}=tt(t),a=e.computeCDF(n,r,i);this.marginalData=a.marginalData,this.conditionalData=a.conditionalData,this.totalSum=a.totalSum,this.compensationDelta=a.compensationDelta,this.width=r,this.height=i}async updateFromAsync(e){let{floatData:t,width:n,height:r}=tt(e);try{this._worker=new Worker(Ze,{type:`module`})}catch(e){if(e.name!==`SecurityError`)throw e;this._worker=await Xe(Ze)}try{let e=await new Promise((e,i)=>{this._worker.onmessage=t=>{t.data.error?i(Error(t.data.error)):e(t.data)},this._worker.onerror=i,this._worker.postMessage({floatData:t,width:n,height:r},[t.buffer])});this.marginalData=e.marginalData,this.conditionalData=e.conditionalData,this.totalSum=e.totalSum,this.compensationDelta=e.compensationDelta,this.width=e.width,this.height=e.height}finally{this._worker&&=(this._worker.terminate(),null)}}static computeCDF(e,t,n){let r=t*n,i=new Float32Array(r),a=0;for(let r=0;r<n;r++){let o=Math.sin(Math.PI*(r+.5)/n);for(let n=0;n<t;n++){let s=r*t+n,c=$e(e[4*s],e[4*s+1],e[4*s+2])*o;i[s]=c,a+=c}}let o=a/r,s=0;for(let e=0;e<r;e++)i[e]=Math.max(0,i[e]-o),s+=i[e];let c=s>0,l=c?s:a,u=c?o:0;if(!c)for(let r=0;r<n;r++){let a=Math.sin(Math.PI*(r+.5)/n);for(let n=0;n<t;n++){let o=r*t+n;i[o]=$e(e[4*o],e[4*o+1],e[4*o+2])*a}}let d=new Float32Array(r),f=new Float32Array(n),p=0;for(let e=0;e<n;e++){let n=0;for(let r=0;r<t;r++){let a=e*t+r;n+=i[a],d[a]=n}if(n!==0)for(let r=e*t,i=e*t+t;r<i;r++)d[r]/=n;p+=n,f[e]=p}if(p!==0)for(let e=0,t=f.length;e<t;e++)f[e]/=p;let m=new Float32Array(n),h=new Float32Array(r);for(let e=0;e<n;e++)m[e]=(Qe(f,(e+1)/n)+.5)/n;for(let e=0;e<n;e++)for(let n=0;n<t;n++){let r=e*t+n;h[r]=(Qe(d,(n+1)/t,e*t,t)+.5)/t}return{marginalData:m,conditionalData:h,totalSum:l,compensationDelta:u}}},rt=Math.PI,it=Math.PI*2,at=Math.E,ot=[5804542996261093e-21,13562911419845635e-21,30265902468824876e-21],st=[183999185144339.78,277980239196605.28,407904795438610.94],ct=1.6110731556870734,lt=1.5,ut=1e3,dt=8400,ft=1250,pt=.9999566769464484,mt=.05968310365946075,ht=.07957747154594767;function gt(e){return ut*Math.max(0,1-at**+(-(ct-Math.acos(Math.max(-1,Math.min(1,e))))/lt))}function _t(e){let t=.2*e*1e-17;return[.434*t*st[0],.434*t*st[1],.434*t*st[2]]}function vt(e){return mt*(1+e**2)}function yt(e,t){let n=t*t;return ht*((1-n)/(1-2*t*e+n)**1.5)}function bt(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function xt(e){let t=Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);return t===0?[0,0,0]:[e[0]/t,e[1]/t,e[2]/t]}function St(e,t,n,r,i,a,o,s){let c=(1-t)*rt,l=(e-.5)*it,u=Math.sin(c),d=xt([u*Math.sin(l),Math.cos(c),u*Math.cos(l)]),f=xt(n),p=gt(f[1])*r,m=i-1*(1-(1-Math.max(0,Math.min(1,1-Math.exp(f[1]/45e4))))),h=[ot[0]*m,ot[1]*m,ot[2]*m],g=_t(s),_=[g[0]*a,g[1]*a,g[2]*a],v=Math.acos(Math.max(0,d[1])),y=Math.cos(v)+.15*(93.885-180/rt*v)**-1.253,b=dt/y,x=ft/y,S=[Math.exp(-(h[0]*b+_[0]*x)),Math.exp(-(h[1]*b+_[1]*x)),Math.exp(-(h[2]*b+_[2]*x))],C=bt(d,f),w=vt(C*.5+.5),T=[h[0]*w,h[1]*w,h[2]*w],E=yt(C,o),D=[_[0]*E,_[1]*E,_[2]*E],O=[T[0]+D[0],T[1]+D[1],T[2]+D[2]],k=[h[0]+_[0],h[1]+_[1],h[2]+_[2]],A=[(p*(O[0]/k[0])*(1-S[0]))**1.5,(p*(O[1]/k[1])*(1-S[1]))**1.5,(p*(O[2]/k[2])*(1-S[2]))**1.5],j=Math.max(0,Math.min(1,1-(1-f[1])**5)),M=[Math.sqrt(p*(O[0]/k[0])*S[0]),Math.sqrt(p*(O[1]/k[1])*S[1]),Math.sqrt(p*(O[2]/k[2])*S[2])],N=1-j;for(let e=0;e<3;e++){let t=1*(1-N)+M[e]*N;A[e]*=t}let ee=[.1*S[0],.1*S[1],.1*S[2]],te=Ct(pt,pt+2e-5,C);for(let e=0;e<3;e++)ee[e]+=p*19e3*S[e]*te;let ne=65504;return[Math.min((A[0]+ee[0])*.04,ne),Math.min((A[1]+ee[1])*.04+3e-4,ne),Math.min((A[2]+ee[2])*.04+75e-5,ne),1]}function Ct(e,t,n){let r=Math.max(0,Math.min(1,(n-e)/(t-e)));return r*r*(3-2*r)}var wt=class{constructor(e=512,t=256){this.width=e,this.height=t,this.lastRenderTime=0,this._pixels=new Float32Array(e*t*4),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1}render(e){let t=performance.now(),n=[e.sunDirection.x,e.sunDirection.y,e.sunDirection.z],r=e.sunIntensity||1,i=e.rayleighDensity||2,a=e.mieDensity||.005,o=e.mieAnisotropy||.8,s=e.turbidity||2,{width:c,height:l}=this,u=this._pixels;for(let e=0;e<l;e++){let t=(e+.5)/l;for(let l=0;l<c;l++){let d=St((l+.5)/c,t,n,r,i,a,o,s),f=(e*c+l)*4;u[f]=d[0],u[f+1]=d[1],u[f+2]=d[2],u[f+3]=d[3]}}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}setResolution(e,t){this.width===e&&this.height===t||(this.width=e,this.height=t,this._pixels=new Float32Array(e*t*4),this._texture.dispose(),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1)}getLastRenderTime(){return this.lastRenderTime}dispose(){this._texture.dispose()}},Tt=class{constructor(e=512,t=256){this.width=e,this.height=t,this.lastRenderTime=0,this._pixels=new Float32Array(e*t*4),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1}renderGradient(e){let t=performance.now(),{width:n,height:r}=this,i=this._pixels,a=e.zenithColor.r,o=e.zenithColor.g,s=e.zenithColor.b,c=e.horizonColor.r,l=e.horizonColor.g,u=e.horizonColor.b,d=e.groundColor.r,f=e.groundColor.g,p=e.groundColor.b;for(let e=0;e<r;e++){let t=(e+.5)/r,m,h,g;if(t>.5){let e=(t-.5)*2;m=c+(a-c)*e,h=l+(o-l)*e,g=u+(s-u)*e}else{let e=t*2;m=d+(c-d)*e,h=f+(l-f)*e,g=p+(u-p)*e}for(let t=0;t<n;t++){let r=(e*n+t)*4;i[r]=m,i[r+1]=h,i[r+2]=g,i[r+3]=1}}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}renderSolid(e){let t=performance.now(),{width:n,height:r}=this,i=this._pixels,a=e.color.r,o=e.color.g,s=e.color.b;for(let e=0;e<r;e++)for(let t=0;t<n;t++){let r=(e*n+t)*4;i[r]=a,i[r+1]=o,i[r+2]=s,i[r+3]=1}return this._texture.needsUpdate=!0,this.lastRenderTime=performance.now()-t,this._texture}setResolution(e,t){this.width===e&&this.height===t||(this.width=e,this.height=t,this._pixels=new Float32Array(e*t*4),this._texture.dispose(),this._texture=new r.DataTexture(this._pixels,e,t,r.RGBAFormat,r.FloatType),this._texture.mapping=r.EquirectangularReflectionMapping,this._texture.colorSpace=r.LinearSRGBColorSpace,this._texture.minFilter=r.LinearFilter,this._texture.magFilter=r.LinearFilter,this._texture.wrapS=r.RepeatWrapping,this._texture.wrapT=r.ClampToEdgeWrapping,this._texture.generateMipmaps=!1)}getLastRenderTime(){return this.lastRenderTime}dispose(){this._texture.dispose()}},Et=class{constructor(e,t){this.scene=e,this.uniforms=t,this.equirectHdrInfo=new nt,this.proceduralSkyRenderer=null,this.simpleSkyRenderer=null,this._envPlaceholder=new r.DataTexture(new Float32Array([0,0,0,1]),1,1,r.RGBAFormat,r.FloatType),this._envPlaceholder.needsUpdate=!0,this.environmentTexture=this._envPlaceholder,this.envTexSize=new r.Vector2,this.envCDFTexture=null,this._initCDFTexture(),this.environmentRotationMatrix=new r.Matrix4,this.cdfBuildTime=0,this.envParams={mode:`hdri`,gradientZenithColor:new r.Color(B.gradientZenithColor),gradientHorizonColor:new r.Color(B.gradientHorizonColor),gradientGroundColor:new r.Color(B.gradientGroundColor),solidSkyColor:new r.Color(B.solidSkyColor),skySunDirection:this._calculateInitialSunDirection(),skySunIntensity:B.skySunIntensity,skyRayleighDensity:B.skyRayleighDensity,skyTurbidity:B.skyTurbidity,skyMieAnisotropy:B.skyMieAnisotropy},this.callbacks={},this._previousHDRI=null}async setMode(e){let t=this.envParams.mode;this.envParams.mode=e,e!==`hdri`&&t===`hdri`&&(this._previousHDRI=this.environmentTexture),e===`gradient`?await this.generateGradientTexture():e===`color`?await this.generateSolidColorTexture():e===`procedural`?await this.generateProceduralSkyTexture():e===`hdri`&&this._previousHDRI&&(await this.setEnvironmentMap(this._previousHDRI),this._previousHDRI=null),this.markDirty(),this.callbacks.onAutoExposureReset?.(),this._notifyReset()}markDirty(){this.environmentTexture&&(this.environmentTexture.needsUpdate=!0)}get params(){return this.envParams}get texture(){return this.environmentTexture}generateGradient(){return this.generateGradientTexture()}generateSolid(){return this.generateSolidColorTexture()}generateProcedural(){return this.generateProceduralSkyTexture()}_initCDFTexture(){this.envCDFTexture=new r.DataTexture(new Float32Array([0]),1,1,r.RedFormat,r.FloatType),this.envCDFTexture.needsUpdate=!0}_updateCDFTexture(){let e=this.equirectHdrInfo.marginalData,t=this.equirectHdrInfo.conditionalData;if(!e||!t)return;let n=this.equirectHdrInfo.width,i=this.equirectHdrInfo.height,a=n+1,o=new Float32Array(a*i);for(let r=0;r<i;r++){let i=r*a;o.set(t.subarray(r*n,r*n+n),i),o[i+n]=e[r]}this.envCDFTexture?.dispose?.(),this.envCDFTexture=new r.DataTexture(o,a,i,r.RedFormat,r.FloatType),this.envCDFTexture.needsUpdate=!0}setEnvironmentTexture(e){e&&(this.environmentTexture=e,this.envTexSize.set(e.image.width,e.image.height),console.log(`EnvironmentManager: Environment map ${e.image.width}x${e.image.height}`))}getEnvironmentTexture(){return this.environmentTexture}setEnvironmentRotation(e){let t=Math.PI/180*e;this.environmentRotationMatrix.makeRotationY(t),this.uniforms.get(`environmentMatrix`).value.copy(this.environmentRotationMatrix)}async buildEnvironmentCDF({useWorker:e=!0}={}){if(!this.scene.environment){this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0);return}try{let t=performance.now(),n=this.scene.environment;if(!n.image){this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0);return}e?await this.equirectHdrInfo.updateFromAsync(n):this.equirectHdrInfo.updateFrom(n),this.cdfBuildTime=performance.now()-t,this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,this.equirectHdrInfo.totalSum),this.uniforms.set(`envCompensationDelta`,this.equirectHdrInfo.compensationDelta),this.uniforms.set(`useEnvMapIS`,1);let{width:r,height:i}=this.equirectHdrInfo;r&&i&&this.uniforms.get(`envResolution`).value.set(r,i),console.log(`Environment CDF built in ${this.cdfBuildTime.toFixed(2)}ms (worker: ${e})`)}catch(e){console.error(`Error building environment CDF:`,e),this.uniforms.set(`useEnvMapIS`,0),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0)}}applyCDFResults(){let e=this.scene.environment,t=this.callbacks.getSceneTextureNodes?.();t&&e&&t.envTex&&(t.envTex.value=e),e&&!e._isGeneratedProcedural&&this.uniforms.set(`hasSun`,0)}async setEnvironmentMap(e){let t=this.environmentTexture;e&&t&&t!==e&&t!==this._envPlaceholder&&t!==this._previousHDRI&&t.dispose?.(),this.scene.environment=e,this.setEnvironmentTexture(e),e?await this.buildEnvironmentCDF():(this._updateCDFTexture(),this.uniforms.set(`envTotalSum`,0),this.uniforms.set(`envCompensationDelta`,0),this.uniforms.set(`useEnvMapIS`,0));let n=this.callbacks.getSceneTextureNodes?.();n&&e&&n.envTex&&(n.envTex.value=e),e&&!e._isGeneratedProcedural&&this.uniforms.set(`hasSun`,0),this._notifyReset()}async generateGradientTexture(){this.simpleSkyRenderer||=new Tt(512,256);let e={zenithColor:this.envParams.gradientZenithColor,horizonColor:this.envParams.gradientHorizonColor,groundColor:this.envParams.gradientGroundColor};try{let t=this.simpleSkyRenderer.renderGradient(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.set(`hasSun`,0)}catch(e){console.error(`Error generating gradient sky:`,e)}}async generateSolidColorTexture(){this.simpleSkyRenderer||=new Tt(512,256);let e={color:this.envParams.solidSkyColor};try{let t=this.simpleSkyRenderer.renderSolid(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.set(`hasSun`,0)}catch(e){console.error(`Error generating solid color sky:`,e)}}async generateProceduralSkyTexture(){this.proceduralSkyRenderer||=new wt(512,256);let e={sunDirection:this.envParams.skySunDirection.clone(),sunIntensity:this.envParams.skySunIntensity*.05,rayleighDensity:this.envParams.skyRayleighDensity*2,mieDensity:this.envParams.skyTurbidity*.005,mieAnisotropy:this.envParams.skyMieAnisotropy,turbidity:this.envParams.skyTurbidity*2};try{let t=this.proceduralSkyRenderer.render(e);t._isGeneratedProcedural=!0,await this.setEnvironmentMap(t),this.uniforms.get(`sunDirection`).value.copy(this.envParams.skySunDirection),this.uniforms.set(`sunAngularSize`,.0087),this.uniforms.set(`hasSun`,1),console.log(`Sun parameters synced: dir=${this.envParams.skySunDirection.toArray().map(e=>e.toFixed(2)).join(`,`)}`)}catch(e){console.error(`Error generating procedural sky:`,e)}}_calculateInitialSunDirection(){let e=B.skySunAzimuth*(Math.PI/180),t=B.skySunElevation*(Math.PI/180);return new r.Vector3(Math.cos(t)*Math.sin(e),Math.sin(t),Math.cos(t)*Math.cos(e)).normalize()}_notifyReset(){this.callbacks.onReset&&this.callbacks.onReset()}dispose(){this.proceduralSkyRenderer=null,this.simpleSkyRenderer=null,this.envCDFTexture?.dispose?.(),this.envCDFTexture=null,this.environmentTexture&&this.environmentTexture!==this._envPlaceholder&&this.environmentTexture.dispose?.(),this._envPlaceholder?.dispose(),this._envPlaceholder=null,this.environmentTexture=null,this._previousHDRI=null}},Dt=S({origin:`vec3`,direction:`vec3`}),Ot=S({color:`vec4`,emissive:`vec3`,emissiveIntensity:`float`,roughness:`float`,metalness:`float`,ior:`float`,transmission:`float`,thickness:`float`,clearcoat:`float`,clearcoatRoughness:`float`,opacity:`float`,transparent:`bool`,attenuationColor:`vec3`,attenuationDistance:`float`,dispersion:`float`,sheen:`float`,sheenRoughness:`float`,sheenColor:`vec3`,specularIntensity:`float`,specularColor:`vec3`,alphaTest:`float`,alphaMode:`int`,side:`int`,depthWrite:`int`,albedoMapIndex:`int`,emissiveMapIndex:`int`,normalMapIndex:`int`,bumpMapIndex:`int`,bumpScale:`float`,displacementScale:`float`,metalnessMapIndex:`int`,roughnessMapIndex:`int`,displacementMapIndex:`int`,normalScale:`vec2`,albedoTransform:`mat3`,emissiveTransform:`mat3`,normalTransform:`mat3`,bumpTransform:`mat3`,metalnessTransform:`mat3`,roughnessTransform:`mat3`,displacementTransform:`mat3`,iridescence:`float`,iridescenceIOR:`float`,iridescenceThicknessRange:`vec2`,subsurface:`float`,subsurfaceColor:`vec3`,subsurfaceRadius:`vec3`,subsurfaceRadiusScale:`float`,subsurfaceAnisotropy:`float`}),kt=S({color:`vec4`,ior:`float`,transmission:`float`,attenuationColor:`vec3`,attenuationDistance:`float`,albedoMapIndex:`int`,opacity:`float`,transparent:`bool`,alphaTest:`float`,alphaMode:`int`,albedoTransform:`mat3`}),At=S({shadowed:`vec3`,unoccluded:`vec3`});S({position:`vec3`,radius:`float`,material:Ot});var jt=S({didHit:`bool`,dst:`float`,hitPoint:`vec3`,normal:`vec3`,uv:`vec2`,materialIndex:`int`,meshIndex:`int`,triangleIndex:`int`,boxTests:`int`,triTests:`int`});S({posA:`vec3`,posB:`vec3`,posC:`vec3`,uvA:`vec2`,uvB:`vec2`,uvC:`vec2`,normalA:`vec3`,normalB:`vec3`,normalC:`vec3`,material:Ot,materialIndex:`int`,meshIndex:`int`}),S({color:`vec4`,samples:`int`});var Mt=S({direction:`vec3`,value:`vec3`,pdf:`float`}),Nt=S({specular:`float`,diffuse:`float`,sheen:`float`,clearcoat:`float`,transmission:`float`,iridescence:`float`}),Pt=S({diffuseImportance:`float`,specularImportance:`float`,transmissionImportance:`float`,clearcoatImportance:`float`}),Ft=S({NoL:`float`,NoV:`float`,NoH:`float`,VoH:`float`,LoH:`float`}),It=S({compensation:`vec3`,E_total:`vec3`}),Lt=S({albedo:`vec4`,emissive:`vec3`,metalness:`float`,roughness:`float`,normal:`vec3`,hasTextures:`bool`}),Rt=S({isMetallic:`bool`,isRough:`bool`,isSmooth:`bool`,isTransmissive:`bool`,hasClearcoat:`bool`,isEmissive:`bool`,complexityScore:`float`}),zt=S({albedoUV:`vec2`,normalUV:`vec2`,metalnessUV:`vec2`,emissiveUV:`vec2`,bumpUV:`vec2`,roughnessUV:`vec2`,normalBumpSameUV:`bool`,metalRoughSameUV:`bool`,albedoEmissiveSameUV:`bool`,allSameUV:`bool`}),Bt=S({F0:`vec3`,NoV:`float`,diffuseColor:`vec3`,isPurelyDiffuse:`bool`,alpha:`float`,k:`float`,alpha2:`float`,invRoughness:`float`,metalFactor:`float`,iorFactor:`float`,maxSheenColor:`float`}),Vt=S({envWeight:`float`,specularWeight:`float`,diffuseWeight:`float`,transmissionWeight:`float`,clearcoatWeight:`float`,totalWeight:`float`,useEnv:`bool`,useSpecular:`bool`,useDiffuse:`bool`,useTransmission:`bool`,useClearcoat:`bool`}),Ht=S({brdfWeight:`float`,lightWeight:`float`,envWeight:`float`,useBRDFSampling:`bool`,useLightSampling:`bool`,useEnvSampling:`bool`});S({traversals:`int`,transmissiveTraversals:`int`,rayType:`int`,isPrimaryRay:`bool`,actualBounceDepth:`int`});var Ut=3.14159,Wt=1/Ut,Gt=2*Ut,Kt=1e-6,qt=.05,Jt=.089,Yt=.001,Xt=(0,n.vec3)(.2126,.7152,.0722),Y=G.SLOTS_PER_MATERIAL,Zt=G.SLOT,X=Zt,Qt=(0,n.mat3)(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252);(0,n.wgslFn)(`
145
145
  fn sRGBToLinear( srgbColor: vec3f ) -> vec3f {
146
146
 
147
147
  return pow( srgbColor, vec3f( 2.2 ) );
@@ -699,7 +699,7 @@
699
699
  return kernelW * lumW * normW * depW * colW;
700
700
 
701
701
  }
702
- `),Qs=class extends ve{constructor(e,i={}){super(`BilateralFiltering`,{...i,executionMode:_e.ALWAYS}),this.renderer=e,this.inputTextureName=i.inputTextureName||`asvgf:demodulated`,this.normalDepthTextureName=i.normalDepthTextureName||`pathtracer:normalDepth`,this.shadingNormalTextureName=i.shadingNormalTextureName||`pathtracer:shadingNormal`,this.albedoTextureName=i.albedoTextureName||`pathtracer:albedo`,this.varianceTextureName=i.varianceTextureName||`variance:output`,this.iterations=i.iterations??4,this.phiColor=(0,n.uniform)(i.phiColor??.5),this.phiNormal=(0,n.uniform)(i.phiNormal??128),this.phiDepth=(0,n.uniform)(i.phiDepth??.05),this.phiLuminance=(0,n.uniform)(i.phiLuminance??4),this.spatialVarianceWeight=(0,n.uniform)(i.spatialVarianceWeight??1),this.stepSizeU=(0,n.uniform)(1,`int`),this.isLastIterationU=(0,n.uniform)(0,`int`),this.resW=(0,n.uniform)(i.width||1),this.resH=(0,n.uniform)(i.height||1),this._readTexNode=new t.TextureNode,this._normalDepthTexNode=new t.TextureNode,this._shadingNormalTexNode=new t.TextureNode,this._albedoTexNode=new t.TextureNode,this._varianceTexNode=new t.TextureNode;let a=i.width||1,o=i.height||1;this._storageTexA=new t.StorageTexture(H,H),this._storageTexA.type=r.HalfFloatType,this._storageTexA.format=r.RGBAFormat,this._storageTexA.minFilter=r.LinearFilter,this._storageTexA.magFilter=r.LinearFilter,this._storageTexB=new t.StorageTexture(H,H),this._storageTexB.type=r.HalfFloatType,this._storageTexB.format=r.RGBAFormat,this._storageTexB.minFilter=r.LinearFilter,this._storageTexB.magFilter=r.LinearFilter,this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),this._outputTarget=new t.RenderTarget(a,o,{type:r.HalfFloatType,format:r.RGBAFormat,minFilter:r.LinearFilter,magFilter:r.LinearFilter,depthBuffer:!1,stencilBuffer:!1}),this._compiled=!1,this._dispatchX=Math.ceil(a/8),this._dispatchY=Math.ceil(o/8),this._buildCompute()}_buildCompute(){this._computeNodeA=this._buildComputeForDirection(this._storageTexA),this._computeNodeB=this._buildComputeForDirection(this._storageTexB)}_buildComputeForDirection(e){let t=this._readTexNode,r=this._normalDepthTexNode,i=this._shadingNormalTexNode,a=this._albedoTexNode,o=this._varianceTexNode,s=this.phiColor,c=this.phiNormal,l=this.phiDepth,u=this.phiLuminance,d=this.spatialVarianceWeight,f=this.stepSizeU,p=this.isLastIterationU,m=this.resW,h=this.resH,g=[1/256,4/256,6/256,4/256,1/256,4/256,16/256,24/256,16/256,4/256,6/256,24/256,36/256,24/256,6/256,4/256,16/256,24/256,16/256,4/256,1/256,4/256,6/256,4/256,1/256];return(0,n.Fn)(()=>{let _=(0,n.int)(n.workgroupId.x).mul(8).add((0,n.int)(n.localId.x)),v=(0,n.int)(n.workgroupId.y).mul(8).add((0,n.int)(n.localId.y));(0,n.If)(_.lessThan((0,n.int)(m)).and(v.lessThan((0,n.int)(h))),()=>{let y=(0,n.ivec2)(_,v),b=(0,n.textureLoad)(t,y).xyz,x=(0,n.textureLoad)(r,y),S=(0,n.textureLoad)(i,y).xyz.mul(2).sub(1),C=x.w,w=tn(b),T=(0,n.max)((0,n.textureLoad)(a,y).xyz,(0,n.vec3)(V)),E=(0,n.max)(tn(T),(0,n.float)(V)).toVar(),D=(0,n.textureLoad)(o,y),O=(0,n.mix)(D.z,(0,n.max)(D.z,D.w),d),k=u.mul((0,n.sqrt)((0,n.max)(O,(0,n.float)(0)))).div(E).add((0,n.float)(1e-4)),A=(0,n.vec3)(0).toVar(),j=(0,n.float)(0).toVar();for(let e=0;e<5;e++)for(let a=0;a<5;a++){let o=a-2,u=e-2,d=g[e*5+a],p=_.add(f.mul(o)).clamp((0,n.int)(0),(0,n.int)(m).sub(1)),y=v.add(f.mul(u)).clamp((0,n.int)(0),(0,n.int)(h).sub(1)),x=(0,n.textureLoad)(t,(0,n.ivec2)(p,y)).xyz,T=(0,n.textureLoad)(r,(0,n.ivec2)(p,y)),E=(0,n.textureLoad)(i,(0,n.ivec2)(p,y)).xyz.mul(2).sub(1),D=T.w,O=Zs(w,tn(x),S,E,C,D,b,x,(0,n.float)(d),k,c,l,s);A.addAssign(x.mul(O)),j.addAssign(O)}let M=A.div((0,n.max)(j,(0,n.float)(1e-4))),N=p.equal((0,n.int)(1)).select(M.mul(T),M);(0,n.textureStore)(e,(0,n.uvec2)((0,n.uint)(_),(0,n.uint)(v)),(0,n.vec4)(N,1)).toWriteOnly()})})().compute([this._dispatchX,this._dispatchY,1],[8,8,1])}render(e){if(!this.enabled)return;let t=e.getTexture(this.inputTextureName)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`),n=e.getTexture(this.normalDepthTextureName),r=e.getTexture(this.shadingNormalTextureName)||n,i=e.getTexture(this.albedoTextureName),a=e.getTexture(this.varianceTextureName);if(!t)return;let o=t.image;o&&o.width>0&&o.height>0&&(o.width!==this._outputTarget.width||o.height!==this._outputTarget.height)&&this.setSize(o.width,o.height),n&&(this._normalDepthTexNode.value=n),r&&(this._shadingNormalTexNode.value=r),i&&(this._albedoTexNode.value=i),this._compiled||=(this.renderer.compute(this._computeNodeA),this.renderer.compute(this._computeNodeB),!0),a&&(this._varianceTexNode.value=a);let s=t,c=this._computeNodeA,l=this._computeNodeB;for(let e=0;e<this.iterations;e++){this.stepSizeU.value=1<<e,this._readTexNode.value=s,this.isLastIterationU.value=+(e===this.iterations-1),this.renderer.compute(c),s=c===this._computeNodeA?this._storageTexA:this._storageTexB;let t=c;c=l,l=t}this._srcRegion.max.set(this._outputTarget.width,this._outputTarget.height),this.renderer.copyTextureToTexture(s,this._outputTarget.texture,this._srcRegion),e.setTexture(`bilateralFiltering:output`,this._outputTarget.texture)}updateParameters(e){e&&(e.phiColor!==void 0&&(this.phiColor.value=e.phiColor),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth),e.phiLuminance!==void 0&&(this.phiLuminance.value=e.phiLuminance),e.spatialVarianceWeight!==void 0&&(this.spatialVarianceWeight.value=e.spatialVarianceWeight),e.atrousIterations!==void 0&&(this.iterations=e.atrousIterations))}setSize(e,t){this._outputTarget.setSize(e,t),this._outputTarget.texture.needsUpdate=!0,this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/8),this._dispatchY=Math.ceil(t/8),this._computeNodeA.dispatchSize=[this._dispatchX,this._dispatchY,1],this._computeNodeB.dispatchSize=[this._dispatchX,this._dispatchY,1]}releaseGPUMemory(){this._storageTexA?.dispose(),this._storageTexB?.dispose(),this.context?.removeTexture(`bilateralFiltering:output`),this._outputTarget?.texture?.dispose()}reset(){}dispose(){this._computeNodeA?.dispose(),this._computeNodeB?.dispose(),this._storageTexA?.dispose(),this._storageTexB?.dispose(),this._outputTarget?.dispose(),this._readTexNode?.dispose(),this._normalDepthTexNode?.dispose(),this._shadingNormalTexNode?.dispose(),this._albedoTexNode?.dispose(),this._varianceTexNode?.dispose()}},$s=class extends ve{constructor(e,i={}){super(`EdgeAwareFiltering`,{...i,executionMode:_e.PER_CYCLE}),this.renderer=e,this.filterStrength=(0,n.uniform)(i.filterStrength??.75),this.strengthDecaySpeed=(0,n.uniform)(i.strengthDecaySpeed??.05),this.edgeThreshold=(0,n.uniform)(i.edgeThreshold??1),this.phiNormal=(0,n.uniform)(i.phiNormal??128),this.phiDepth=(0,n.uniform)(i.phiDepth??1),this.iterationCount=(0,n.uniform)(0),this.resW=(0,n.uniform)(i.width||1),this.resH=(0,n.uniform)(i.height||1),this._iterations=0,this._inputTexNode=new t.TextureNode,this._ndTexNode=new t.TextureNode;let a=i.width||1,o=i.height||1;this._outputStorageTex=new t.StorageTexture(H,H),this._outputStorageTex.type=r.HalfFloatType,this._outputStorageTex.format=r.RGBAFormat,this._outputStorageTex.minFilter=r.NearestFilter,this._outputStorageTex.magFilter=r.NearestFilter,this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),this.outputTarget=new t.RenderTarget(a,o,{type:r.HalfFloatType,format:r.RGBAFormat,minFilter:r.NearestFilter,magFilter:r.NearestFilter,depthBuffer:!1,stencilBuffer:!1}),this._dispatchX=Math.ceil(a/16),this._dispatchY=Math.ceil(o/16),this._buildCompute()}_buildCompute(){let e=this._inputTexNode,t=this._ndTexNode,r=this._outputStorageTex,i=this.filterStrength,a=this.strengthDecaySpeed,o=this.edgeThreshold,s=this.phiNormal,c=this.phiDepth,l=this.iterationCount,u=this.resW,d=this.resH;this._computeNode=(0,n.Fn)(()=>{let f=(0,n.int)(n.workgroupId.x).mul(16).add((0,n.int)(n.localId.x)),p=(0,n.int)(n.workgroupId.y).mul(16).add((0,n.int)(n.localId.y));(0,n.If)(f.lessThan((0,n.int)(u)).and(p.lessThan((0,n.int)(d))),()=>{let m=(0,n.ivec2)(f,p),h=(0,n.textureLoad)(e,m).xyz,g=(0,n.dot)(h,Xt),_=6e4,v=(0,n.textureLoad)(t,m),y=v.xyz.mul(2).sub(1),b=v.w,x=(0,n.step)((0,n.float)(_),b).oneMinus(),S=i.sub(l.mul(a)).clamp(0,1),C=h.toVar(),w=(0,n.float)(1).toVar();for(let[r,i]of[[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[-1,-1],[1,-1]])for(let a of[1,2]){let l=(0,n.ivec2)(f.add(r*a).clamp((0,n.int)(0),(0,n.int)(u).sub(1)),p.add(i*a).clamp((0,n.int)(0),(0,n.int)(d).sub(1))),m=(0,n.textureLoad)(e,l).xyz,h=(0,n.dot)(m,Xt),v=(0,n.textureLoad)(t,l),S=v.xyz.mul(2).sub(1),T=v.w,E=(0,n.step)((0,n.float)(_),T).oneMinus(),D=(0,n.abs)(g.sub(h)).div((0,n.max)(o,(0,n.float)(.001))).negate().exp(),O=x.mul(E),k=x.oneMinus().mul(E.oneMinus()),A=O.add(k),j=(0,n.pow)((0,n.dot)(y,S).clamp(0,1),s),M=(0,n.abs)(b.sub(T)).div((0,n.max)(c,(0,n.float)(.001))).negate().exp(),N=(0,n.mix)((0,n.float)(1),j.mul(M),O),ee=(0,n.float)(1).div((0,n.float)(a).add(.5)),te=D.mul(N).mul(A).mul(ee);C.addAssign(m.mul(te)),w.addAssign(te)}let T=(0,n.mix)(h,C.div((0,n.max)(w,(0,n.float)(1e-4))),S),E=(0,n.dot)(T,Xt),D=T.toVar();(0,n.If)(E.greaterThan(10),()=>{D.assign(T.mul((0,n.float)(10).div(E)))}),(0,n.textureStore)(r,(0,n.uvec2)((0,n.uint)(f),(0,n.uint)(p)),(0,n.vec4)(D,1)).toWriteOnly()})})().compute([this._dispatchX,this._dispatchY,1],[16,16,1])}render(e){if(!this.enabled)return;let t=e.getTexture(`asvgf:output`)||e.getTexture(`bilateralFiltering:output`)||e.getTexture(`pathtracer:color`),n=e.getTexture(`pathtracer:normalDepth`);if(!t||!n){t&&e.setTexture(`edgeFiltering:output`,t);return}if(e.getState(`interactionMode`)){e.setTexture(`edgeFiltering:output`,t);return}let r=t.image;r&&r.width>0&&r.height>0&&(r.width!==this.outputTarget.width||r.height!==this.outputTarget.height)&&this.setSize(r.width,r.height),this._inputTexNode.value=t,this._ndTexNode.value=n,this._iterations++,this.iterationCount.value=this._iterations,this.renderer.compute(this._computeNode),this._srcRegion.max.set(this.outputTarget.width,this.outputTarget.height),this.renderer.copyTextureToTexture(this._outputStorageTex,this.outputTarget.texture,this._srcRegion),e.setTexture(`edgeFiltering:output`,this.outputTarget.texture)}setFilteringEnabled(e){this.enabled=e}updateUniforms(e){e&&(e.filterStrength!==void 0&&(this.filterStrength.value=e.filterStrength),e.strengthDecaySpeed!==void 0&&(this.strengthDecaySpeed.value=e.strengthDecaySpeed),e.edgeThreshold!==void 0&&(this.edgeThreshold.value=e.edgeThreshold),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth))}releaseGPUMemory(){this._outputStorageTex?.dispose(),this.context?.removeTexture(`edgeFiltering:output`),this.outputTarget?.texture?.dispose(),this.reset()}reset(){this._iterations=0,this.iterationCount.value=0}setSize(e,t){this.outputTarget.setSize(e,t),this.outputTarget.texture.needsUpdate=!0,this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/16),this._dispatchY=Math.ceil(t/16),this._computeNode.dispatchSize=[this._dispatchX,this._dispatchY,1]}dispose(){this._computeNode?.dispose(),this._outputStorageTex?.dispose(),this.outputTarget?.dispose(),this._inputTexNode?.dispose(),this._ndTexNode?.dispose()}},ec=256,tc=-8,nc=6-tc,rc=nc/ec,ic=1e4,ac=(0,n.wgslFn)(`
702
+ `),Qs=class extends ve{constructor(e,i={}){super(`BilateralFiltering`,{...i,executionMode:_e.ALWAYS}),this.renderer=e,this.inputTextureName=i.inputTextureName||`asvgf:demodulated`,this.normalDepthTextureName=i.normalDepthTextureName||`pathtracer:normalDepth`,this.shadingNormalTextureName=i.shadingNormalTextureName||`pathtracer:shadingNormal`,this.albedoTextureName=i.albedoTextureName||`pathtracer:albedo`,this.varianceTextureName=i.varianceTextureName||`variance:output`,this.iterations=i.iterations??4,this.phiColor=(0,n.uniform)(i.phiColor??.5),this.phiNormal=(0,n.uniform)(i.phiNormal??128),this.phiDepth=(0,n.uniform)(i.phiDepth??.05),this.phiLuminance=(0,n.uniform)(i.phiLuminance??4),this.spatialVarianceWeight=(0,n.uniform)(i.spatialVarianceWeight??1),this.stepSizeU=(0,n.uniform)(1,`int`),this.isLastIterationU=(0,n.uniform)(0,`int`),this.resW=(0,n.uniform)(i.width||1),this.resH=(0,n.uniform)(i.height||1),this._readTexNode=new t.TextureNode,this._normalDepthTexNode=new t.TextureNode,this._shadingNormalTexNode=new t.TextureNode,this._albedoTexNode=new t.TextureNode,this._varianceTexNode=new t.TextureNode;let a=i.width||1,o=i.height||1;this._storageTexA=new t.StorageTexture(H,H),this._storageTexA.type=r.HalfFloatType,this._storageTexA.format=r.RGBAFormat,this._storageTexA.minFilter=r.LinearFilter,this._storageTexA.magFilter=r.LinearFilter,this._storageTexB=new t.StorageTexture(H,H),this._storageTexB.type=r.HalfFloatType,this._storageTexB.format=r.RGBAFormat,this._storageTexB.minFilter=r.LinearFilter,this._storageTexB.magFilter=r.LinearFilter,this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),this._outputTarget=new t.RenderTarget(a,o,{type:r.HalfFloatType,format:r.RGBAFormat,minFilter:r.LinearFilter,magFilter:r.LinearFilter,depthBuffer:!1,stencilBuffer:!1}),this._compiled=!1,this._dispatchX=Math.ceil(a/8),this._dispatchY=Math.ceil(o/8),this._buildCompute()}_buildCompute(){this._computeNodeA=this._buildComputeForDirection(this._storageTexA),this._computeNodeB=this._buildComputeForDirection(this._storageTexB)}_buildComputeForDirection(e){let t=this._readTexNode,r=this._normalDepthTexNode,i=this._shadingNormalTexNode,a=this._albedoTexNode,o=this._varianceTexNode,s=this.phiColor,c=this.phiNormal,l=this.phiDepth,u=this.phiLuminance,d=this.spatialVarianceWeight,f=this.stepSizeU,p=this.isLastIterationU,m=this.resW,h=this.resH,g=[1/256,4/256,6/256,4/256,1/256,4/256,16/256,24/256,16/256,4/256,6/256,24/256,36/256,24/256,6/256,4/256,16/256,24/256,16/256,4/256,1/256,4/256,6/256,4/256,1/256];return(0,n.Fn)(()=>{let _=(0,n.int)(n.workgroupId.x).mul(8).add((0,n.int)(n.localId.x)),v=(0,n.int)(n.workgroupId.y).mul(8).add((0,n.int)(n.localId.y));(0,n.If)(_.lessThan((0,n.int)(m)).and(v.lessThan((0,n.int)(h))),()=>{let y=(0,n.ivec2)(_,v),b=(0,n.textureLoad)(t,y).xyz,x=(0,n.textureLoad)(r,y),S=(0,n.textureLoad)(i,y).xyz.mul(2).sub(1),C=x.w,w=tn(b),T=(0,n.max)((0,n.textureLoad)(a,y).xyz,(0,n.vec3)(V)),E=(0,n.max)(tn(T),(0,n.float)(V)).toVar(),D=(0,n.textureLoad)(o,y),O=(0,n.mix)(D.z,(0,n.max)(D.z,D.w),d),k=u.mul((0,n.sqrt)((0,n.max)(O,(0,n.float)(0)))).div(E).add((0,n.float)(1e-4)),A=(0,n.vec3)(0).toVar(),j=(0,n.float)(0).toVar();for(let e=0;e<5;e++)for(let a=0;a<5;a++){let o=a-2,u=e-2,d=g[e*5+a],p=_.add(f.mul(o)).clamp((0,n.int)(0),(0,n.int)(m).sub(1)),y=v.add(f.mul(u)).clamp((0,n.int)(0),(0,n.int)(h).sub(1)),x=(0,n.textureLoad)(t,(0,n.ivec2)(p,y)).xyz,T=(0,n.textureLoad)(r,(0,n.ivec2)(p,y)),E=(0,n.textureLoad)(i,(0,n.ivec2)(p,y)).xyz.mul(2).sub(1),D=T.w,O=Zs(w,tn(x),S,E,C,D,b,x,(0,n.float)(d),k,c,l,s);A.addAssign(x.mul(O)),j.addAssign(O)}let M=A.div((0,n.max)(j,(0,n.float)(1e-4))),N=p.equal((0,n.int)(1)).select(M.mul(T),M);(0,n.textureStore)(e,(0,n.uvec2)((0,n.uint)(_),(0,n.uint)(v)),(0,n.vec4)(N,1)).toWriteOnly()})})().compute([this._dispatchX,this._dispatchY,1],[8,8,1])}render(e){if(!this.enabled)return;let t=e.getTexture(this.inputTextureName)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`),n=e.getTexture(this.normalDepthTextureName),r=e.getTexture(this.shadingNormalTextureName)||n,i=e.getTexture(this.albedoTextureName),a=e.getTexture(this.varianceTextureName);if(!t)return;let o=t.image;o&&o.width>0&&o.height>0&&(o.width!==this._outputTarget.width||o.height!==this._outputTarget.height)&&this.setSize(o.width,o.height),n&&(this._normalDepthTexNode.value=n),r&&(this._shadingNormalTexNode.value=r),i&&(this._albedoTexNode.value=i),this._compiled||=(this.renderer.compute(this._computeNodeA),this.renderer.compute(this._computeNodeB),!0),a&&(this._varianceTexNode.value=a);let s=t,c=this._computeNodeA,l=this._computeNodeB;for(let e=0;e<this.iterations;e++){this.stepSizeU.value=1<<e,this._readTexNode.value=s,this.isLastIterationU.value=+(e===this.iterations-1),this.renderer.compute(c),s=c===this._computeNodeA?this._storageTexA:this._storageTexB;let t=c;c=l,l=t}this._srcRegion.max.set(this._outputTarget.width,this._outputTarget.height),this.renderer.copyTextureToTexture(s,this._outputTarget.texture,this._srcRegion),e.setTexture(`bilateralFiltering:output`,this._outputTarget.texture)}updateParameters(e){e&&(e.phiColor!==void 0&&(this.phiColor.value=e.phiColor),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth),e.phiLuminance!==void 0&&(this.phiLuminance.value=e.phiLuminance),e.spatialVarianceWeight!==void 0&&(this.spatialVarianceWeight.value=e.spatialVarianceWeight),e.atrousIterations!==void 0&&(this.iterations=e.atrousIterations))}setSize(e,t){this._outputTarget.setSize(e,t),this._outputTarget.texture.needsUpdate=!0,this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/8),this._dispatchY=Math.ceil(t/8),this._computeNodeA.dispatchSize=[this._dispatchX,this._dispatchY,1],this._computeNodeB.dispatchSize=[this._dispatchX,this._dispatchY,1]}releaseGPUMemory(){this._storageTexA?.dispose(),this._storageTexB?.dispose(),this.context?.removeTexture(`bilateralFiltering:output`),this._outputTarget?.texture?.dispose()}reset(){}dispose(){this._computeNodeA?.dispose(),this._computeNodeB?.dispose(),this._storageTexA?.dispose(),this._storageTexB?.dispose(),this._outputTarget?.dispose(),this._readTexNode?.dispose(),this._normalDepthTexNode?.dispose(),this._shadingNormalTexNode?.dispose(),this._albedoTexNode?.dispose(),this._varianceTexNode?.dispose()}},$s=6e4,ec=e=>(0,n.select)(e.equal(e),e,(0,n.float)(0)).clamp(0,1e7),tc=e=>(0,n.vec3)(ec(e.x),ec(e.y),ec(e.z)),nc=[1/256,4/256,6/256,4/256,1/256,4/256,16/256,24/256,16/256,4/256,6/256,24/256,36/256,24/256,6/256,4/256,16/256,24/256,16/256,4/256,1/256,4/256,6/256,4/256,1/256],rc=class extends ve{constructor(e,i={}){super(`EdgeAwareFiltering`,{...i,executionMode:_e.PER_CYCLE}),this.renderer=e,this.filterStrength=(0,n.uniform)(i.filterStrength??1),this.phiLuminance=(0,n.uniform)(i.phiLuminance??4),this.phiNormal=(0,n.uniform)(i.phiNormal??64),this.phiDepth=(0,n.uniform)(i.phiDepth??.1),this.iterations=i.atrousIterations??i.edgeAtrousIterations??5,this.stepSizeU=(0,n.uniform)(1,`int`),this.isLastIterationU=(0,n.uniform)(0,`int`),this.resW=(0,n.uniform)(i.width||1),this.resH=(0,n.uniform)(i.height||1),this._colorTexNode=new t.TextureNode,this._ndTexNode=new t.TextureNode,this._snTexNode=new t.TextureNode,this._albedoTexNode=new t.TextureNode,this._varTexNode=new t.TextureNode,this._readTexNode=new t.TextureNode;let a=i.width||1,o=i.height||1;this._demodTex=this._makeStorageTex(),this._storageTexA=this._makeStorageTex(),this._storageTexB=this._makeStorageTex(),this._srcRegion=new r.Box2(new r.Vector2(0,0),new r.Vector2(0,0)),this.outputTarget=new t.RenderTarget(a,o,{type:r.FloatType,format:r.RGBAFormat,minFilter:r.LinearFilter,magFilter:r.LinearFilter,depthBuffer:!1,stencilBuffer:!1}),this._compiled=!1,this._dispatchX=Math.ceil(a/16),this._dispatchY=Math.ceil(o/16),this._buildCompute()}_makeStorageTex(){let e=new t.StorageTexture(H,H);return e.type=r.FloatType,e.format=r.RGBAFormat,e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e}_buildCompute(){this._computeDemod=this._buildDemod(),this._computeAtrousA=this._buildAtrous(this._storageTexA),this._computeAtrousB=this._buildAtrous(this._storageTexB)}_buildDemod(){let e=this._colorTexNode,t=this._ndTexNode,r=this._albedoTexNode,i=this._demodTex,a=this.resW,o=this.resH;return(0,n.Fn)(()=>{let s=(0,n.int)(n.workgroupId.x).mul(16).add((0,n.int)(n.localId.x)),c=(0,n.int)(n.workgroupId.y).mul(16).add((0,n.int)(n.localId.y));(0,n.If)(s.lessThan((0,n.int)(a)).and(c.lessThan((0,n.int)(o))),()=>{let a=(0,n.ivec2)(s,c),o=(0,n.textureLoad)(e,a).xyz,l=(0,n.textureLoad)(t,a).w.lessThan((0,n.float)($s)),u=(0,n.textureLoad)(r,a).xyz,d=(0,n.select)(l,(0,n.max)(u,(0,n.vec3)(V)),(0,n.vec3)(1)),f=tc(o.div(d));(0,n.textureStore)(i,(0,n.uvec2)((0,n.uint)(s),(0,n.uint)(c)),(0,n.vec4)(f,1)).toWriteOnly()})})().compute([this._dispatchX,this._dispatchY,1],[16,16,1])}_buildAtrous(e){let t=this._readTexNode,r=this._colorTexNode,i=this._ndTexNode,a=this._snTexNode,o=this._albedoTexNode,s=this._varTexNode,c=this.filterStrength,l=this.phiLuminance,u=this.phiNormal,d=this.phiDepth,f=this.stepSizeU,p=this.isLastIterationU,m=this.resW,h=this.resH;return(0,n.Fn)(()=>{let g=(0,n.int)(n.workgroupId.x).mul(16).add((0,n.int)(n.localId.x)),_=(0,n.int)(n.workgroupId.y).mul(16).add((0,n.int)(n.localId.y));(0,n.If)(g.lessThan((0,n.int)(m)).and(_.lessThan((0,n.int)(h))),()=>{let v=(0,n.ivec2)(g,_),y=(0,n.textureLoad)(t,v).xyz,b=tn(y),x=(0,n.textureLoad)(i,v).w,S=(0,n.textureLoad)(a,v).xyz.mul(2).sub(1),C=x.lessThan((0,n.float)($s)),w=(0,n.select)(C,(0,n.float)(1),(0,n.float)(0)),T=(0,n.textureLoad)(o,v).xyz,E=(0,n.select)(C,(0,n.max)(T,(0,n.vec3)(V)),(0,n.vec3)(1)),D=(0,n.max)(tn(E),(0,n.float)(V)),O=(0,n.textureLoad)(s,v),k=(0,n.max)(O.z,O.w),A=l.mul((0,n.sqrt)((0,n.max)(k,(0,n.float)(0)))).div(D).add((0,n.float)(1e-4)),j=(0,n.vec3)(0).toVar(),M=(0,n.float)(0).toVar();for(let e=0;e<5;e++)for(let r=0;r<5;r++){let o=r-2,s=e-2,c=nc[e*5+r],l=(0,n.ivec2)(g.add(f.mul(o)).clamp((0,n.int)(0),(0,n.int)(m).sub(1)),_.add(f.mul(s)).clamp((0,n.int)(0),(0,n.int)(h).sub(1))),p=(0,n.textureLoad)(t,l).xyz,v=tn(p),y=(0,n.textureLoad)(i,l).w,C=(0,n.textureLoad)(a,l).xyz.mul(2).sub(1),T=(0,n.select)(y.lessThan((0,n.float)($s)),(0,n.float)(1),(0,n.float)(0)),E=b.sub(v).abs().div(A).negate().exp(),D=(0,n.pow)((0,n.dot)(S,C).clamp(0,1),u),O=x.sub(y).abs().div((0,n.max)(x.mul(d),(0,n.float)(.001))).negate().exp(),k=w.mul(T),N=w.oneMinus().mul(T.oneMinus()),ee=k.add(N),te=(0,n.mix)((0,n.float)(1),D.mul(O),k),ne=(0,n.float)(c).mul(E).mul(te).mul(ee);j.addAssign(p.mul(ne)),M.addAssign(ne)}let N=j.div((0,n.max)(M,(0,n.float)(1e-4))),ee=p.equal((0,n.int)(1)),te=(0,n.textureLoad)(r,v).xyz,ne=(0,n.mix)(te,N.mul(E),c),re=ee.select(ne,N);(0,n.textureStore)(e,(0,n.uvec2)((0,n.uint)(g),(0,n.uint)(_)),(0,n.vec4)(re,1)).toWriteOnly()})})().compute([this._dispatchX,this._dispatchY,1],[16,16,1])}render(e){if(!this.enabled)return;let t=e.getTexture(`pathtracer:color`),n=e.getTexture(`pathtracer:normalDepth`),r=e.getTexture(`pathtracer:shadingNormal`)||n,i=e.getTexture(`pathtracer:albedo`),a=e.getTexture(`variance:output`);if(!t||!n||!i||!a){t&&e.setTexture(`edgeFiltering:output`,t);return}if(e.getState(`interactionMode`)){e.setTexture(`edgeFiltering:output`,t);return}let o=t.image;o&&o.width>0&&o.height>0&&(o.width!==this.outputTarget.width||o.height!==this.outputTarget.height)&&this.setSize(o.width,o.height),this._colorTexNode.value=t,this._ndTexNode.value=n,this._snTexNode.value=r,this._albedoTexNode.value=i,this._varTexNode.value=a,this._compiled||=(this.renderer.compute(this._computeDemod),this.renderer.compute(this._computeAtrousA),this.renderer.compute(this._computeAtrousB),!0),this.renderer.compute(this._computeDemod);let s=this._demodTex,c=this._computeAtrousA,l=this._computeAtrousB;for(let e=0;e<this.iterations;e++){this.stepSizeU.value=1<<e,this.isLastIterationU.value=+(e===this.iterations-1),this._readTexNode.value=s,this.renderer.compute(c),s=c===this._computeAtrousA?this._storageTexA:this._storageTexB;let t=c;c=l,l=t}this._srcRegion.max.set(this.outputTarget.width,this.outputTarget.height),this.renderer.copyTextureToTexture(s,this.outputTarget.texture,this._srcRegion),e.setTexture(`edgeFiltering:output`,this.outputTarget.texture)}setFilteringEnabled(e){this.enabled=e}updateUniforms(e){e&&(e.filterStrength!==void 0&&(this.filterStrength.value=e.filterStrength),e.phiLuminance!==void 0&&(this.phiLuminance.value=e.phiLuminance),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth),e.atrousIterations!==void 0&&(this.iterations=e.atrousIterations))}releaseGPUMemory(){this._demodTex?.dispose(),this._storageTexA?.dispose(),this._storageTexB?.dispose(),this.context?.removeTexture(`edgeFiltering:output`),this.outputTarget?.texture?.dispose()}reset(){}setSize(e,t){this.outputTarget.setSize(e,t),this.outputTarget.texture.needsUpdate=!0,this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/16),this._dispatchY=Math.ceil(t/16);let n=[this._dispatchX,this._dispatchY,1];this._computeDemod.dispatchSize=n,this._computeAtrousA.dispatchSize=n,this._computeAtrousB.dispatchSize=n}dispose(){this._computeDemod?.dispose(),this._computeAtrousA?.dispose(),this._computeAtrousB?.dispose(),this._demodTex?.dispose(),this._storageTexA?.dispose(),this._storageTexB?.dispose(),this.outputTarget?.dispose(),this._colorTexNode?.dispose(),this._ndTexNode?.dispose(),this._snTexNode?.dispose(),this._albedoTexNode?.dispose(),this._varTexNode?.dispose(),this._readTexNode?.dispose()}},ic=256,ac=-8,oc=6-ac,sc=oc/ic,cc=1e4,lc=(0,n.wgslFn)(`
703
703
  fn adaptExposure(
704
704
  geoMean: f32,
705
705
  prevExposure: f32,
@@ -728,8 +728,8 @@
728
728
  return vec4f( newExposure, geoMean, targetExp, 1.0 );
729
729
 
730
730
  }
731
- `),oc=class extends ve{constructor(e,r={}){super(`AutoExposure`,{...r,executionMode:_e.ALWAYS}),this.renderer=e,this.REDUCTION_SIZE=64,this.keyValueU=(0,n.uniform)(r.keyValue??.18),this.minExposureU=(0,n.uniform)(r.minExposure??.1),this.maxExposureU=(0,n.uniform)(r.maxExposure??20),this.adaptSpeedBrightU=(0,n.uniform)(r.adaptSpeedBright??3),this.adaptSpeedDarkU=(0,n.uniform)(r.adaptSpeedDark??.5),this.epsilonU=(0,n.uniform)(r.epsilon??1e-4),this.deltaTimeU=(0,n.uniform)(1/60),this.isFirstFrameU=(0,n.uniform)(1),this.previousExposureU=(0,n.uniform)(r.initialExposure??1),this.lowPercentileU=(0,n.uniform)(r.lowPercentile??.1),this.highPercentileU=(0,n.uniform)(r.highPercentile??.9),this.centerWeightU=(0,n.uniform)(r.centerWeight??8),this.inputResW=(0,n.uniform)(1),this.inputResH=(0,n.uniform)(1),this._inputTexNode=new t.TextureNode,this._reductionReadTexNode=new t.TextureNode,this.currentExposure=r.initialExposure??1,this.currentLuminance=.18,this.targetExposure=1,this.lastTime=performance.now(),this.isFirstFrame=!0,this._pendingReadback=!1,this._readbackGeneration=0,this._initRenderTargets(),this._buildCompute()}_initRenderTargets(){let e={type:r.FloatType,format:r.RGBAFormat,minFilter:r.NearestFilter,magFilter:r.NearestFilter,depthBuffer:!1,stencilBuffer:!1};this._downsampleTarget=new t.RenderTarget(this.REDUCTION_SIZE,this.REDUCTION_SIZE,e),this._downsampleStorageTex=new t.StorageTexture(this.REDUCTION_SIZE,this.REDUCTION_SIZE),this._downsampleStorageTex.type=r.FloatType,this._downsampleStorageTex.format=r.RGBAFormat,this._downsampleStorageTex.minFilter=r.NearestFilter,this._downsampleStorageTex.magFilter=r.NearestFilter,this._reductionStorageTex=new t.StorageTexture(1,1),this._reductionStorageTex.type=r.FloatType,this._reductionStorageTex.format=r.RGBAFormat,this._reductionStorageTex.minFilter=r.NearestFilter,this._reductionStorageTex.magFilter=r.NearestFilter,this._reductionReadTarget=new t.RenderTarget(1,1,e),this._adaptationResult=(0,n.attributeArray)(1,`vec4`),this._readbackBuffer=new t.ReadbackBuffer(16),this._readbackBuffer.name=`AutoExposureAdaptation`,this._histogramBuffer=(0,n.attributeArray)(ec,`uint`).toAtomic()}_buildCompute(){this._buildDownsampleCompute(),this._buildHistogramCompute(),this._buildHistogramAnalyzeCompute(),this._buildAdaptationCompute()}_buildDownsampleCompute(){let e=this._inputTexNode,t=this._downsampleStorageTex,r=this.epsilonU,i=this.inputResW,a=this.inputResH;this._downsampleComputeNode=(0,n.Fn)(()=>{let o=(0,n.int)(n.workgroupId.x).mul(8).add((0,n.int)(n.localId.x)),s=(0,n.int)(n.workgroupId.y).mul(8).add((0,n.int)(n.localId.y)),c=i.div((0,n.float)(64)),l=a.div((0,n.float)(64)),u=(0,n.float)(o).mul(c),d=(0,n.float)(s).mul(l),f=(0,n.float)(0).toVar(),p=(0,n.float)(0).toVar();for(let t=0;t<4;t++)for(let i=0;i<4;i++){let a=tn((0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(u.add((0,n.float)((i+.5)/4).mul(c))),(0,n.int)(d.add((0,n.float)((t+.5)/4).mul(l))))).xyz);(0,n.If)(a.greaterThan(r),()=>{f.addAssign(a.add(r).log()),p.addAssign(1)})}(0,n.textureStore)(t,(0,n.uvec2)((0,n.uint)(o),(0,n.uint)(s)),(0,n.vec4)(f,p,0,1)).toWriteOnly()})().compute([64/8,64/8,1],[8,8,1])}_buildHistogramCompute(){let e=this._downsampleTarget.texture,t=this._histogramBuffer,r=this.centerWeightU;this._histogramComputeNode=(0,n.Fn)(()=>{let i=n.localId.x;(0,n.atomicStore)(t.element(i),(0,n.uint)(0)),(0,n.workgroupBarrier)();for(let a=0;a<16;a++){let o=i.mul(16).add(a),s=o.mod(64),c=o.div(64),l=(0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(s),(0,n.int)(c))),u=l.x,d=l.y;(0,n.If)(d.greaterThan(0),()=>{let e=(0,n.uint)(u.div(d).sub((0,n.float)(tc)).div((0,n.float)(nc)).mul((0,n.float)(ec)).floor().clamp(0,(0,n.float)(ec-1))),i=(0,n.float)(s).add(.5).div((0,n.float)(64)),a=(0,n.float)(c).add(.5).div((0,n.float)(64)),o=i.sub(.5),l=a.sub(.5),f=(0,n.uint)(o.mul(o).add(l.mul(l)).mul(r).negate().exp().mul((0,n.float)(ic)));(0,n.atomicAdd)(t.element(e),f)})}})().compute([1,1,1],[256,1,1])}_buildHistogramAnalyzeCompute(){let e=this._histogramBuffer,t=this._reductionStorageTex,r=this.lowPercentileU,i=this.highPercentileU;this._histogramAnalyzeNode=(0,n.Fn)(()=>{let a=(0,n.float)(0).toVar();(0,n.Loop)(ec,({i:t})=>{a.addAssign((0,n.float)((0,n.atomicLoad)(e.element(t))))});let o=a.mul(r),s=a.mul(i),c=(0,n.float)(0).toVar(),l=(0,n.float)(0).toVar(),u=(0,n.float)(0).toVar(),d=(0,n.float)(0).toVar();(0,n.Loop)(ec,({i:t})=>{let r=(0,n.float)((0,n.atomicLoad)(e.element(t)));d.assign(c),c.addAssign(r),(0,n.If)(d.lessThan(s).and(c.greaterThan(o)),()=>{let e=(0,n.float)(tc).add((0,n.float)(t).add(.5).mul((0,n.float)(rc)));l.addAssign(e.mul(r)),u.addAssign(r)})});let f=(0,n.max)(u,(0,n.float)(1)),p=l.div(f),m=p.exp();(0,n.textureStore)(t,(0,n.uvec2)((0,n.uint)(0),(0,n.uint)(0)),(0,n.vec4)(m,a,p,1)).toWriteOnly()})().compute(1,[1,1,1])}_buildAdaptationCompute(){let e=this._reductionReadTexNode,t=this._adaptationResult,r=this.keyValueU,i=this.minExposureU,a=this.maxExposureU,o=this.adaptSpeedBrightU,s=this.adaptSpeedDarkU,c=this.deltaTimeU,l=this.isFirstFrameU,u=this.previousExposureU;this._adaptationComputeNode=(0,n.Fn)(()=>{let d=(0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(0),(0,n.int)(0))).x,f=ac(d,u,r,i,a,o,s,c,l);t.element((0,n.uint)(0)).assign(f)})().compute(1,[1,1,1])}setupEventListeners(){this.on(`pipeline:reset`,()=>this.reset()),this.on(`autoexposure:resetHistory`,()=>this.resetHistory()),this.on(`autoexposure:toggle`,e=>{this.enabled=e}),this.on(`autoexposure:updateParameters`,e=>e&&this.updateParameters(e))}render(e){if(!this.enabled)return;let t=e.getTexture(`edgeFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`);if(!t)return;let n=performance.now(),r=Math.min((n-this.lastTime)/1e3,.1);if(this.lastTime=n,this.deltaTimeU.value=this.isFirstFrame?1:r,this.isFirstFrameU.value=+!!this.isFirstFrame,this.previousExposureU.value=this.currentExposure,this.inputResW.value=t.image?.width||1,this.inputResH.value=t.image?.height||1,this._inputTexNode.value=t,this.renderer.compute(this._downsampleComputeNode),this.renderer.copyTextureToTexture(this._downsampleStorageTex,this._downsampleTarget.texture),this.renderer.compute(this._histogramComputeNode),this.renderer.compute(this._histogramAnalyzeNode),this.renderer.copyTextureToTexture(this._reductionStorageTex,this._reductionReadTarget.texture),this._reductionReadTexNode.value=this._reductionReadTarget.texture,this.renderer.compute(this._adaptationComputeNode),!this._pendingReadback){this._pendingReadback=!0;let e=this._readbackGeneration;this.renderer.getArrayBufferAsync(this._adaptationResult.value,this._readbackBuffer).then(t=>{let n=t&&t.buffer?new Float32Array(t.buffer.slice(0)):null;this._readbackBuffer.release(),this._pendingReadback=!1,n&&e===this._readbackGeneration&&this._applyReadback(n)}).catch(()=>{try{this._readbackBuffer.release()}catch{}this._pendingReadback=!1})}e.setState(`autoexposure:value`,this.currentExposure),e.setState(`autoexposure:avgLuminance`,this.currentLuminance),this.emit(`autoexposure:updated`,{exposure:this.currentExposure,luminance:this.currentLuminance,targetExposure:this.targetExposure}),this.isFirstFrame=!1}_applyReadback(e){if(!this.enabled||!e||e.length<3)return;let t=e[0],n=e[1],r=e[2];(!isFinite(t)||t<=0)&&(t=1),(!isFinite(n)||n<=0)&&(n=.18),(!isFinite(r)||r<=0)&&(r=t),this.currentExposure=t,this.currentLuminance=n,this.targetExposure=r,this.renderer.toneMappingExposure=t}reset(){this.lastTime=performance.now(),this._readbackGeneration++,this._pendingReadback=!1}resetHistory(){this.isFirstFrame=!0,this.currentExposure=1,this.currentLuminance=.18,this.targetExposure=1,this.lastTime=performance.now(),this._readbackGeneration++,this._pendingReadback=!1}setSize(){}setExposure(e){this.currentExposure=e,this.previousExposureU.value=e,this.renderer.toneMappingExposure=e}getExposure(){return this.currentExposure}getLuminance(){return this.currentLuminance}updateParameters(e){e.keyValue!==void 0&&(this.keyValueU.value=e.keyValue),e.minExposure!==void 0&&(this.minExposureU.value=e.minExposure),e.maxExposure!==void 0&&(this.maxExposureU.value=e.maxExposure),e.adaptSpeedBright!==void 0&&(this.adaptSpeedBrightU.value=e.adaptSpeedBright),e.adaptSpeedDark!==void 0&&(this.adaptSpeedDarkU.value=e.adaptSpeedDark),e.lowPercentile!==void 0&&(this.lowPercentileU.value=e.lowPercentile),e.highPercentile!==void 0&&(this.highPercentileU.value=e.highPercentile),e.centerWeight!==void 0&&(this.centerWeightU.value=e.centerWeight)}dispose(){this._downsampleComputeNode?.dispose(),this._histogramComputeNode?.dispose(),this._histogramAnalyzeNode?.dispose(),this._adaptationComputeNode?.dispose(),this._downsampleTarget?.dispose(),this._downsampleStorageTex?.dispose(),this._reductionStorageTex?.dispose(),this._reductionReadTarget?.dispose(),this._readbackBuffer?.dispose(),this._inputTexNode?.dispose(),this._reductionReadTexNode?.dispose()}},sc=class extends ve{constructor(e,i={}){super(`Compositor`,{...i,executionMode:_e.ALWAYS}),this.renderer=e,this.saturation=(0,n.uniform)(i.saturation??1),this._transparentBackground=(0,n.uniform)(0,`int`),this._sourceTexNode=new t.TextureNode;let a=this._sourceTexNode.sample((0,n.uv)()),o=(0,n.mix)((0,n.vec3)((0,n.dot)(a.xyz,Xt)),a.xyz,this.saturation),s=(0,n.select)(this._transparentBackground,a.w,1);this.compositorMaterial=new t.MeshBasicNodeMaterial,this.compositorMaterial.colorNode=(0,n.vec4)(o,s),this.compositorMaterial.blending=r.NoBlending,this.compositorQuad=new t.QuadMesh(this.compositorMaterial)}_resolveSourceTexture(e){return e.getTexture(`bloom:output`)||e.getTexture(`edgeFiltering:output`)||e.getTexture(`bilateralFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`)}render(e){if(!this.enabled)return;let t=this._resolveSourceTexture(e);t&&(this._sourceTexNode.value=t,this.renderer.setRenderTarget(null),this.compositorQuad.render(this.renderer))}setSaturation(e){this.saturation.value=e}setTransparentBackground(e){this._transparentBackground.value=+!!e}dispose(){this._sourceTexNode?.dispose(),this.compositorMaterial?.dispose(),this.compositorQuad=null}},cc=class{constructor(){this.textures=new Map,this.renderTargets=new Map,this.uniforms=new Map,this.state={frame:0,accumulatedFrames:0,renderMode:0,interactionMode:!1,isComplete:!1,tileInfo:null,currentTile:0,totalTiles:0,cameraChanged:!1,cameraMoving:!1,width:0,height:0,time:0,deltaTime:0,enableASVGF:!1,enableEdgeFiltering:!1},this._stateChangeCallbacks=new Map}setTexture(e,t){this.textures.set(e,t)}getTexture(e){return this.textures.get(e)}hasTexture(e){return this.textures.has(e)}removeTexture(e){this.textures.delete(e)}getTextureNames(){return Array.from(this.textures.keys())}clearTextures(){this.textures.clear()}setRenderTarget(e,t){this.renderTargets.set(e,t)}getRenderTarget(e){return this.renderTargets.get(e)}hasRenderTarget(e){return this.renderTargets.has(e)}removeRenderTarget(e){this.renderTargets.delete(e)}getRenderTargetNames(){return Array.from(this.renderTargets.keys())}clearRenderTargets(){this.renderTargets.clear()}setUniform(e,t){this.uniforms.has(e)?this.uniforms.get(e).value=t:this.uniforms.set(e,{value:t})}getUniform(e){return this.uniforms.get(e)}getUniformValue(e){return this.uniforms.get(e)?.value}hasUniform(e){return this.uniforms.has(e)}removeUniform(e){this.uniforms.delete(e)}getUniformNames(){return Array.from(this.uniforms.keys())}clearUniforms(){this.uniforms.clear()}setState(e,t){let n=this.state[e],r=n!==t;return r&&(this.state[e]=t,this._notifyStateChange(e,t,n)),r}getState(e){return this.state[e]}getAllState(){return this.state}setStates(e){let t=[];for(let[n,r]of Object.entries(e))this.setState(n,r)&&t.push(n);return t}hasState(e){return e in this.state}watchState(e,t){this._stateChangeCallbacks.has(e)||this._stateChangeCallbacks.set(e,[]),this._stateChangeCallbacks.get(e).push(t)}unwatchState(e,t){if(!this._stateChangeCallbacks.has(e))return;let n=this._stateChangeCallbacks.get(e),r=n.indexOf(t);r>-1&&n.splice(r,1)}_notifyStateChange(e,t,n){if(!this._stateChangeCallbacks.has(e))return;let r=this._stateChangeCallbacks.get(e);for(let i of r)try{i(t,n)}catch(t){console.error(`Error in state change callback for '${e}':`,t)}}reset(){this.state.frame=0,this.state.accumulatedFrames=0,this.state.isComplete=!1,this.state.cameraChanged=!0,this.state.currentTile=0}incrementFrame(){return this.state.frame++,this.state.accumulatedFrames++,this.state.frame}dispose(){this.textures.clear(),this.renderTargets.clear(),this.uniforms.clear(),this._stateChangeCallbacks.clear(),this.state={}}},lc=class extends r.EventDispatcher{constructor(){super(),this._onceCallbacks=new Map}on(e,t){this.addEventListener(e,t)}once(e,t){let n=r=>{t(r),this.off(e,n),this._onceCallbacks.delete(t)};this._onceCallbacks.set(t,n),this.on(e,n)}off(e,t){let n=this._onceCallbacks.get(t);n?(this.removeEventListener(e,n),this._onceCallbacks.delete(t)):this.removeEventListener(e,t)}emit(e,t){t&&typeof t==`object`&&t.type?this.dispatchEvent(t):this.dispatchEvent({type:e,...t})}removeAllListeners(e){if(e){for(let[t,n]of this._onceCallbacks.entries())this.hasEventListener(e,n)&&(this.removeEventListener(e,n),this._onceCallbacks.delete(t));this._listeners&&this._listeners[e]&&delete this._listeners[e]}else this._onceCallbacks.clear(),this._listeners&&={}}listenerCount(e){return!this._listeners||!this._listeners[e]?0:this._listeners[e].length}clear(){this.removeAllListeners()}eventNames(){return this._listeners?Object.keys(this._listeners):[]}},uc=class{constructor(e,t,n){this.renderer=e,this.width=t,this.height=n,this.stages=[],this.context=new cc,this.eventBus=new lc,this.context.setState(`width`,t),this.context.setState(`height`,n),this.stats={enabled:!1,logSkipped:!1,timings:new Map,frameCount:0}}addStage(e){this.stages.push(e),e.initialize(this.context,this.eventBus),this.stats.enabled&&console.log(`[Pipeline] Added stage: ${e.name}`)}getStage(e){return this.stages.find(t=>t.name===e)}removeStage(e){let t=this.stages.findIndex(t=>t.name===e);if(t>-1){let e=this.stages[t];return this.stages.splice(t,1),e.dispose&&e.dispose(),this.stats.timings.delete(e.name),!0}return!1}setStageEnabled(e,t){let n=this.getStage(e);n&&(t?n.enable():n.disable())}render(e=null){let t=this.stats.enabled?performance.now():0;for(let t of this.stages){if(!t.shouldExecuteThisFrame(this.context)){this.stats.enabled&&this.stats.logSkipped&&console.log(`[Pipeline] Skipped stage '${t.name}' (executionMode: ${t.executionMode})`);continue}try{let n=this.stats.enabled?performance.now():0;if(t.render(this.context,e),this.stats.enabled){let e=performance.now()-n;this.stats.timings.has(t.name)||this.stats.timings.set(t.name,[]);let r=this.stats.timings.get(t.name);r.push(e),r.length>60&&r.shift()}}catch(e){console.error(`[Pipeline] Error in stage '${t.name}':`,e)}}if(this.context.incrementFrame(),this.eventBus.emit(`frame:complete`,{frame:this.context.getState(`frame`),accumulatedFrames:this.context.getState(`accumulatedFrames`)}),this.stats.enabled){let e=performance.now()-t;this.stats.timings.has(`_total`)||this.stats.timings.set(`_total`,[]);let n=this.stats.timings.get(`_total`);n.push(e),n.length>60&&n.shift(),this.stats.frameCount++}}reset(){this.eventBus.emit(`pipeline:reset`);for(let e of this.stages)if(e.reset)try{e.reset()}catch(t){console.error(`[Pipeline] Error resetting stage '${e.name}':`,t)}this.context.reset(),this.stats.enabled&&(this.stats.timings.clear(),this.stats.frameCount=0)}setSize(e,t){this.width=e,this.height=t,this.context.setState(`width`,e),this.context.setState(`height`,t),this.eventBus.emit(`pipeline:resize`,{width:e,height:t});for(let n of this.stages)if(n.setSize)try{n.setSize(e,t)}catch(e){console.error(`[Pipeline] Error resizing stage '${n.name}':`,e)}}dispose(){for(let e of this.stages)if(e.dispose)try{e.dispose()}catch(t){console.error(`[Pipeline] Error disposing stage '${e.name}':`,t)}this.stages=[],this.context.dispose(),this.eventBus.clear(),this.stats.timings.clear()}setStatsEnabled(e){this.stats.enabled=e,e||(this.stats.timings.clear(),this.stats.frameCount=0)}getStats(){if(!this.stats.enabled)return null;let e={frameCount:this.stats.frameCount,stages:{},total:0};for(let[t,n]of this.stats.timings.entries()){if(n.length===0)continue;let r=n.reduce((e,t)=>e+t,0)/n.length,i=Math.min(...n),a=Math.max(...n);t===`_total`?(e.total=r,e.totalMin=i,e.totalMax=a):e.stages[t]={avg:r,min:i,max:a}}return e}logStats(){let e=this.getStats();if(!e){console.log(`[Pipeline] Stats not enabled`);return}console.group(`[Pipeline] Performance Stats`),console.log(`Frames: ${e.frameCount}`),e.totalMin===void 0?console.log(`Total: no frames recorded yet (pipeline.render() has not run since stats were enabled — the path tracer may have converged and stopped its animation loop)`):console.log(`Total: ${e.total.toFixed(2)}ms (min: ${e.totalMin.toFixed(2)}ms, max: ${e.totalMax.toFixed(2)}ms)`);for(let[t,n]of Object.entries(e.stages))console.log(` ${t}: ${n.avg.toFixed(2)}ms (min: ${n.min.toFixed(2)}ms, max: ${n.max.toFixed(2)}ms)`);console.groupEnd()}getInfo(){return{stageCount:this.stages.length,enabledStages:this.stages.filter(e=>e.enabled).length,stages:this.stages.map(e=>({name:e.name,enabled:e.enabled})),contextState:this.context.getAllState(),textures:this.context.getTextureNames(),renderTargets:this.context.getRenderTargetNames(),uniforms:this.context.getUniformNames(),events:this.eventBus.eventNames()}}logInfo(){let e=this.getInfo();console.group(`[Pipeline] Info`),console.log(`Stages:`,e.stages),console.log(`Context Textures:`,e.textures),console.log(`Context Render Targets:`,e.renderTargets),console.log(`Context Uniforms:`,e.uniforms),console.log(`Event Types:`,e.events),console.log(`State:`,e.contextState),console.groupEnd()}},dc=class{constructor(){this.timeElapsed=0,this.lastResetTime=performance.now(),this.renderCompleteDispatched=!1}updateTime(){this.timeElapsed=(performance.now()-this.lastResetTime)/1e3}isTimeLimitReached(e,t){return e===`time`&&t>0&&this.timeElapsed>=t}isLimitReached(e,t,n){return e?this.isTimeLimitReached(t,n)?!0:e.frameCount>=e.completionThreshold:!1}markComplete(){return this.renderCompleteDispatched?!1:(this.renderCompleteDispatched=!0,!0)}reset(){this.timeElapsed=0,this.lastResetTime=performance.now(),this.renderCompleteDispatched=!1}resumeFromPause(){this.renderCompleteDispatched=!1,this.lastResetTime=performance.now()-this.timeElapsed*1e3}},fc=class extends r.EventDispatcher{constructor({scene:e,camera:t,canvas:n,assetLoader:i,pathTracer:a,floorPlane:o}){super(),this.scene=e,this.camera=t,this.canvas=n,this.assetLoader=i,this.pathTracer=a,this.floorPlane=o,this.raycaster=new r.Raycaster,this.focusMode=!1,this.focusPointIndicator=null,this.afPointPlacementMode=!1,this.handleAFPointClick=this.handleAFPointClick.bind(this),this.selectedObject=null,this.selectMode=!1,this.clickTimeout=null,this.mouseDownPosition=null,this.dragThreshold=5,this.handleFocusClick=this.handleFocusClick.bind(this),this.handleSelectClick=this.handleSelectClick.bind(this),this.handleSelectDoubleClick=this.handleSelectDoubleClick.bind(this),this.handleMouseDown=this.handleMouseDown.bind(this),this.handleMouseUp=this.handleMouseUp.bind(this),this.handleContextMenu=this.handleContextMenu.bind(this),this.handleContextPointerDown=this.handleContextPointerDown.bind(this),this.handleContextPointerUp=this.handleContextPointerUp.bind(this),this.contextPointerDownPosition=null,this.canvas.addEventListener(`pointerdown`,this.handleContextPointerDown),this.canvas.addEventListener(`pointerup`,this.handleContextPointerUp),this.canvas.addEventListener(`contextmenu`,this.handleContextMenu),this._overlayManager=null,this._transformManager=null,this._appDispatch=null,this._orbitControls=null}setDependencies({overlayManager:e,transformManager:t,appDispatch:n,orbitControls:r}){this._overlayManager=e||null,this._transformManager=t||null,this._appDispatch=n||null,this._orbitControls=r||null}select(e){let t=this._overlayManager?.getHelper(`outline`);t&&t.setSelectedObjects(e?[e]:[]),this.selectedObject=e||null,e?this._transformManager?.attach(e):this._transformManager?.detach(),this._appDispatch?.({type:F.OBJECT_SELECTED,object:e||null})}deselect(){this.select(null)}disableMode(){this.disableSelectMode(),this._transformManager?.detach()}on(e,t){return this.addEventListener(e,t),()=>this.removeEventListener(e,t)}toggleFocusMode(){return this.focusMode=!this.focusMode,this.canvas.style.cursor=this.focusMode?`crosshair`:`auto`,this.focusMode?this.canvas.addEventListener(`click`,this.handleFocusClick):this.canvas.removeEventListener(`click`,this.handleFocusClick),this._orbitControls&&(this._orbitControls.enabled=!this.focusMode),this.dispatchEvent({type:`focusModeChanged`,enabled:this.focusMode}),this.focusMode}handleFocusClick(e){let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0);if(n.length>0){let e=n[0],t=e.distance;this.showFocusPoint(e.point),this.toggleFocusMode(),this.dispatchEvent({type:`focusChanged`,distance:t/this.assetLoader.getSceneScale(),worldDistance:t})}}showFocusPoint(e){this.focusPointIndicator&&this.scene.remove(this.focusPointIndicator),this.focusPointIndicator=new r.Mesh(new r.SphereGeometry(this.assetLoader.getSceneScale()*.02,16,16),new r.MeshBasicMaterial({color:65280,transparent:!0,opacity:.8,depthTest:!1})),this.focusPointIndicator.position.copy(e),this.scene.add(this.focusPointIndicator),setTimeout(()=>{this.focusPointIndicator&&=(this.scene.remove(this.focusPointIndicator),null)},2e3)}enterAFPointPlacementMode(){this.afPointPlacementMode=!0,this.canvas.style.cursor=`crosshair`,this.canvas.addEventListener(`click`,this.handleAFPointClick)}exitAFPointPlacementMode(){this.afPointPlacementMode=!1,this.canvas.style.cursor=`auto`,this.canvas.removeEventListener(`click`,this.handleAFPointClick)}handleAFPointClick(e){let t=this.canvas.getBoundingClientRect(),n=(e.clientX-t.left)/t.width,r=(e.clientY-t.top)/t.height;this.exitAFPointPlacementMode(),this.dispatchEvent({type:`afPointPlaced`,point:{x:n,y:r}})}toggleSelectMode(){return this.selectMode=!this.selectMode,this.canvas.style.cursor=this.selectMode?`pointer`:`auto`,this.selectMode?(this.canvas.addEventListener(`mousedown`,this.handleMouseDown),this.canvas.addEventListener(`mouseup`,this.handleMouseUp),this.canvas.addEventListener(`click`,this.handleSelectClick),this.canvas.addEventListener(`dblclick`,this.handleSelectDoubleClick)):(this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null),this.dispatchEvent({type:`selectModeChanged`,enabled:this.selectMode}),this.selectMode}disableSelectMode(){this.selectMode&&(this.selectMode=!1,this.canvas.style.cursor=`auto`,this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null,this.dispatchEvent({type:`selectModeChanged`,enabled:!1}))}handleMouseDown(e){this.mouseDownPosition={x:e.clientX,y:e.clientY,button:e.button}}wasMouseDragged(e){if(!this.mouseDownPosition)return!1;let t=Math.abs(e.clientX-this.mouseDownPosition.x),n=Math.abs(e.clientY-this.mouseDownPosition.y);return Math.sqrt(t*t+n*n)>this.dragThreshold}handleSelectClick(e){if(this.wasMouseDragged(e)){this.mouseDownPosition=null;return}if(this.mouseDownPosition=null,this.clickTimeout){clearTimeout(this.clickTimeout),this.clickTimeout=null;return}this.clickTimeout=setTimeout(()=>{this.clickTimeout=null;let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0),r=this.filterValidIntersects(n);if(r.length>0){let e=r[0].object,t=this.selectedObject;t&&t.uuid===e.uuid?this.dispatchEvent({type:`objectDeselected`,object:e,uuid:e.uuid}):this.dispatchEvent({type:`objectSelected`,object:e,uuid:e.uuid})}else this.dispatchEvent({type:`objectDeselected`})},250)}handleSelectDoubleClick(e){if(this.wasMouseDragged(e)){this.mouseDownPosition=null;return}this.mouseDownPosition=null,this.clickTimeout&&=(clearTimeout(this.clickTimeout),null);let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0),r=this.filterValidIntersects(n);if(r.length>0){let e=r[0].object;this.dispatchEvent({type:`objectDoubleClicked`,object:e,uuid:e.uuid})}}handleMouseUp(){}handleContextPointerDown(e){e.button===2&&(this.contextPointerDownPosition={x:e.clientX,y:e.clientY})}handleContextPointerUp(e){if(e.button!==2)return;if(this.contextPointerDownPosition){let t=Math.abs(e.clientX-this.contextPointerDownPosition.x),n=Math.abs(e.clientY-this.contextPointerDownPosition.y);if(Math.sqrt(t*t+n*n)>this.dragThreshold){this.contextPointerDownPosition=null;return}}else return;this.contextPointerDownPosition=null;let t=this.selectedObject;t&&this.dispatchEvent({type:`contextMenuRequested`,x:e.clientX,y:e.clientY,selectedObject:t})}handleContextMenu(e){e.preventDefault()}getMouseCoordinates(e){let t=this.canvas.getBoundingClientRect();return{x:(e.clientX-t.left)/t.width*2-1,y:-((e.clientY-t.top)/t.height)*2+1}}filterValidIntersects(e){return e.filter(e=>{let t=e.object;return t!==this.focusPointIndicator&&t!==this.floorPlane&&!t.name.includes(`Helper`)&&t.type===`Mesh`})}updateDependencies({scene:e,camera:t,floorPlane:n}){e&&(this.scene=e),t&&(this.camera=t),n&&(this.floorPlane=n)}wireAppEvents(e){this.addEventListener(`objectSelected`,t=>{this.select(t.object),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_SELECTED,object:t.object,uuid:t.uuid})}),this.addEventListener(`objectDeselected`,t=>{this.select(null),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_DESELECTED,object:t.object,uuid:t.uuid})}),this.addEventListener(`selectModeChanged`,t=>{e.dispatchEvent({type:F.SELECT_MODE_CHANGED,enabled:t.enabled})}),this.addEventListener(`objectDoubleClicked`,t=>{this.select(t.object),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_DOUBLE_CLICKED,object:t.object,uuid:t.uuid})}),this.addEventListener(`focusChanged`,t=>{e.settings.set(`focusDistance`,t.worldDistance),e.dispatchEvent({type:`focusChanged`,distance:t.distance})}),this.addEventListener(`afPointPlaced`,t=>{e.dispatchEvent({type:F.AF_POINT_PLACED,point:t.point})})}dispose(){this.canvas.removeEventListener(`click`,this.handleAFPointClick),this.canvas.removeEventListener(`click`,this.handleFocusClick),this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.canvas.removeEventListener(`contextmenu`,this.handleContextMenu),this.canvas.removeEventListener(`pointerdown`,this.handleContextPointerDown),this.canvas.removeEventListener(`pointerup`,this.handleContextPointerUp),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null,this.contextPointerDownPosition=null,this.focusPointIndicator&&=(this.scene.remove(this.focusPointIndicator),null),this.canvas.style.cursor=`auto`,this.scene=null,this.camera=null,this.canvas=null,this.assetLoader=null,this.pathTracer=null,this.floorPlane=null,this.raycaster=null}},pc={STRING:`string`,NUMBER:`number`,WORD:`word`,LBRACKET:`[`,RBRACKET:`]`},mc=e=>e===` `||e===` `||e===`
732
- `||e===`\r`||e===`\f`,hc=e=>e>=`0`&&e<=`9`,gc=(e,t,n)=>!!(hc(e)||e===`.`&&hc(t)||(e===`-`||e===`+`)&&(hc(t)||t===`.`&&hc(n)));function _c(e){let t=[],n=e.length,r=0;for(;r<n;){let i=e[r];if(mc(i)){r++;continue}if(i===`#`){for(;r<n&&e[r]!==`
733
- `;)r++;continue}if(i===`[`){t.push({type:pc.LBRACKET}),r++;continue}if(i===`]`){t.push({type:pc.RBRACKET}),r++;continue}if(i===`"`){r++;let i=r;for(;r<n&&e[r]!==`"`;)r++;if(r>=n)throw Error(`PBRT tokenizer: unterminated string literal`);t.push({type:pc.STRING,value:e.slice(i,r)}),r++;continue}if(gc(i,e[r+1],e[r+2])){let i=r;for(r++;r<n;){let t=e[r];if(t>=`0`&&t<=`9`||t===`.`||t===`e`||t===`E`||t===`-`||t===`+`)r++;else break}let a=e.slice(i,r),o=Number(a);if(Number.isNaN(o))throw Error(`PBRT tokenizer: invalid number "${a}"`);t.push({type:pc.NUMBER,value:o});continue}{let i=r;for(;r<n&&!mc(e[r])&&e[r]!==`"`&&e[r]!==`[`&&e[r]!==`]`&&e[r]!==`#`;)r++;t.push({type:pc.WORD,value:e.slice(i,r)})}}return t}function vc(){return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}function yc(e,t){let n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],d=e[9],f=e[10],p=e[11],m=e[12],h=e[13],g=e[14],_=e[15],v=t[0],y=t[1],b=t[2],x=t[3],S=t[4],C=t[5],w=t[6],T=t[7],E=t[8],D=t[9],O=t[10],k=t[11],A=t[12],j=t[13],M=t[14],N=t[15];return[n*v+o*y+u*b+m*x,r*v+s*y+d*b+h*x,i*v+c*y+f*b+g*x,a*v+l*y+p*b+_*x,n*S+o*C+u*w+m*T,r*S+s*C+d*w+h*T,i*S+c*C+f*w+g*T,a*S+l*C+p*w+_*T,n*E+o*D+u*O+m*k,r*E+s*D+d*O+h*k,i*E+c*D+f*O+g*k,a*E+l*D+p*O+_*k,n*A+o*j+u*M+m*N,r*A+s*j+d*M+h*N,i*A+c*j+f*M+g*N,a*A+l*j+p*M+_*N]}function bc(e,t,n){return[1,0,0,0,0,1,0,0,0,0,1,0,e,t,n,1]}function xc(e,t,n){return[e,0,0,0,0,t,0,0,0,0,n,0,0,0,0,1]}function Sc(e,t,n,r){let i=Math.hypot(t,n,r)||1;t/=i,n/=i,r/=i;let a=e*Math.PI/180,o=Math.cos(a),s=Math.sin(a),c=1-o,l=c*t*t+o,u=c*t*n-s*r,d=c*t*r+s*n,f=c*t*n+s*r,p=c*n*n+o,m=c*n*r-s*t;return[l,f,c*t*r-s*n,0,u,p,c*n*r+s*t,0,d,m,c*r*r+o,0,0,0,0,1]}function Cc(e,t){return[e[0]-t[0],e[1]-t[1],e[2]-t[2]]}function wc(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function Tc(e){let t=Math.hypot(e[0],e[1],e[2])||1;return[e[0]/t,e[1]/t,e[2]/t]}function Ec(e,t,n){let r=Tc(Cc(t,e)),i=Tc(wc(Tc(n),r)),a=wc(r,i);return[i[0],i[1],i[2],0,a[0],a[1],a[2],0,r[0],r[1],r[2],0,e[0],e[1],e[2],1]}function Dc(e){let t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],c=e[7],l=e[8],u=e[9],d=e[10],f=e[11],p=e[12],m=e[13],h=e[14],g=e[15],_=u*h*c-m*d*c+m*s*f-o*h*f-u*s*g+o*d*g,v=p*d*c-l*h*c-p*s*f+a*h*f+l*s*g-a*d*g,y=l*m*c-p*u*c+p*o*f-a*m*f-l*o*g+a*u*g,b=p*u*s-l*m*s-p*o*d+a*m*d+l*o*h-a*u*h,x=t*_+n*v+r*y+i*b;if(x===0)return vc();let S=1/x;return[_*S,(m*d*i-u*h*i-m*r*f+n*h*f+u*r*g-n*d*g)*S,(o*h*i-m*s*i+m*r*c-n*h*c-o*r*g+n*s*g)*S,(u*s*i-o*d*i-u*r*c+n*d*c+o*r*f-n*s*f)*S,v*S,(l*h*i-p*d*i+p*r*f-t*h*f-l*r*g+t*d*g)*S,(p*s*i-a*h*i-p*r*c+t*h*c+a*r*g-t*s*g)*S,(a*d*i-l*s*i+l*r*c-t*d*c-a*r*f+t*s*f)*S,y*S,(p*u*i-l*m*i-p*n*f+t*m*f+l*n*g-t*u*g)*S,(a*m*i-p*o*i+p*n*c-t*m*c-a*n*g+t*o*g)*S,(l*o*i-a*u*i-l*n*c+t*u*c+a*n*f-t*o*f)*S,b*S,(l*m*r-p*u*r+p*n*d-t*m*d-l*n*h+t*u*h)*S,(p*o*r-a*m*r-p*n*s+t*m*s+a*n*h-t*o*h)*S,(a*u*r-l*o*r+l*n*s-t*u*s-a*n*d+t*o*d)*S]}var Oc=class{constructor(e={}){this.resolveInclude=e.resolveInclude||(()=>{throw Error(`PBRTParser: Include used but no resolveInclude provided`)}),this.ir={film:null,camera:null,namedMaterials:new Map,namedTextures:new Map,shapes:[],lights:[],instances:[],objects:new Map,warnings:[]},this.ctm=vc(),this.state={material:null,areaLight:null,reverseOrientation:!1},this.attributeStack=[],this.transformStack=[],this.coordSystems=new Map,this.currentObject=null,this.objectBeginCTM=null,this.dirStack=[``],this.tokens=[],this.pos=0,this._warnedUnknown=new Set}parse(e,t=``){return this.dirStack=[t],this._run(_c(e)),this.ir}_peek(){return this.tokens[this.pos]}_next(){return this.tokens[this.pos++]}_expectNumber(e){let t=this._next();if(!t||t.type!==pc.NUMBER)throw Error(`PBRT parser: expected number for ${e}, got ${t?t.value:`EOF`}`);return t.value}_expectString(e){let t=this._next();if(!t||t.type!==pc.STRING)throw Error(`PBRT parser: expected string for ${e}, got ${t?t.value:`EOF`}`);return t.value}_readNumbers(e){let t=[];for(let n=0;n<e;n++)t.push(this._expectNumber(`matrix/transform`));return t}_readBracketedOrBareNumbers(e){if(this._peek()&&this._peek().type===pc.LBRACKET){this._next();let e=[];for(;this._peek()&&this._peek().type!==pc.RBRACKET;)e.push(this._expectNumber(`transform element`));return this._next(),e}return this._readNumbers(e)}_parseParams(){let e={};for(;this._peek()&&this._peek().type===pc.STRING;){let t=this._next().value.trim().split(/\s+/),n=t[0],r=t[1]===void 0?t[0]:t[1];e[r]={type:n,value:this._parseParamValue()}}return e}_parseParamValue(){let e=[];if(this._peek()&&this._peek().type===pc.LBRACKET){for(this._next();this._peek()&&this._peek().type!==pc.RBRACKET;)e.push(this._coerceValueToken(this._next()));this._next()}else e.push(this._coerceValueToken(this._next()));return e}_coerceValueToken(e){if(!e)throw Error(`PBRT parser: unexpected EOF in parameter value`);if(e.type===pc.NUMBER||e.type===pc.STRING)return e.value;if(e.type===pc.WORD)return e.value===`true`?!0:e.value===`false`?!1:e.value;throw Error(`PBRT parser: unexpected token in parameter value: ${e.type}`)}_run(e){let t=this.tokens,n=this.pos;for(this.tokens=e,this.pos=0;this.pos<this.tokens.length;){let e=this._next();if(e.type!==pc.WORD)throw Error(`PBRT parser: expected directive, got ${e.type} ${e.value??``}`);this._directive(e.value)}this.tokens=t,this.pos=n}_directive(e){switch(e){case`Identity`:this.ctm=vc();break;case`Translate`:{let[e,t,n]=this._readNumbers(3);this.ctm=yc(this.ctm,bc(e,t,n));break}case`Scale`:{let[e,t,n]=this._readNumbers(3);this.ctm=yc(this.ctm,xc(e,t,n));break}case`Rotate`:{let[e,t,n,r]=this._readNumbers(4);this.ctm=yc(this.ctm,Sc(e,t,n,r));break}case`LookAt`:{let e=this._readNumbers(9),t=Ec([e[0],e[1],e[2]],[e[3],e[4],e[5]],[e[6],e[7],e[8]]);this.ctm=yc(this.ctm,Dc(t));break}case`Transform`:this.ctm=this._readBracketedOrBareNumbers(16);break;case`ConcatTransform`:{let e=this._readBracketedOrBareNumbers(16);this.ctm=yc(this.ctm,e);break}case`CoordinateSystem`:this.coordSystems.set(this._expectString(`CoordinateSystem`),this.ctm.slice());break;case`CoordSysTransform`:{let e=this.coordSystems.get(this._expectString(`CoordSysTransform`));e&&(this.ctm=e.slice());break}case`Camera`:{let e=this._expectString(`Camera type`),t=this._parseParams();this.ir.camera={type:e,params:t,cameraToWorld:Dc(this.ctm)};break}case`Film`:{this._expectString(`Film type`);let e=this._parseParams();this.ir.film={xresolution:this._num(e.xresolution,1280),yresolution:this._num(e.yresolution,720),filename:this._str(e.filename,null)};break}case`Integrator`:case`Sampler`:case`PixelFilter`:case`Filter`:case`Accelerator`:case`ColorSpace`:case`Option`:this._skipTypeAndParams();break;case`WorldBegin`:this.ctm=vc(),this.state={material:null,areaLight:null,reverseOrientation:!1};break;case`WorldEnd`:break;case`AttributeBegin`:this.attributeStack.push({ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation});break;case`AttributeEnd`:{let e=this.attributeStack.pop();e&&(this.ctm=e.ctm,this.state={material:e.material,areaLight:e.areaLight,reverseOrientation:e.reverseOrientation});break}case`TransformBegin`:this.transformStack.push(this.ctm.slice());break;case`TransformEnd`:{let e=this.transformStack.pop();e&&(this.ctm=e);break}case`ReverseOrientation`:this.state.reverseOrientation=!this.state.reverseOrientation;break;case`Attribute`:this._expectString(`Attribute target`),this._parseParams();break;case`ActiveTransform`:this._next();break;case`TransformTimes`:this._readNumbers(2);break;case`MediumInterface`:this._peek()&&this._peek().type===pc.STRING&&this._next(),this._peek()&&this._peek().type===pc.STRING&&this._next();break;case`MakeNamedMedium`:this._skipNamedAndParams();break;case`Material`:{let e=this._expectString(`Material type`),t=this._parseParams();this.state.material={type:e,params:t};break}case`MakeNamedMaterial`:{let e=this._expectString(`MakeNamedMaterial name`),t=this._parseParams(),n=this._str(t.type,`diffuse`);this.ir.namedMaterials.set(e,{type:n,params:t});break}case`NamedMaterial`:{let e=this._expectString(`NamedMaterial name`),t=this.ir.namedMaterials.get(e);this.state.material=t||{type:`diffuse`,params:{},_missingRef:e},t||this._warn(`NamedMaterial "${e}" referenced before definition`);break}case`Texture`:{let e=this._expectString(`Texture name`),t=this._expectString(`Texture data type`),n=this._expectString(`Texture class`),r=this._parseParams();this.ir.namedTextures.set(e,{dataType:t,class:n,params:r});break}case`AreaLightSource`:{let e=this._expectString(`AreaLightSource type`),t=this._parseParams();this.state.areaLight={type:e,params:t};break}case`LightSource`:{let e=this._expectString(`LightSource type`),t=this._parseParams();this.ir.lights.push({type:e,params:t,ctm:this.ctm.slice()});break}case`Shape`:{let e={type:this._expectString(`Shape type`),params:this._parseParams(),ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation};this._emitShape(e);break}case`ObjectBegin`:{let e=this._expectString(`ObjectBegin name`);this.attributeStack.push({ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation}),this.currentObject=e,this.objectBeginCTM=this.ctm.slice(),this.ir.objects.has(e)||this.ir.objects.set(e,[]);break}case`ObjectEnd`:{this.currentObject=null,this.objectBeginCTM=null;let e=this.attributeStack.pop();e&&(this.ctm=e.ctm,this.state={material:e.material,areaLight:e.areaLight,reverseOrientation:e.reverseOrientation});break}case`ObjectInstance`:{let e=this._expectString(`ObjectInstance name`);this.ir.instances.push({name:e,ctm:this.ctm.slice()});break}case`Include`:case`Import`:{let t=this._expectString(e);this._include(t);break}default:this._warnUnknown(e),this._parseParams();break}}_emitShape(e){this.currentObject===null?this.ir.shapes.push(e):(e.relativeCTM=yc(Dc(this.objectBeginCTM),e.ctm),this.ir.objects.get(this.currentObject).push(e))}_include(e){let t=this.resolveInclude(e,this.dirStack[this.dirStack.length-1]);if(t==null){this._warn(`Include target not found: ${e}`);return}let n=e.includes(`/`)?e.slice(0,e.lastIndexOf(`/`)):``;this.dirStack.push(n),this._run(_c(t)),this.dirStack.pop()}_skipTypeAndParams(){this._peek()&&this._peek().type===pc.STRING&&this._next(),this._parseParams()}_skipNamedAndParams(){this._peek()&&this._peek().type===pc.STRING&&this._next(),this._parseParams()}_num(e,t){return e&&e.value.length?e.value[0]:t}_str(e,t){return e&&e.value.length?e.value[0]:t}_warn(e){this.ir.warnings.push(e)}_warnUnknown(e){this._warnedUnknown.has(e)||(this._warnedUnknown.add(e),this._warn(`Unsupported directive ignored: ${e}`))}},kc={au:[1,.78,.34],gold:[1,.78,.34],cu:[.95,.64,.54],copper:[.95,.64,.54],ag:[.97,.96,.91],silver:[.97,.96,.91],al:[.91,.92,.92],aluminium:[.91,.92,.92],aluminum:[.91,.92,.92],mgo:[.9,.9,.9],tio2:[.9,.9,.9]},Ac=[.92,.92,.92];function jc(e){let t=Math.max(1e3,Math.min(4e4,e))/100,n,r,i;t<=66?(n=255,r=99.47*Math.log(t)-161.12):(n=329.7*(t-60)**-.1332,r=288.12*(t-60)**-.0755),i=t>=66?255:t<=19?0:138.52*Math.log(t-10)-305.04;let a=e=>Math.max(0,Math.min(255,e))/255;return[a(n)**2.2,a(r)**2.2,a(i)**2.2]}function Mc(e,t,n){let r=e[t];return r&&typeof r.value[0]==`number`?r.value[0]:n}function Nc(e,t,n){let r=e[t];return r&&typeof r.value[0]==`string`?r.value[0]:n}async function Pc(e,t,n,r=null){let i=e[t];if(!i)return{rgb:r,texture:null};if(i.type===`texture`){let e=i.value[0],t=await n.resolveNamedTexture(e);return t&&t.texture?{rgb:t.constant??null,texture:t.texture}:t&&t.constant?{rgb:t.constant,texture:null}:(n.warn(`texture "${e}" could not be resolved`),{rgb:r,texture:null})}if(i.type===`rgb`||i.type===`color`)return{rgb:[i.value[0],i.value[1],i.value[2]],texture:null};if(i.type===`float`){let e=i.value[0];return{rgb:[e,e,e],texture:null}}if(i.type===`blackbody`)return{rgb:jc(i.value[0]),texture:null};if(i.type===`spectrum`){if(typeof i.value[0]==`string`){let e=Fc(i.value[0]);return e&&kc[e]?{rgb:kc[e].slice(),texture:null}:(n.warn(`named spectrum "${i.value[0]}" approximated to gray`),{rgb:[.5,.5,.5],texture:null})}let e=0,t=0;for(let n=1;n<i.value.length;n+=2)e+=i.value[n],t++;let r=t?e/t:.5;return{rgb:[r,r,r],texture:null}}return{rgb:r,texture:null}}function Fc(e){let t=e.toLowerCase().match(/metal-([a-z]+)/);if(t)return t[1];for(let t of Object.keys(kc))if(e.toLowerCase().includes(t))return t;return null}function Ic(e,t){if(e.roughness&&typeof e.roughness.value[0]==`number`)return e.roughness.value[0];let n=Mc(e,`uroughness`,null),r=Mc(e,`vroughness`,null);return n!==null&&r!==null?(n+r)/2:n===null?t:n}async function Lc(e,t){let n=e?.type||`diffuse`,i=e?.params||{},a=new r.MeshPhysicalMaterial({side:r.DoubleSide,roughness:1,metalness:0}),o=e=>{e&&a.color.setRGB(e[0],e[1],e[2])},s=e=>{o(e.rgb),e.texture&&(a.map=e.texture,e.rgb||a.color.setRGB(1,1,1))};switch(n){case`diffuse`:s(await Pc(i,`reflectance`,t,[.5,.5,.5])),a.roughness=1,a.metalness=0;break;case`conductor`:case`metal`:{let e=await Pc(i,`reflectance`,t,null),n=i.eta,r=i.k,c=n&&n.type===`spectrum`&&typeof n.value[0]==`string`;if(e.rgb||e.texture)s(e);else if(n&&r&&!c){let e=(await Pc(i,`eta`,t,[.2,.92,1.1])).rgb,n=(await Pc(i,`k`,t,[3.9,2.45,2.14])).rgb,r=(e,t)=>((e-1)**2+t**2)/((e+1)**2+t**2);o([r(e[0],n[0]),r(e[1],n[1]),r(e[2],n[2])])}else o(n?(await Pc(i,`eta`,t,Ac)).rgb||Ac:kc.cu);a.metalness=1,a.roughness=Ic(i,.1);break}case`dielectric`:case`thindielectric`:a.transmission=1,a.metalness=0,a.color.setRGB(1,1,1),a.ior=Mc(i,`eta`,1.5),a.roughness=Ic(i,0),a.thickness=n===`thindielectric`?0:Mc(i,`thickness`,0);break;case`coateddiffuse`:s(await Pc(i,`reflectance`,t,[.5,.5,.5])),a.roughness=.6,a.metalness=0,a.clearcoat=1,a.clearcoatRoughness=Ic(i,0);break;case`diffusetransmission`:{let e=await Pc(i,`transmittance`,t,[.25,.25,.25]);s(await Pc(i,`reflectance`,t,[.25,.25,.25])),a.transmission=e.rgb?(e.rgb[0]+e.rgb[1]+e.rgb[2])/3:.5,a.roughness=1,a.ior=1;break}case`interface`:case`none`:case``:a.transmission=1,a.ior=1,a.roughness=0,a.color.setRGB(1,1,1);break;case`mix`:{let e=i.materials?.value||[],n=Math.max(0,Math.min(1,Mc(i,`amount`,.5))),o=e[0]?t.namedMaterials?.get(e[0]):null,s=e[1]?t.namedMaterials?.get(e[1]):null;if(o&&s){let[e,r]=await Promise.all([Lc(o,t),Lc(s,t)]),i=(e,t)=>e*(1-n)+t*n;a.color.lerpColors(e.color,r.color,n),a.roughness=i(e.roughness,r.roughness),a.metalness=i(e.metalness,r.metalness),a.ior=i(e.ior??1.5,r.ior??1.5),a.transmission=i(e.transmission??0,r.transmission??0),a.thickness=i(e.thickness??0,r.thickness??0),a.clearcoat=i(e.clearcoat??0,r.clearcoat??0),a.clearcoatRoughness=i(e.clearcoatRoughness??0,r.clearcoatRoughness??0),a.emissive.lerpColors(e.emissive,r.emissive,n),a.emissiveIntensity=i(e.emissiveIntensity??0,r.emissiveIntensity??0),a.map=(n<.5?e.map:r.map)||null;break}t.warn(`material "mix" — could not resolve inner materials [${e.join(`, `)}], falling back to diffuse`),a.color.set(new r.Color(.6,.6,.6));break}case`subsurface`:case`hair`:case`measured`:t.warn(`material "${n}" not supported — using diffuse approximation`),o((await Pc(i,`reflectance`,t,[.5,.5,.5])).rgb),a.roughness=1;break;default:t.warn(`unknown material "${n}" — using neutral diffuse`),a.color.set(new r.Color(.6,.6,.6));break}return a.roughness=Math.max(0,Math.min(1,a.roughness)),a}var Rc=[1,0,0,0,0,1,0,0,0,0,-1,0,0,0,0,1],zc=class{constructor(e={}){this.resolvePLY=e.resolvePLY||(async()=>null),this.resolveImage=e.resolveImage||(async()=>null),this.resolveEnvironment=e.resolveEnvironment||e.resolveImage||(async()=>null),this.convertHandedness=e.convertHandedness===!0,this.warnings=[],this.report=[],this._materialCache=new Map,this._textureCache=new Map}warn(e){this.warnings.push(e)}async build(e){this.ir=e;let t=new r.Group;t.name=`PBRTScene`;for(let n=0;n<e.shapes.length;n++){let r=await this._buildShapeMesh(e.shapes[n],e.shapes[n].ctm,`shape_${n}`);r&&t.add(r)}await this._buildInstances(e,t);let n=null;e.camera&&(n=this._buildCamera(e.camera,e.film),n&&t.add(n));let i=await this._buildEnvironment(e.lights);return this._reportUnsupportedLights(e.lights),{group:t,camera:n,environment:i,report:this.report,warnings:this.warnings.concat(e.warnings||[])}}async _buildInstances(e,t){let n=0;for(let r of e.instances){let i=e.objects.get(r.name);if(!i){this.warn(`ObjectInstance "${r.name}" has no template`);continue}for(let e of i){let i=yc(r.ctm,e.relativeCTM||e.ctm),a=await this._buildShapeMesh(e,i,`instance_${n++}`);a&&t.add(a)}}}async _buildShapeMesh(e,t,n){let[i,a]=await Promise.all([this._buildGeometry(e),this._getMaterial(e)]);if(!i)return null;let o=!!i.getAttribute(`uv`),s=a;a.map&&!o&&(this.warn(`${n} (${e.type}, "${e.material?.type||`diffuse`}") has a texture map but no UVs — dropping map, using base color`),s=a.clone(),s.map=null);let c=new r.Mesh(i,s);c.name=n;let l=this.convertHandedness?yc(Rc,t):t;new r.Matrix4().fromArray(l).decompose(c.position,c.quaternion,c.scale),c.updateMatrix(),i.computeBoundingBox();let u=i.boundingBox?i.boundingBox.clone().applyMatrix4(c.matrix).getSize(new r.Vector3):new r.Vector3;return this.report.push({mesh:n,shape:e.type,material:e.material?.type||`diffuse`,color:`#`+s.color.getHexString(),map:s.map?`yes`:`-`,uv:o?`yes`:`NO`,normals:i.getAttribute(`normal`)?`yes`:`NO`,emissive:s.emissiveIntensity>0?`#${s.emissive.getHexString()}×${s.emissiveIntensity}`:`-`,size:`${u.x.toFixed(2)}×${u.y.toFixed(2)}×${u.z.toFixed(2)}`,tris:i.index?i.index.count/3:i.getAttribute(`position`).count/3}),c}async _buildGeometry(e){switch(e.type){case`trianglemesh`:return this._triangleMesh(e.params);case`bilinearmesh`:return this._bilinearMesh(e.params);case`plymesh`:return this._plyMesh(e.params);case`sphere`:return this._sphere(e.params);case`disk`:return this._disk(e.params);default:return this.warn(`shape "${e.type}" not supported — skipped`),null}}_triangleMesh(e){let t=e.P?.value;if(!t||t.length<9)return this.warn(`trianglemesh missing P`),null;let n=new r.BufferGeometry;n.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(t),3));let i=e.N?.value;i&&i.length===t.length&&n.setAttribute(`normal`,new r.Float32BufferAttribute(Float32Array.from(i),3));let a=(e.uv||e.st)?.value;a&&a.length===t.length/3*2&&n.setAttribute(`uv`,new r.Float32BufferAttribute(Float32Array.from(a),2));let o=e.indices?.value;return o&&o.length&&n.setIndex(o),i||n.computeVertexNormals(),n}_bilinearMesh(e){let t=e.P?.value,n=e.indices?.value;if(!t||!n)return this.warn(`bilinearmesh missing P/indices`),null;let i=[];for(let e=0;e+3<n.length;e+=4){let[t,r,a,o]=[n[e],n[e+1],n[e+2],n[e+3]];i.push(t,r,a,t,a,o)}let a=new r.BufferGeometry;return a.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(t),3)),a.setIndex(i),a.computeVertexNormals(),a}async _plyMesh(e){let t=Nc(e,`filename`,null);if(!t)return this.warn(`plymesh missing filename`),null;try{let e=await this.resolvePLY(t);return e?(e.getAttribute(`normal`)||e.computeVertexNormals(),e):(this.warn(`plymesh file not found: ${t}`),null)}catch(e){return this.warn(`failed to load plymesh ${t}: ${e.message}`),null}}_sphere(e){return new r.SphereGeometry(Mc(e,`radius`,1),48,32)}_disk(e){let t=Mc(e,`radius`,1),n=Mc(e,`innerradius`,0),i=Mc(e,`height`,0),a=[],o=[];for(let e=0;e<48;e++){let r=e/48*Math.PI*2,s=(e+1)/48*Math.PI*2,c=a.length/3;a.push(Math.cos(r)*n,Math.sin(r)*n,i),a.push(Math.cos(r)*t,Math.sin(r)*t,i),a.push(Math.cos(s)*t,Math.sin(s)*t,i),a.push(Math.cos(s)*n,Math.sin(s)*n,i),o.push(c,c+1,c+2,c,c+2,c+3)}let s=new r.BufferGeometry;return s.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(a),3)),s.setIndex(o),s.computeVertexNormals(),s}async _getMaterial(e){let t=this._materialCache.get(e.material);if(t||(t=new Map,this._materialCache.set(e.material,t)),t.has(e.areaLight))return t.get(e.areaLight);let n={resolveNamedTexture:e=>this._resolveNamedTexture(e),namedMaterials:this.ir.namedMaterials,warn:e=>this.warn(e)},r=await Lc(e.material,n);return e.areaLight&&await this._applyAreaLight(r,e.areaLight,n),t.set(e.areaLight,r),r}async _applyAreaLight(e,t,n){let r=await Pc(t.params,`L`,n,[1,1,1]),i=Mc(t.params,`scale`,1),a=r.rgb||[1,1,1];e.emissive.setRGB(a[0],a[1],a[2]),e.emissiveIntensity=i}async _resolveNamedTexture(e){if(this._textureCache.has(e))return this._textureCache.get(e);let t=this.ir.namedTextures.get(e),n=null;if(!t)this.warn(`named texture "${e}" not defined`);else if(t.class===`imagemap`){let r=Nc(t.params,`filename`,null);if(r)try{let t=await this.resolveImage(r);t?n={texture:t}:this.warn(`image not found for texture "${e}": ${r}`)}catch(t){this.warn(`failed to load texture "${e}" (${r}): ${t.message}`)}}else if(t.class===`constant`){let e=t.params.value;e&&e.type===`rgb`?n={constant:[e.value[0],e.value[1],e.value[2]]}:e&&(n={constant:[e.value[0],e.value[0],e.value[0]]})}else t.class===`scale`?n=await this._resolveScaleTexture(e,t):this.warn(`texture class "${t.class}" not supported (texture "${e}")`);return this._textureCache.set(e,n),n}async _resolveScaleTexture(e,t){let n=t.params.tex,r=null;if(n?.type===`texture`&&typeof n.value[0]==`string`)r=await this._resolveNamedTexture(n.value[0]);else if(n?.type===`rgb`||n?.type===`color`)r={constant:[n.value[0],n.value[1],n.value[2]]};else if(n?.type===`float`){let e=n.value[0];r={constant:[e,e,e]}}let i=t.params.scale,a=[1,1,1];if(i?.type===`rgb`||i?.type===`color`)a=[i.value[0],i.value[1],i.value[2]];else if(i?.type===`float`){let e=i.value[0];a=[e,e,e]}if(r?.texture){let e=r.constant||[1,1,1];return{texture:r.texture,constant:[e[0]*a[0],e[1]*a[1],e[2]*a[2]]}}let o=r?.constant||[1,1,1];return{constant:[o[0]*a[0],o[1]*a[1],o[2]*a[2]]}}_buildCamera(e,t){let n=new r.Matrix4().fromArray(e.cameraToWorld).elements,i=new r.Vector3(n[12],n[13],n[14]),a=new r.Vector3(n[8],n[9],n[10]),o=new r.Vector3(n[4],n[5],n[6]);this.convertHandedness&&(i.z*=-1,a.z*=-1,o.z*=-1);let s=i.clone().add(a),c=t&&t.yresolution?t.xresolution/t.yresolution:16/9,l=new r.PerspectiveCamera(this._verticalFov(e.params,c),c,.01,1e4);return l.name=`PBRT Camera`,l.up.copy(o.normalize()),l.position.copy(i),l.lookAt(s),l.updateMatrixWorld(!0),l}_verticalFov(e,t){let n=Mc(e,`fov`,90);if(t>=1)return n;let r=n*Math.PI/180;return 2*Math.atan(Math.tan(r/2)/t)*180/Math.PI}async _buildEnvironment(e){let t=e.find(e=>e.type===`infinite`);if(!t)return null;let n=Mc(t.params,`scale`,1),i=Nc(t.params,`filename`,null);if(i)try{let e=await this.resolveEnvironment(i);if(e)return e.mapping=r.EquirectangularReflectionMapping,{texture:e};this.warn(`infinite-light image not found: ${i}`)}catch(e){this.warn(`failed to load infinite-light image ${i}: ${e.message}`)}let a=((await Pc(t.params,`L`,{resolveNamedTexture:async()=>null,warn:e=>this.warn(e)},[1,1,1])).rgb||[1,1,1]).map(e=>e*n),o=new Float32Array(8);for(let e=0;e<2;e++)o[e*4+0]=a[0],o[e*4+1]=a[1],o[e*4+2]=a[2],o[e*4+3]=1;let s=new r.DataTexture(o,2,1,r.RGBAFormat,r.FloatType);return s.mapping=r.EquirectangularReflectionMapping,s.minFilter=r.LinearFilter,s.magFilter=r.LinearFilter,s.needsUpdate=!0,{texture:s}}_reportUnsupportedLights(e){for(let t of e)t.type!==`infinite`&&this.warn(`light "${t.type}" not supported (only infinite lights and emissive area lights are mapped)`)}},Bc=new TextDecoder;function Vc(e){let t=e.replace(/\\/g,`/`).split(`/`),n=[];for(let e of t)e===``||e===`.`||(e===`..`?n.pop():n.push(e));return n.join(`/`)}function Hc(e,t){return!e||t.startsWith(`/`)?Vc(t):Vc(`${e}/${t}`)}var Uc=class{constructor(e){this.byPath=new Map,this.byBase=new Map;for(let t in e){let n=Vc(t).toLowerCase(),r={norm:n,bytes:e[t]};this.byPath.set(n,r);let i=n.split(`/`).pop(),a=this.byBase.get(i);a?a.push(r):this.byBase.set(i,[r])}}find(e){let t=Vc(e).toLowerCase();if(this.byPath.has(t))return this.byPath.get(t).bytes;let n=this.byBase.get(t.split(`/`).pop());return n?(n.find(e=>e.norm.endsWith(`/`+t))||n[0]).bytes:null}};function Wc(e){let t=Object.keys(e).filter(e=>e.toLowerCase().endsWith(`.pbrt`));if(t.length===0)return null;let n=t.filter(e=>/(^|\/)(scene|main)\.pbrt$/i.test(e)),r=n.length?n:t;return r.sort((e,t)=>{let n=e.split(`/`).length,r=t.split(`/`).length;return n===r?e.length-t.length:n-r}),r[0]}async function Gc(e){let{vfs:t,plyParser:n,imageFromBytes:r,envFromBytes:i,convertHandedness:a}=e,o=new Uc(t),s=e.entryPath||Wc(t);if(!s)throw Error(`PBRT loader: no .pbrt file found in archive`);let c=o.find(s);if(!c)throw Error(`PBRT loader: entry "${s}" not readable`);let l=s.includes(`/`)?s.slice(0,s.lastIndexOf(`/`)):``,u=new Oc({resolveInclude:(e,t)=>{let n=o.find(Hc(t,e))||o.find(e);return n?Bc.decode(n):null}}).parse(Bc.decode(c),l),d=e=>e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength);return{...await new zc({convertHandedness:a,resolvePLY:async e=>{let t=o.find(e);return t?n(d(t)):null},resolveImage:async e=>{let t=o.find(e);return t?r(t,e):null},resolveEnvironment:async e=>{let t=o.find(e);return t?(i||r)(t,e):null}}).build(u),entryPath:s}}var Kc={glb:{type:`model`,name:`GLB (GLTF Binary)`},gltf:{type:`model`,name:`GLTF`},fbx:{type:`model`,name:`FBX`},obj:{type:`model`,name:`OBJ`},stl:{type:`model`,name:`STL`},ply:{type:`model`,name:`PLY (Polygon File Format)`},dae:{type:`model`,name:`Collada`},"3mf":{type:`model`,name:`3D Manufacturing Format`},usdz:{type:`model`,name:`Universal Scene Description`},hdr:{type:`environment`,name:`HDR (High Dynamic Range)`},exr:{type:`environment`,name:`EXR (OpenEXR)`},png:{type:`image`,name:`PNG`},jpg:{type:`image`,name:`JPEG`},jpeg:{type:`image`,name:`JPEG`},webp:{type:`image`,name:`WebP`},zip:{type:`archive`,name:`ZIP Archive`}},qc=class e extends r.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.camera=t,this.controls=n,this.targetModel=null,this._externalModel=null,this.floorPlane=null,this.sceneScale=1,this.loaderCache={},this.uploadedFileInfo=null,this.animations=[],this.renderer=null,this._loadingManager=new r.LoadingManager,this._loadCancelled=!1}cancelActiveLoad(){this._loadCancelled=!0,this._loadingManager.abort()}_isCancellation(e){return this._loadCancelled||e?.name===`AbortError`||e?.code===`LOAD_CANCELLED`}_cancellationError(){let e=Error(`Load cancelled`);return e.code=`LOAD_CANCELLED`,e}_downloadProgress(e,t){return n=>{let r=n?.loaded||0,i=n?.lengthComputable&&n.total||0;I({isLoading:!0,status:e,loadedBytes:r,totalBytes:i,canCancel:!!t,progress:i?Math.min(60,2+Math.round(r/i*58)):2})}}_downloadComplete(e=`Processing Data...`,t=62){I({status:e,progress:t,canCancel:!1,loadedBytes:null,totalBytes:null})}static _isNetworkUrl(e){return typeof e==`string`&&/^https?:/i.test(e)}releaseTargetModel(){this.targetModel&&(this.targetModel===this._externalModel?this.targetModel.parent?.remove(this.targetModel):R(this.targetModel),this.targetModel=null,this._externalModel=null,this.animations=[])}setRenderer(e){this.renderer=e}getFileFormat(e){return Kc[e.split(`.`).pop().toLowerCase()]||null}readFileAsArrayBuffer(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=e=>t(e.target.result),r.onerror=e=>n(e),r.readAsArrayBuffer(e)})}readFileAsText(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=e=>t(e.target.result),r.onerror=e=>n(e),r.readAsText(e)})}async loadAssetFromFile(e){let t=e.name,n=this.getFileFormat(t);if(!n)throw Error(`Unsupported file format: ${t}`);I({isLoading:!0,status:`Loading ${n.name}...`,progress:2});try{let r;switch(n.type){case`model`:r=await this.loadModelFromFile(e,t);break;case`environment`:case`image`:r=await this.loadEnvironmentFromFile(e,t);break;case`archive`:r=await this.loadArchiveFromFile(e,t);break;default:throw Error(`Unknown asset type: ${n.type}`)}return r}catch(e){throw this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadModelFromFile(e,t){let n=t.split(`.`).pop().toLowerCase(),r=await this.readFileAsArrayBuffer(e);switch(n){case`glb`:case`gltf`:return await this.loadGLBFromArrayBuffer(r,t);case`fbx`:return await this.loadFBXFromArrayBuffer(r,t);case`obj`:return await this.loadOBJFromFile(e,t);case`stl`:return await this.loadSTLFromArrayBuffer(r,t);case`ply`:return await this.loadPLYFromArrayBuffer(r,t);case`dae`:return await this.loadColladaFromFile(e,t);case`3mf`:return await this.load3MFFromArrayBuffer(r,t);case`usdz`:return await this.loadUSDZFromArrayBuffer(r,t);default:throw Error(`Support for ${n} files is not yet implemented`)}}async loadEnvironmentFromFile(e,t){let n=URL.createObjectURL(e);this.uploadedFileInfo={name:t,type:e.type,size:e.size};try{let e=await this.loadEnvironment(n);return this.dispatchEvent({type:`load`,texture:e,filename:t}),e}finally{URL.revokeObjectURL(n)}}async loadEnvironment(e){this._loadCancelled=!1;try{this.dispatchEvent({type:`beforeEnvironmentLoad`,url:e});let t;if(e.startsWith(`blob:`))t=await this.loadEnvironmentFromBlob(e);else{let n=e.split(/[?#]/)[0].split(`.`).pop().toLowerCase();t=await this.loadEnvironmentByExtension(e,n)}return t.generateMipmaps=!0,this.applyEnvironmentToScene(t),this.dispatchEvent({type:`load`,texture:t}),t}catch(t){throw this._isCancellation(t)?this._cancellationError():(console.error(`Error loading environment:`,t),this.dispatchEvent({type:`error`,message:t.message,filename:e}),t)}}async loadEnvironmentFromBlob(e){let t=await(await fetch(e)).blob(),n=this.determineEnvironmentExtension(t,e),r=URL.createObjectURL(t);try{return await this.loadEnvironmentByExtension(r,n)}finally{URL.revokeObjectURL(r)}}determineEnvironmentExtension(e,t){let n;if(e.type===`image/x-exr`||e.type.includes(`exr`))n=`exr`;else if(e.type===`image/vnd.radiance`||e.type.includes(`hdr`))n=`hdr`;else{let e=t.split(`/`).pop();if(e){let t=e.match(/\.([^.]+)$/);t&&(n=t[1].toLowerCase())}}return!n&&this.uploadedFileInfo&&(n=this.uploadedFileInfo.name.split(`.`).pop().toLowerCase()),n}async loadEnvironmentByExtension(t,n){let i=e._isNetworkUrl(t),a=this._downloadProgress(`Downloading Environment...`,i),o;return n===`hdr`||n===`exr`?o=await(n===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new s.HDRLoader(this._loadingManager).setDataType(r.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new u.EXRLoader(this._loadingManager).setDataType(r.FloatType))).loadAsync(t,a):(this.loaderCache.texture||(this.loaderCache.texture=new r.TextureLoader(this._loadingManager)),o=await this.loaderCache.texture.loadAsync(t,a),o.colorSpace=r.SRGBColorSpace),this._downloadComplete(`Processing Environment...`,62),o.mapping=r.EquirectangularReflectionMapping,o.minFilter=r.LinearFilter,o.magFilter=r.LinearFilter,o}applyEnvironmentToScene(e){this.scene.background=e,this.scene.environment=e}async loadArchiveFromFile(e,t){try{let n=await this.readFileAsArrayBuffer(e),r=(0,p.unzipSync)(new Uint8Array(n));return Wc(r)?await this.loadPBRTFromZip(r,t):await this.processObjMtlPairsInZip(r,t)||await this.findAndLoadModelFromZip(r,t)}catch(e){throw console.error(`Error loading ZIP archive:`,e),e}}async loadPBRTFromZip(e,t){if(I({isLoading:!0,status:`Parsing PBRT scene...`,progress:5}),!this.loaderCache.ply){let{PLYLoader:e}=await import(`three/examples/jsm/loaders/PLYLoader.js`);this.loaderCache.ply=new e}let{group:n,environment:r,report:i,warnings:a,entryPath:o}=await Gc({vfs:e,plyParser:e=>this.loaderCache.ply.parse(e),imageFromBytes:(e,t)=>this._pbrtTextureFromBytes(e,t),envFromBytes:async(e,t)=>{let n=t.split(`.`).pop().toLowerCase(),r=URL.createObjectURL(new Blob([e]));try{return await this.loadEnvironmentByExtension(r,n)}finally{URL.revokeObjectURL(r)}}});return i&&i.length&&typeof console.table==`function`&&(console.groupCollapsed(`PBRT loader: ${i.length} mesh(es) from "${o}"`),console.table(i),console.groupEnd()),a&&a.length&&(console.warn(`PBRT loader: ${a.length} warning(s) parsing "${o}"`),a.forEach(e=>console.warn(` •`,e))),r?.texture&&(r.texture.generateMipmaps=!0,this.applyEnvironmentToScene(r.texture)),n.name=o||t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing PBRT geometry...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:`${o} (from ZIP)`}),n}async _pbrtTextureFromBytes(e,t){let n=t.split(`.`).pop().toLowerCase(),i;if(n===`exr`||n===`hdr`){let t=n===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new s.HDRLoader().setDataType(r.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new u.EXRLoader().setDataType(r.FloatType));i=await this._loadViaObjectURL(t,e)}else if(n===`tga`){if(!this.loaderCache.tga){let{TGALoader:e}=await import(`three/examples/jsm/loaders/TGALoader.js`);this.loaderCache.tga=new e}i=await this._loadViaObjectURL(this.loaderCache.tga,e),i.colorSpace=r.SRGBColorSpace}else i=new r.Texture(await createImageBitmap(new Blob([e]))),i.colorSpace=r.SRGBColorSpace;return i.wrapS=i.wrapT=r.RepeatWrapping,i.needsUpdate=!0,i}async _loadViaObjectURL(e,t){let n=URL.createObjectURL(new Blob([t]));try{return await e.loadAsync(n)}finally{URL.revokeObjectURL(n)}}async processObjMtlPairsInZip(e,t){let n=[],r=[];for(let t in e){let i=t.toLowerCase();i.endsWith(`.obj`)?n.push({path:t,content:e[t]}):i.endsWith(`.mtl`)&&r.push({path:t,content:e[t]})}if(n.length>0&&r.length>0){console.log(`Found ${n.length} OBJ files and ${r.length} MTL files in ZIP`);let i=this.findMatchingObjMtlPairs(n,r);if(i.length>0)return console.log(`Found ${i.length} matching OBJ+MTL pairs`),await this.loadOBJMTLPairFromZip(i[0].obj,i[0].mtl,e,t);if(i.length===0)return console.log(`No matching pairs by name, using first OBJ and MTL files`),await this.loadOBJMTLPairFromZip(n[0],r[0],e,t)}return null}findMatchingObjMtlPairs(e,t){let n=[];for(let r of e){let e=r.path.split(`/`).pop().replace(/\.obj$/i,``).toLowerCase();for(let i of t){let t=i.path.split(`/`).pop().replace(/\.mtl$/i,``).toLowerCase();if(e===t||e.includes(t)||t.includes(e)){n.push({obj:r,mtl:i});break}}}return n}async findAndLoadModelFromZip(e){for(let t of[`scene.gltf`,`scene.glb`,`model.gltf`,`model.glb`,`main.gltf`,`main.glb`,`asset.gltf`,`asset.glb`])if(e[t]){console.log(`Found main model file: ${t}`);let n=t.split(`.`).pop().toLowerCase();return await this.loadModelFromZipEntry(e[t],t,n,e)}for(let t in e){let n=t.split(`.`).pop().toLowerCase();if(Kc[n]&&Kc[n].type===`model`)return console.log(`Loading model file from ZIP: ${t}`),await this.loadModelFromZipEntry(e[t],t,n,e)}throw Error(`No supported model files found in the ZIP archive`)}async loadModelFromZipEntry(e,t,n,r){try{I({isLoading:!0,status:`Processing ${n.toUpperCase()} from ZIP...`,progress:5});let i=new Blob([e.buffer],{type:`application/octet-stream`}),a=URL.createObjectURL(i),o;switch(n){case`glb`:case`gltf`:o=await this.handleGltfFromZip(n,e,t,r);break;case`fbx`:o=await this.loadFBXFromArrayBuffer(e.buffer,t);break;case`obj`:o=await this.handleObjFromZip(e,t,r);break;case`stl`:o=await this.loadSTLFromArrayBuffer(e.buffer,t);break;case`ply`:o=await this.loadPLYFromArrayBuffer(e.buffer,t);break;case`dae`:{let n=(0,p.strFromU8)(e),r=new File([new Blob([n])],t);o=await this.loadColladaFromFile(r,t)}break;case`3mf`:o=await this.load3MFFromArrayBuffer(e.buffer,t);break;case`usdz`:o=await this.loadUSDZFromArrayBuffer(e.buffer,t);break;default:throw Error(`Support for ${n} files is not yet implemented`)}return URL.revokeObjectURL(a),this.dispatchEvent({type:`load`,model:this.targetModel,filename:`${t} (from ZIP)`}),o}catch(e){throw console.error(`Error loading ${n} from ZIP:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async handleGltfFromZip(e,t,n,i){if(e===`gltf`){let e=(0,p.strFromU8)(t),a=new r.LoadingManager,o=n.split(`/`).slice(0,-1).join(`/`);a.setURLModifier(e=>this.resolveZipResource(e,o,i));let s=await this.createGLTFLoader();s.manager=a;try{return await new Promise((t,n)=>{s.parse(e,``,e=>{this.releaseTargetModel(),this.targetModel=e.scene,this.onModelLoad(this.targetModel).then(()=>t(e))},e=>n(e))})}finally{this._disposeGLTFLoader(s)}}else return await this.loadGLBFromArrayBuffer(t.buffer,n)}async handleObjFromZip(e,t,n){let r=(0,p.strFromU8)(e),i=r.match(/mtllib\s+([^\s]+)/),a=null;i&&i[1]&&(a=await this.loadMtlFromZip(i[1],t,n));let{OBJLoader:o}=await import(`three/examples/jsm/loaders/OBJLoader.js`),s=new o;a&&s.setMaterials(a);let c=s.parse(r);return c.name=t,this.releaseTargetModel(),this.targetModel=c,await this.onModelLoad(this.targetModel),c}async loadMtlFromZip(e,t,n){let i=t.split(`/`).slice(0,-1).join(`/`),a=[e,`${i}/${e}`,e.split(`/`).pop()];for(let e of a)if(n[e]){let{MTLLoader:t}=await import(`three/examples/jsm/loaders/MTLLoader.js`),a=(0,p.strFromU8)(n[e]),o=new r.LoadingManager;o.setURLModifier(e=>this.resolveZipResource(e,i,n));let s=new t(o).parse(a,i);return s.preload(),s}return null}resolveZipResource(e,t,n){let r=e.replace(/^\.\/|^\//,``),i=[r,`${t}/${r}`,r.split(`/`).pop()];for(let e of i)if(n[e]){let t=new Blob([n[e].buffer],{type:`application/octet-stream`});return URL.createObjectURL(t)}return console.warn(`Resource not found in ZIP: ${e}`),e}async loadOBJMTLPairFromZip(e,t,n,i){let{MTLLoader:a}=await import(`three/examples/jsm/loaders/MTLLoader.js`),{OBJLoader:o}=await import(`three/examples/jsm/loaders/OBJLoader.js`),s=[],c=new r.LoadingManager,l=e.path.split(`/`).slice(0,-1).join(`/`),u=t.path.split(`/`).slice(0,-1).join(`/`);c.setURLModifier(e=>this.resolveTextureInZip(e,l,u,t,n,s));let d=this.prepareFixedMtlContent(t),f=new a(c).parse(d,u);f.preload();let m=new o(c);m.setMaterials(f);let h=(0,p.strFromU8)(e.content),g=m.parse(h);return this.releaseTargetModel(),this.targetModel=g,await this.onModelLoad(this.targetModel),s.forEach(e=>URL.revokeObjectURL(e)),this.dispatchEvent({type:`load`,model:g,filename:`${e.path} (from ${i})`}),g}prepareFixedMtlContent(e){return(0,p.strFromU8)(e.content).replace(RegExp(`${e.path.split(`/`).pop()}\\s+`,`g`),` `).replace(/([a-zA-Z_]+)([\\/])/g,`$1 $2`)}resolveTextureInZip(e,t,n,r,i,a){let o=e.split(`?`)[0].split(`#`)[0].replace(/^\.\/|^\//,``),s=r.path.split(`/`).pop();o.startsWith(s)&&(o=o.substring(s.length).replace(/^\.\/|^\/|^\./,``));let c=[o,`${t}/${o}`,`${n}/${o}`,`textures/${o}`,`texture/${o}`,`materials/${o}`,o.split(`/`).pop()];for(let e of c)if(i[e]){let t=new Blob([i[e].buffer],{type:`application/octet-stream`}),n=URL.createObjectURL(t);return a.push(n),n}return this.findTextureWithFuzzyMatch(o,i,a)||e}findTextureWithFuzzyMatch(e,t,n){let r=e.split(`/`).pop();for(let e in t)if(e.endsWith(r)){let r=new Blob([t[e].buffer],{type:`application/octet-stream`}),i=URL.createObjectURL(r);return n.push(i),i}if(r&&r.length>5)for(let e in t){let i=e.split(`/`).pop();if(i.includes(r)||r.includes(i)){let r=new Blob([t[e].buffer],{type:`application/octet-stream`}),i=URL.createObjectURL(r);return n.push(i),i}}return null}async createGLTFLoader(){let{dracoDecoderPath:e,ktx2TranscoderPath:t}=na(),n=new c.DRACOLoader;n.setDecoderConfig({type:`js`}),n.setDecoderPath(e);let r=new l.KTX2Loader;r.setTranscoderPath(t),this.renderer&&(r.detectSupport(this.renderer),r.workerConfig={astcSupported:!1,etc1Supported:!1,etc2Supported:!1,dxtSupported:!1,bptcSupported:!1,pvrtcSupported:!1});let i=new o.GLTFLoader(this._loadingManager);return i.setDRACOLoader(n),i.setKTX2Loader(r),i.setMeshoptDecoder(f.MeshoptDecoder),i}_disposeGLTFLoader(e){e&&(e.dracoLoader?.dispose(),e.ktx2Loader?.dispose())}async loadExampleModels(e,t){if(!t||!t[e])throw Error(`No model file at index ${e}`);let n=`${t[e].url}`;return await this.loadModel(n)}async loadModel(t){this._loadCancelled=!1;let n=await this.createGLTFLoader(),r=e._isNetworkUrl(t);try{I({isLoading:!0,status:`Downloading Model...`,progress:2,canCancel:r,loadedBytes:0,totalBytes:0});let e=await n.loadAsync(t,this._downloadProgress(`Downloading Model...`,r));return this._downloadComplete(),this.releaseTargetModel(),this.targetModel=e.scene,this.animations=e.animations||[],await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:e.scene,filename:t.split(`/`).pop()}),e}catch(e){throw this._isCancellation(e)?this._cancellationError():(console.error(`Error loading model:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e)}finally{this._disposeGLTFLoader(n)}}_processAndParent(e){this.processModelObjects(e),this.scene.add(e),e.updateMatrixWorld(!0)}async appendModel(t){this._loadCancelled=!1;let n=await this.createGLTFLoader(),r=e._isNetworkUrl(t);try{I({isLoading:!0,status:`Downloading Model...`,progress:2,canCancel:r,loadedBytes:0,totalBytes:0});let e=await n.loadAsync(t,this._downloadProgress(`Downloading Model...`,r));return this._downloadComplete(),this._processAndParent(e.scene),{root:e.scene,animations:e.animations||[]}}catch(e){throw this._isCancellation(e)?this._cancellationError():e}finally{this._disposeGLTFLoader(n)}}appendObject3D(e,t=`object3d`){return e.name=e.name||t,this._processAndParent(e),{root:e}}removeModelRoot(e,{external:t=!1}={}){e&&(t?e.parent?.remove(e):R(e))}async loadGLBFromArrayBuffer(e,t=`model.glb`){let n=await this.createGLTFLoader();try{I({isLoading:!0,status:`Processing GLB Data...`,progress:5}),await new Promise(e=>setTimeout(e,0));let r=await n.parseAsync(e,``);return this.releaseTargetModel(),this.targetModel=r.scene,this.animations=r.animations||[],I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r.scene,filename:t}),r}catch(e){throw console.error(`Error loading GLB:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}finally{this._disposeGLTFLoader(n)}}async loadFBXFromArrayBuffer(e,t=`model.fbx`){try{if(I({isLoading:!0,status:`Processing FBX Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.fbx){let{FBXLoader:e}=await import(`three/examples/jsm/loaders/FBXLoader.js`);this.loaderCache.fbx=new e}let n=this.loaderCache.fbx.parse(e);return this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading FBX:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadOBJFromFile(e,t=`model.obj`){try{if(I({isLoading:!0,status:`Processing OBJ Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.obj){let{OBJLoader:e}=await import(`three/examples/jsm/loaders/OBJLoader.js`);this.loaderCache.obj=new e}let n=await this.readFileAsText(e),r=this.loaderCache.obj.parse(n);return r.name=t,this.releaseTargetModel(),this.targetModel=r,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r,filename:t}),r}catch(e){throw console.error(`Error loading OBJ:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadSTLFromArrayBuffer(e,t=`model.stl`){try{if(I({isLoading:!0,status:`Processing STL Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.stl){let{STLLoader:e}=await import(`three/examples/jsm/loaders/STLLoader.js`);this.loaderCache.stl=new e}let n=new r.Mesh(this.loaderCache.stl.parse(e),new r.MeshStandardMaterial);return n.name=t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading STL:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadPLYFromArrayBuffer(e,t=`model.ply`){try{if(I({isLoading:!0,status:`Processing PLY Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.ply){let{PLYLoader:e}=await import(`three/examples/jsm/loaders/PLYLoader.js`);this.loaderCache.ply=new e}let n=this.loaderCache.ply.parse(e),i;if(n.index!==null)i=new r.Mesh(n,new r.MeshStandardMaterial);else{let e=new r.PointsMaterial({size:.01});e.vertexColors=n.hasAttribute(`color`),i=new r.Points(n,e)}return i.name=t,this.releaseTargetModel(),this.targetModel=i,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:i,filename:t}),i}catch(e){throw console.error(`Error loading PLY:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadColladaFromFile(e,t=`model.dae`){try{if(I({isLoading:!0,status:`Processing Collada Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.collada){let{ColladaLoader:e}=await import(`three/examples/jsm/loaders/ColladaLoader.js`);this.loaderCache.collada=new e}let n=await this.readFileAsText(e),r=this.loaderCache.collada.parse(n);return r.scene.name=t,this.releaseTargetModel(),this.targetModel=r.scene,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r.scene,filename:t}),r}catch(e){throw console.error(`Error loading Collada:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async load3MFFromArrayBuffer(e,t=`model.3mf`){try{if(I({isLoading:!0,status:`Processing 3MF Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.threemf){let{ThreeMFLoader:e}=await import(`three/examples/jsm/loaders/3MFLoader.js`);this.loaderCache.threemf=new e}let n=this.loaderCache.threemf.parse(e);return this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading 3MF:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadUSDZFromArrayBuffer(e,t=`model.usdz`){try{if(I({isLoading:!0,status:`Processing USDZ Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.usdz){let{USDZLoader:e}=await import(`three/examples/jsm/loaders/USDZLoader.js`);this.loaderCache.usdz=new e}let n=this.loaderCache.usdz.parse(e);return n.name=t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading USDZ:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadObject3D(e,t=`object3d`){return e.name=e.name||t,this.releaseTargetModel(),this.targetModel=e,this._externalModel=e,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:e,filename:t}),e}async onModelLoad(e){let t=new Wi(`onModelLoad`);t.start(`Camera extraction`);let n=this.extractCamerasFromModel(e);t.end(`Camera extraction`),t.start(`Camera setup`);let i=new r.Box3().setFromObject(e),a=i.getCenter(new r.Vector3),o=i.getSize(new r.Vector3);this.controls.target.copy(a);let s=Math.max(o.x,o.y,o.z),c=this.camera.fov*(Math.PI/180),l=Math.abs(s/Math.sin(c/2)/2),u=Math.PI/6,d=new r.Vector3(Math.cos(u)*l,l/Math.sqrt(2),Math.sin(u)*l);if(this.camera.position.copy(d.add(a)),this.camera.lookAt(a),this.camera.near=s/100,this.camera.far=s*100,this.camera.updateProjectionMatrix(),this.controls.maxDistance=l*10,this.controls.saveState(),this.controls.update(),t.end(`Camera setup`),this.floorPlane){let e=i.min.y;this.floorPlane.position.y=e,this.floorPlane.rotation.x=-Math.PI/2,this.floorPlane.scale.setScalar(s*5)}t.start(`Process model objects`),this.processModelObjects(e),t.end(`Process model objects`),t.start(`Scene add`),this.scene.add(e),t.end(`Scene add`);let f=s;return t.start(`setupPathTracing`),await this.setupPathTracing(e,f),t.end(`setupPathTracing`),t.print(),this.dispatchEvent({type:`modelProcessed`,model:e,cameras:n,sceneData:{center:a,size:o,maxDim:s,sceneScale:f}}),this.dispatchEvent({type:`SceneRebuild`}),{center:a,size:o,maxDim:s,sceneScale:f}}extractCamerasFromModel(e){let t=[];return e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(e.isCamera){let n=e.clone();e.getWorldPosition(n.position),e.getWorldQuaternion(n.quaternion),(!n.name||n.name===``)&&(n.name=`Model Camera ${t.length+1}`),n.isPerspectiveCamera&&(n.aspect=this.camera.aspect,n.updateProjectionMatrix()),t.push(n)}}),t}processModelObjects(e){let t=[];e.traverse(e=>{let n=e.userData;if(e.isRectAreaLight&&!t.includes(e.uuid)&&t.push(e.uuid),e.name.startsWith(`RectAreaLightPlaceholder`)&&n.name&&n.type===`RectAreaLight`){let i=new r.RectAreaLight(new r.Color(...n.color),n.intensity*.1,n.width,n.height);i.userData.normalize=n.normalize??!0,i.userData.spread=Number.isFinite(n.spread)?n.spread:Math.PI,i.userData.shape=n.shape??`rectangle`,i.position.z=-2,i.name=n.name,e.add(i),t.push(i.uuid)}if(e.isMesh&&Array.isArray(e.material)){console.log(`Found multi-material mesh:`,e.name);let t=(0,d.createMeshesFromMultiMaterialMesh)(e);e.parent&&(e.parent.add(t),e.parent.remove(e))}})}async setupPathTracing(e,t){this.sceneScale=t}createFloorPlane(){this.floorPlane=new r.Mesh(new r.CircleGeometry,new r.MeshPhysicalMaterial({transparent:!1,color:3158064,roughness:1,metalness:0,opacity:0,transmission:0})),this.floorPlane.name=`Ground`,this.floorPlane.visible=!1,this.scene.add(this.floorPlane)}setFloorPlane(e){this.floorPlane=e}getSceneScale(){return this.sceneScale}getTargetModel(){return this.targetModel}getSupportedFormats(e=null){if(e){let t={};for(let[n,r]of Object.entries(Kc))r.type===e&&(t[n]=r);return t}return Kc}dispose(){for(let e in this.loaderCache){let t=this.loaderCache[e];t&&typeof t.dispose==`function`&&t.dispose()}this.loaderCache={},this._listeners=void 0,this.releaseTargetModel()}removeAllEventListeners(){this._listeners=void 0}},Jc={maxBounces:{uniform:`maxBounces`,reset:!0},transmissiveBounces:{uniform:`transmissiveBounces`,reset:!0},maxSubsurfaceSteps:{uniform:`maxSubsurfaceSteps`,reset:!0},environmentIntensity:{uniform:`environmentIntensity`,reset:!0},backgroundIntensity:{uniform:`backgroundIntensity`,reset:!0},backgroundBlurriness:{uniform:`backgroundBlurriness`,reset:!0},backgroundBlurSamples:{uniform:`backgroundBlurSamples`,reset:!0},showBackground:{uniform:`showBackground`,reset:!0},enableEnvironment:{uniform:`enableEnvironment`,reset:!0},groundProjectionEnabled:{uniform:`groundProjectionEnabled`,reset:!0},groundProjectionRadius:{uniform:`groundProjectionRadius`,reset:!0},groundProjectionHeight:{uniform:`groundProjectionHeight`,reset:!0},groundProjectionLevel:{uniform:`groundProjectionLevel`,reset:!0},enableGroundCatcher:{uniform:`enableGroundCatcher`,reset:!0},groundCatcherHeight:{uniform:`groundCatcherHeight`,reset:!0},globalIlluminationIntensity:{uniform:`globalIlluminationIntensity`,reset:!0},enableDOF:{uniform:`enableDOF`,reset:!0},focusDistance:{uniform:`focusDistance`,reset:!1},focalLength:{uniform:`focalLength`,reset:!0},aperture:{uniform:`aperture`,reset:!0},apertureScale:{uniform:`apertureScale`,reset:!0},anamorphicRatio:{uniform:`anamorphicRatio`,reset:!0},samplingTechnique:{uniform:`samplingTechnique`,reset:!0},fireflyThreshold:{uniform:`fireflyThreshold`,reset:!0},enableAlphaShadows:{uniform:`enableAlphaShadows`,reset:!0},enableEmissiveTriangleSampling:{uniform:`enableEmissiveTriangleSampling`,reset:!0},emissiveBoost:{uniform:`emissiveBoost`,reset:!0},visMode:{uniform:`visMode`,reset:!0},debugVisScale:{uniform:`debugVisScale`,reset:!0},interactionModeEnabled:{handler:`handleInteractionModeEnabled`,reset:!1},maxSamples:{handler:`handleMaxSamples`,reset:!1},transparentBackground:{handler:`handleTransparentBackground`},backgroundColor:{handler:`handleBackgroundColor`,reset:!0},exposure:{handler:`handleExposure`},saturation:{handler:`handleSaturation`},renderLimitMode:{handler:`handleRenderLimitMode`},renderTimeLimit:{handler:`handleRenderTimeLimit`,reset:!1},renderMode:{handler:`handleRenderMode`},environmentRotation:{handler:`handleEnvironmentRotation`}},Yc={bounces:`maxBounces`,debugMode:`visMode`},Xc=class extends r.EventDispatcher{constructor(e=B){super(),this._values=new Map,this._pathTracer=null,this._resetCallback=null,this._handlers={},this._delegates={},this._initDefaults(e)}bind({stages:e,renderer:t,resetCallback:n,reconcileCompletion:r}){this._pathTracer=e.pathTracer,this._resetCallback=n,this._delegates={},this._handlers=this._buildHandlers(e,t,r)}_buildHandlers(e,t,n){return{handleTransparentBackground:t=>{e.pathTracer?.setUniform(`transparentBackground`,t),e.compositor?.setTransparentBackground(t)},handleBackgroundColor:t=>{let n=t?.isColor?t:new r.Color(t);e.pathTracer?.setUniform(`backgroundColor`,n)},handleExposure:n=>{!e.autoExposure?.enabled&&t&&(t.toneMappingExposure=n)},handleSaturation:t=>{e.compositor?.setSaturation(t)},handleRenderLimitMode:t=>{e.pathTracer?.setRenderLimitMode?.(t)},handleMaxSamples:t=>{e.pathTracer?.setUniform(`maxSamples`,t),e.pathTracer?.updateCompletionThreshold(),n?.()},handleRenderTimeLimit:()=>{n?.()},handleRenderMode:t=>{e.pathTracer?.setUniform(`renderMode`,parseInt(t))},handleEnvironmentRotation:t=>{e.pathTracer?.environment.setEnvironmentRotation(t)},handleInteractionModeEnabled:t=>{e.pathTracer?.setInteractionModeEnabled(t)}}}set(e,t,{reset:n,silent:r}={}){let i=this._values.get(e);if(i===t)return;this._values.set(e,t);let a=Jc[e];a&&(this._applyRoute(a,t,i),(n===void 0?a.reset??!0:n)&&this._resetCallback?.(),r||this.dispatchEvent({type:F.SETTING_CHANGED,key:e,value:t,prev:i}))}setMany(e,{silent:t}={}){let n=!1;for(let[r,i]of Object.entries(e)){let e=this._values.get(r);if(e===i)continue;this._values.set(r,i);let a=Jc[r];a&&(this._applyRoute(a,i,e),(a.reset??!0)&&(n=!0),t||this.dispatchEvent({type:F.SETTING_CHANGED,key:r,value:i,prev:e}))}n&&this._resetCallback?.()}get(e){return this._values.get(e)}getAll(){return Object.fromEntries(this._values)}applyAll(){for(let[e,t]of this._values){let n=Jc[e];n&&this._applyRoute(n,t,void 0)}}_applyRoute(e,t,n){e.uniform?(this._pathTracer?.setUniform(e.uniform,t),e.after&&this._pathTracer?.[e.after]?.()):e.handler?this._handlers[e.handler]?.(t,n):e.delegate&&this._delegates[e.delegate]?.updateParam?.(e.param,t)}_initDefaults(e){for(let t of Object.keys(Jc))t in e&&this._values.set(t,e[t]);for(let[t,n]of Object.entries(Yc))t in e&&this._values.set(n,e[t])}},Zc=class extends r.EventDispatcher{constructor(e){super();let t=e.clientWidth,n=e.clientHeight;this.camera=new r.PerspectiveCamera(60,t/n||1,.01,1e3),this.camera.position.set(0,0,5),this.controls=new m.OrbitControls(this.camera,e),this.controls.screenSpacePanning=!0,this.controls.zoomToCursor=!0,this.controls.saveState(),this.interactionManager=null,this.cameras=[this.camera],this.currentCameraIndex=0,this.autoFocusMode=Ne.SMOOTHING_FACTOR?`auto`:`manual`,this.afScreenPoint={x:.5,y:.5},this.afSmoothingFactor=Ne.SMOOTHING_FACTOR,this._lastValidFocusDistance=null,this._smoothedFocusDistance=null,this._afPointDirty=!1,this._afSuspended=!1,this._defaultCameraState=null,this._onResize=null,this._onReset=null,this._getSettings=null}setCameras(e){this.cameras=e}getCameraNames(){return!this.cameras||this.cameras.length===0?[`Default Camera`]:this.cameras.map((e,t)=>t===0?`Default Camera`:e.name||`Camera ${t}`)}initCallbacks({onResize:e,onReset:t,getSettings:n}){this._onResize=e,this._onReset=t,this._getSettings=n}switchCamera(e,t,n,i){if(t??=this._getSettings?.(`focusDistance`),n??=this._onResize,i??=this._onReset,!(!this.cameras||this.cameras.length===0)){if((e<0||e>=this.cameras.length)&&(console.warn(`CameraManager: Invalid camera index ${e}. Using default camera.`),e=0),this.currentCameraIndex===0&&e!==0&&(this._defaultCameraState={position:this.camera.position.clone(),quaternion:this.camera.quaternion.clone(),fov:this.camera.fov,near:this.camera.near,far:this.camera.far,target:this.controls?this.controls.target.clone():null}),this.currentCameraIndex=e,e===0&&this._defaultCameraState){let e=this._defaultCameraState;this.camera.position.copy(e.position),this.camera.quaternion.copy(e.quaternion),this.camera.fov=e.fov,this.camera.near=e.near,this.camera.far=e.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls&&e.target&&(this.controls.target.copy(e.target),this.controls.update())}else{let n=this.cameras[e];if(this.camera.position.copy(n.position),this.camera.quaternion.copy(n.quaternion),this.camera.fov=n.fov,this.camera.near=n.near,this.camera.far=n.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls){let e=new r.Vector3(0,0,-1).applyQuaternion(n.quaternion),i=t||5;this.controls.target.copy(this.camera.position).addScaledVector(e,i),this.controls.update()}}n?.(),i?.(),this.dispatchEvent({type:`CameraSwitched`,cameraIndex:e})}}focusOn(e){!e||!this.controls||(this.controls.target.copy(e),this.controls.update(),this._onReset?.())}get active(){return this.camera}getNames(){return this.getCameraNames()}setAutoFocusMode(e){this.autoFocusMode=e,e!==`manual`&&(this._smoothedFocusDistance=null,this._afPointDirty=!0)}setAFScreenPoint(e,t){this.afScreenPoint={x:e,y:t},this._afPointDirty=!0}enterAFPointPlacementMode(){this.interactionManager&&(this.interactionManager.enterAFPointPlacementMode(),this.controls&&(this.controls.enabled=!1))}exitAFPointPlacementMode(){this.interactionManager&&(this.interactionManager.exitAFPointPlacementMode(),this.controls&&(this.controls.enabled=!0))}updateAutoFocus(e){let{meshScene:t,assetLoader:n,floorPlane:r,currentFocusDistance:i,pathTracer:a,setFocusDistance:o,softReset:s,hardReset:c}=e||this._afContext||{};if(!t||this.autoFocusMode===`manual`)return;if(!a?.enableDOF?.value){this._afSuspended=!0;return}this._afSuspended&&(this._afSuspended=!1,this._smoothedFocusDistance=null);let l=a;if(l?.isReady&&l.renderMode?.value===1&&l.frameCount>0&&!l.isComplete)return;let u=this.afScreenPoint.x*2-1,d=-(this.afScreenPoint.y*2-1),f=this.interactionManager?.raycaster;if(!f)return;f.setFromCamera({x:u,y:d},this.camera);let p=f.intersectObjects(t.children,!0).find(e=>e.object!==this.interactionManager?.focusPointIndicator&&e.object!==r&&!e.object.name.includes(`Helper`)&&e.object.type===`Mesh`),m;if(p)m=p.distance,this._lastValidFocusDistance=m;else if(this._lastValidFocusDistance!==null)m=this._lastValidFocusDistance;else{let e=n?.getSceneScale()||1;m=Ne.FALLBACK_DISTANCE*e,this._lastValidFocusDistance=m}let h=this._afPointDirty;this._afPointDirty=!1,h||this._smoothedFocusDistance===null||this._smoothedFocusDistance===0||Math.abs(m-this._smoothedFocusDistance)/this._smoothedFocusDistance>Ne.SNAP_THRESHOLD?this._smoothedFocusDistance=m:this._smoothedFocusDistance+=this.afSmoothingFactor*(m-this._smoothedFocusDistance);let g=i,_=this._smoothedFocusDistance;if(h||g===0||Math.abs(_-g)/Math.max(g,.001)>.001){o(_);let e=n?.getSceneScale()||1;this.dispatchEvent({type:F.AUTO_FOCUS_UPDATED,distance:_/e});let t=Math.abs(_-g)/Math.max(g,.001);h?c?.():t>Ne.RESET_THRESHOLD&&s?.()}}setInteractionManager(e){this.interactionManager=e}initAutoFocus({meshScene:e,assetLoader:t,floorPlane:n,pathTracer:r,settings:i,softReset:a,hardReset:o}){this._afContext={meshScene:e,assetLoader:t,floorPlane:n,pathTracer:r,setFocusDistance:e=>i.set(`focusDistance`,e,{silent:!0}),softReset:a,hardReset:o},Object.defineProperty(this._afContext,`currentFocusDistance`,{get:()=>i.get(`focusDistance`)})}dispose(){this.controls?.dispose()}},Qc=class extends r.EventDispatcher{constructor(e,t,n,r={}){super(),this.scene=e,this.sceneHelpers=t,this.pathTracer=n,this._onReset=r.onReset||null}addLight(e){let t={DirectionalLight:{position:[1,1,1],intensity:1,color:`#ffffff`},PointLight:{position:[0,2,0],intensity:1e3,color:`#ffffff`},SpotLight:{position:[0,1,0],intensity:1e3,color:`#ffffff`,angle:15},RectAreaLight:{position:[0,2,0],intensity:100,color:`#ffffff`,width:2,height:2}}[e];if(!t)return null;let n;if(e===`DirectionalLight`)n=new r.DirectionalLight(t.color,t.intensity),n.position.fromArray(t.position);else if(e===`PointLight`)n=new r.PointLight(t.color,t.intensity),n.position.fromArray(t.position);else if(e===`SpotLight`){n=new r.SpotLight(t.color,t.intensity),n.position.fromArray(t.position),n.angle=r.MathUtils.degToRad(t.angle);let e=new r.Object3D;this.scene.add(e),n.target=e}else e===`RectAreaLight`&&(n=new r.RectAreaLight(t.color,t.intensity,t.width,t.height),n.position.fromArray(t.position),n.lookAt(0,0,0),n.userData.normalize=!0,n.userData.spread=Math.PI,n.userData.shape=`rectangle`);n.userData.temperature=6500,n.userData.useTemperature=!1,n.userData.exposure=0;let i=this.scene.getObjectsByProperty(`isLight`,!0).length;return n.name=`${e.replace(`Light`,``)} ${i+1}`,this.scene.add(n),this.updateLights(),this._syncHelpers(),this._onReset?.(),this._buildDescriptor(n)}removeLight(e){let t=this.scene.getObjectByProperty(`uuid`,e);return!t||!t.isLight?!1:(this.sceneHelpers.remove(t),t.target&&t.target.removeFromParent(),t.removeFromParent(),this.updateLights(),this._onReset?.(),!0)}clearLights(){this.sceneHelpers.clear(),this._removeAllLights(),this.updateLights(),this._onReset?.()}getLights(){return this.scene.getObjectsByProperty(`isLight`,!0).map(e=>this._buildDescriptor(e))}updateLights(){this.pathTracer?.updateLights(),this.sceneHelpers?.visible&&this.sceneHelpers.update()}transferSceneLights(e){this._removeAllLights();let t=e.getObjectsByProperty(`isLight`,!0);if(!t||t.length===0){this.updateLights();return}for(let e of t){let t=e.clone();if(e.updateWorldMatrix(!0,!1),e.getWorldPosition(t.position),e.getWorldQuaternion(t.quaternion),e.getWorldScale(t.scale),t.isRectAreaLight&&(t.width*=t.scale.x,t.height*=t.scale.y,t.scale.set(1,1,1)),(e.isSpotLight||e.isDirectionalLight)&&e.target){let n=new r.Object3D;e.target.updateWorldMatrix(!0,!1),e.target.getWorldPosition(n.position),this.scene.add(n),t.target=n}this.scene.add(t)}this.updateLights(),this._syncHelpers()}setShowLightHelper(e){this.sceneHelpers.visible=e,e?this._syncHelpers():this.sceneHelpers.clear()}add(e){return this.addLight(e)}remove(e){return this.removeLight(e)}clear(){this.clearLights()}getAll(){return this.getLights()}sync(){this.updateLights()}showHelpers(e){this.setShowLightHelper(e)}dispose(){this._disposed||(this._disposed=!0,this.sceneHelpers?.clear(),this._removeAllLights(),this._onReset=null,this.pathTracer=null,this.sceneHelpers=null,this.scene=null)}_removeAllLights(){this.scene.getObjectsByProperty(`isLight`,!0).forEach(e=>{e.target&&this.scene.remove(e.target),this.scene.remove(e)})}_syncHelpers(){if(!this.sceneHelpers.visible)return;let e=this.scene.getObjectsByProperty(`isLight`,!0);this.sceneHelpers.sync(e)}_buildDescriptor(e){let t=0;e.type===`SpotLight`&&e.angle!==void 0&&(t=r.MathUtils.radToDeg(e.angle));let n={uuid:e.uuid,name:e.name,type:e.type,intensity:e.intensity,color:`#${e.color.getHexString()}`,position:[e.position.x,e.position.y,e.position.z],angle:t,temperature:e.userData?.temperature??6500,useTemperature:e.userData?.useTemperature??!1,exposure:e.userData?.exposure??0};if(e.type===`RectAreaLight`){n.width=e.width,n.height=e.height,n.normalize=e.userData?.normalize??!0,n.spread=r.MathUtils.radToDeg(e.userData?.spread??Math.PI);let t=e.userData?.shape;n.shape=t===`square`||t===`rectangle`||t===`disk`||t===`ellipse`?t:t===1?`ellipse`:`rectangle`;let i=e.getWorldDirection(e.position.clone());n.target=[e.position.x+i.x,e.position.y+i.y,e.position.z+i.z]}else e.type===`SpotLight`&&e.target?(n.target=[e.target.position.x,e.target.position.y,e.target.position.z],n.distance=e.distance??0,n.penumbra=e.penumbra??0,n.decay=e.decay??2):e.type===`PointLight`&&(n.distance=e.distance??0,n.decay=e.decay??2);return(e.type===`SpotLight`||e.type===`DirectionalLight`)&&e.userData?.gobo&&(n.gobo=e.userData.gobo.name,n.goboIntensity=e.userData.gobo.intensity,n.goboInverted=!!e.userData.gobo.inverted,e.type===`DirectionalLight`&&(n.goboScale=e.userData.gobo.scale??5)),e.type===`SpotLight`&&e.userData?.ies&&(n.ies=e.userData.ies.name,n.iesIntensity=e.userData.ies.intensity??1,n.fixtureLumens=e.userData.ies.fixtureLumens??null),n}},$c=class{constructor(e,t={}){this.pathTracer=e,this._onReset=t.onReset||null,this.texture=null,this.entries=[],this._size=256}async loadLibrary(e,{size:t=256}={}){if(!Array.isArray(e)||e.length===0)return[];this._size=t;let n=await Promise.all(e.map(e=>el(e.url))),i=t,a=t,o=n.length,s=new Uint8Array(i*a*o*4),c=document.createElement(`canvas`);c.width=i,c.height=a;let l=c.getContext(`2d`,{willReadFrequently:!0});for(let e=0;e<o;e++){l.clearRect(0,0,i,a),l.drawImage(n[e],0,0,i,a);let t=l.getImageData(0,0,i,a);s.set(t.data,e*i*a*4)}let u=new r.DataArrayTexture(s,i,a,o);u.minFilter=r.LinearFilter,u.magFilter=r.LinearFilter,u.format=r.RGBAFormat,u.type=r.UnsignedByteType,u.generateMipmaps=!1,u.needsUpdate=!0;let d=this.texture;return this.texture=u,this.entries=e.map((e,t)=>({name:e.name,index:t})),this.pathTracer.goboMaps=u,this.pathTracer.shaderBuilder?.updateGoboMaps?.(u),d?.dispose?.(),this.entries}getEntries(){return this.entries.slice()}setLightGobo(e,t,n={}){let{intensity:r=1,inverted:i=!1,scale:a=5}=n,o=this._findGoboLight(e);if(!o)return!1;if(o.userData=o.userData||{},t==null)delete o.userData.gobo;else{let e=this.entries.find(e=>e.name===t);if(!e)return console.warn(`GoboManager: unknown gobo "${t}"`),!1;o.userData.gobo={name:e.name,index:e.index,intensity:tl(r),inverted:!!i,scale:Math.max(1e-4,a)}}return this.pathTracer.updateLights(),this._onReset?.(),!0}setLightGoboInverted(e,t){let n=this._findGoboLight(e);return n?.userData?.gobo?(n.userData.gobo.inverted=!!t,this.pathTracer.updateLights(),this._onReset?.(),!0):!1}setLightGoboScale(e,t){let n=this._findGoboLight(e);return n?.userData?.gobo?(n.userData.gobo.scale=Math.max(1e-4,t),this.pathTracer.updateLights(),this._onReset?.(),!0):!1}getLightGobo(e){return this._findGoboLight(e)?.userData?.gobo||null}setSpotLightGobo(e,t,n=1,r=!1){return this.setLightGobo(e,t,{intensity:n,inverted:r})}setSpotLightGoboInverted(e,t){return this.setLightGoboInverted(e,t)}getSpotLightGobo(e){return this.getLightGobo(e)}dispose(){this.texture?.dispose?.(),this.texture=null,this.entries=[],this.pathTracer=null,this._onReset=null}_findGoboLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&(t.isSpotLight||t.isDirectionalLight)?t:null}_findSpotLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&t.isSpotLight?t:null}};function el(e){return new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>t(r),r.onerror=()=>n(Error(`Failed to load gobo image: ${e}`)),r.src=e})}function tl(e){return Math.max(0,Math.min(1,e))}function nl(e,t=`ies`){let n=e.search(/TILT\s*=/i);if(n<0)throw Error(`IES (${t}): missing TILT line`);let r=e.indexOf(`
734
- `,n);if(r<0)throw Error(`IES (${t}): truncated TILT line`);let i=e.slice(n,r).match(/TILT\s*=\s*(\w+)/i),a=i?i[1].toUpperCase():`NONE`,o=e.slice(r);if(a===`INCLUDE`){let e=ol(o),t=2+2*Number(e[1]);o=sl(o,t)}let s=ol(o),c=0,l=()=>Number(s[c++]),u=l(),d=l(),f=l(),p=l(),m=l(),h=l();l(),l(),l(),l();let g=l();if(l(),l(),!Number.isFinite(p)||p<=0)throw Error(`IES (${t}): invalid vertical angle count ${p}`);if(!Number.isFinite(m)||m<=0)throw Error(`IES (${t}): invalid horizontal angle count ${m}`);let _=Array(p);for(let e=0;e<p;e++)_[e]=l();let v=Array(m);for(let e=0;e<m;e++)v[e]=l();let y=Array(p);for(let e=0;e<p;e++)y[e]=new Float32Array(m);let b=f*g,x=0;for(let e=0;e<m;e++)for(let t=0;t<p;t++){let n=l()*b;y[t][e]=n,n>x&&(x=n)}return{verticalAngles:_,horizontalAngles:v,candela:y,maxCandela:x,lumens:d*u,photometricType:h,name:t}}function rl(e,t,n){let r=new Uint8Array(t*n),{verticalAngles:i,horizontalAngles:a,candela:o,maxCandela:s}=e;if(s<=0)return r;let c=i[i.length-1],l=a[a.length-1],u=a[0],d=a.length===1||l===u;for(let e=0;e<n;e++){let f=(e+.5)/n*c,p=cl(i,f),m=Math.min(p+1,i.length-1),h=i[m]-i[p],g=h>0?(f-i[p])/h:0;for(let n=0;n<t;n++){let i;if(d)i=ll(o[p][0],o[m][0],g);else{let e=u+(n+.5)/t*(l-u),r=cl(a,e),s=Math.min(r+1,a.length-1),c=a[s]-a[r],d=c>0?(e-a[r])/c:0,f=o[p][r],h=o[p][s],_=o[m][r],v=o[m][s];i=ll(ll(f,h,d),ll(_,v,d),g)}let c=Math.min(1,Math.max(0,i/s));r[e*t+n]=Math.round(c*255)}}return r}function il(e,t=.1){let{verticalAngles:n,horizontalAngles:r,candela:i,maxCandela:a}=e,o=Math.PI/4;if(a<=0||!n?.length)return o;let s=a*t,c=r.length,l=n[n.length-1],u=!1;for(let e=0;e<n.length;e++){let t=0;for(let n=0;n<c;n++)t+=i[e][n];if(t/=c,t>=s&&(u=!0),u&&t<s){l=n[e];break}}let d=l*Math.PI/180;return Math.min(Math.max(d,5*Math.PI/180),89*Math.PI/180)}function al(e,t,n=.7){let{verticalAngles:r,horizontalAngles:i,candela:a,maxCandela:o}=e;if(o<=0||!r?.length||t<=0)return 0;let s=o*n,c=i.length,l=0;for(let e=0;e<r.length;e++){let t=0;for(let n=0;n<c;n++)t+=a[e][n];if(t/=c,t>=s)l=r[e];else break}let u=t*180/Math.PI,d=u>0?1-l/u:0;return Math.min(Math.max(d,0),1)}function ol(e){return e.split(/\s+/).filter(e=>e.length>0)}function sl(e,t){let n=/\S+/g,r=0;for(;n.exec(e)!==null;)if(r++,r===t)return e.slice(n.lastIndex);return``}function cl(e,t){if(t<=e[0])return 0;if(t>=e[e.length-1])return e.length-1;let n=0,r=e.length-1;for(;r-n>1;){let i=n+r>>1;e[i]<=t?n=i:r=i}return n}function ll(e,t,n){return e+(t-e)*n}var ul=class{constructor(e,t={}){this.pathTracer=e,this._onReset=t.onReset||null,this.texture=null,this.entries=[],this._gridWidth=128,this._gridHeight=128}async loadLibrary(e,{gridWidth:t=128,gridHeight:n=128}={}){if(!Array.isArray(e)||e.length===0)return[];this._gridWidth=t,this._gridHeight=n;let i=(await Promise.all(e.map(async e=>{try{let r=await fetch(e.url);if(!r.ok)throw Error(`HTTP ${r.status}`);let i=nl(await r.text(),e.name);return{it:e,profile:i,grid:rl(i,t,n)}}catch(t){return console.warn(`IESManager: failed to load "${e.name}": ${t.message}`),null}}))).filter(e=>e!==null);if(i.length===0)return[];let a=i.length,o=t*n,s=new Uint8Array(o*4*a),c=[];for(let e=0;e<a;e++){let t=i[e].grid,n=e*o*4;for(let e=0;e<o;e++){let r=t[e];s[n+e*4+0]=r,s[n+e*4+1]=r,s[n+e*4+2]=r,s[n+e*4+3]=255}let r=i[e].profile,a=il(r);c.push({name:i[e].it.name,index:e,maxCandela:r.maxCandela,photometricType:r.photometricType,suggestedAngle:a,suggestedPenumbra:al(r,a),lumens:r.lumens})}let l=new r.DataArrayTexture(s,t,n,a);l.format=r.RGBAFormat,l.type=r.UnsignedByteType,l.minFilter=r.LinearFilter,l.magFilter=r.LinearFilter,l.generateMipmaps=!1,l.needsUpdate=!0;let u=this.texture;return this.texture=l,this.entries=c,this.pathTracer.iesProfiles=l,this.pathTracer.shaderBuilder?.updateIESProfiles?.(l),u?.dispose?.(),this.entries.map(({name:e,index:t})=>({name:e,index:t}))}getEntries(){return this.entries.slice()}setSpotLightProfile(e,t,n=1,{applyAutoCone:r=!0}={}){let i=this._findSpotLight(e),a={applied:!1,suggestedAngle:null,suggestedPenumbra:null,suggestedDecay:null,fixtureLumens:null};if(!i)return a;i.userData=i.userData||{};let o=null,s=null,c=null,l=null;if(t==null)delete i.userData.ies;else{let e=this.entries.find(e=>e.name===t);if(!e)return console.warn(`IESManager: unknown profile "${t}"`),a;l=Number.isFinite(e.lumens)?e.lumens:null,i.userData.ies={name:e.name,index:e.index,intensity:dl(n),fixtureLumens:l},r&&(Number.isFinite(e.suggestedAngle)&&(i.angle=e.suggestedAngle,o=e.suggestedAngle),Number.isFinite(e.suggestedPenumbra)&&(i.penumbra=e.suggestedPenumbra,s=e.suggestedPenumbra),i.decay=2,c=2)}return this.pathTracer.updateLights(),this._onReset?.(),{applied:!0,suggestedAngle:o,suggestedPenumbra:s,suggestedDecay:c,fixtureLumens:l}}getSpotLightProfile(e){return this._findSpotLight(e)?.userData?.ies||null}dispose(){this.texture?.dispose?.(),this.texture=null,this.entries=[],this.pathTracer=null,this._onReset=null}_findSpotLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&t.isSpotLight?t:null}};function dl(e){return Math.max(0,Math.min(1,e))}var fl=e=>Math.min(Math.max(e,0),1);function pl(e,t,n,r,i){i[0]=fl(e),i[1]=fl(t),i[2]=fl(n)}function ml(e,t,n,r,i){i[0]=fl(e*r),i[1]=fl(t*r),i[2]=fl(n*r)}function hl(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=fl(e/(e+1)),i[1]=fl(t/(t+1)),i[2]=fl(n/(n+1))}function gl(e,t,n,r,i){e=Math.max(e*r-.004,0),t=Math.max(t*r-.004,0),n=Math.max(n*r-.004,0);let a=e=>(e*(6.2*e+.5)/(e*(6.2*e+1.7)+.06))**2.2;i[0]=a(e),i[1]=a(t),i[2]=a(n)}function _l(e,t,n,r,i){e=e*r/.6,t=t*r/.6,n=n*r/.6;let a=.59719*e+.35458*t+.04823*n,o=.076*e+.90834*t+.01566*n,s=.0284*e+.13383*t+.83777*n,c=e=>(e*(e+.0245786)-90537e-9)/(e*(.983729*e+.432951)+.238081);a=c(a),o=c(o),s=c(s),i[0]=fl(1.60475*a-.53108*o-.07367*s),i[1]=fl(-.10208*a+1.10813*o-.00605*s),i[2]=fl(-.00327*a-.07276*o+1.07602*s)}function vl(e,t,n,r,i){e*=r,t*=r,n*=r;let a=.6274*e+.3293*t+.0433*n,o=.0691*e+.9195*t+.0113*n,s=.0164*e+.088*t+.8956*n,c=.856627153315983*a+.0951212405381588*o+.0482516061458583*s,l=.137318972929847*a+.761241990602591*o+.101439036467562*s,u=.11189821299995*a+.0767994186031903*o+.811302368396859*s,d=-12.47393,f=4.026069-d;c=fl((Math.log2(Math.max(c,1e-10))-d)/f),l=fl((Math.log2(Math.max(l,1e-10))-d)/f),u=fl((Math.log2(Math.max(u,1e-10))-d)/f);let p=e=>{let t=e*e,n=t*t;return 15.5*n*t-40.14*n*e+31.96*n-6.868*t*e+.4298*t+.1191*e-.00232};c=p(c),l=p(l),u=p(u);let m=1.1271005818144368*c-.11060664309660323*l-.016493938717834573*u,h=-.1413297634984383*c+1.157823702216272*l-.016493938717834257*u,g=-.14132976349843826*c-.11060664309660294*l+1.2519364065950405*u;m=Math.max(0,m)**2.2,h=Math.max(0,h)**2.2,g=Math.max(0,g)**2.2,i[0]=fl(1.6605*m-.5876*h-.0728*g),i[1]=fl(-.1246*m+1.1329*h-.0083*g),i[2]=fl(-.0182*m-.1006*h+1.1187*g)}function yl(e,t,n,r,i){let a=.76;e*=r,t*=r,n*=r;let o=Math.min(e,Math.min(t,n)),s=o<.08?o-6.25*o*o:.04;e-=s,t-=s,n-=s;let c=Math.max(e,Math.max(t,n));if(c<a){i[0]=e,i[1]=t,i[2]=n;return}let l=1-a,u=1-l*l/(c+l-a),d=u/c;e*=d,t*=d,n*=d;let f=1-1/(.15*(c-u)+1);i[0]=e+(u-e)*f,i[1]=t+(u-t)*f,i[2]=n+(u-n)*f}var bl=new Map([[r.NoToneMapping,pl],[r.LinearToneMapping,ml],[r.ReinhardToneMapping,hl],[r.CineonToneMapping,gl],[r.ACESFilmicToneMapping,_l],[r.AgXToneMapping,vl],[r.NeutralToneMapping,yl]]),xl=1/2.2;function Sl(e){return e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055}var Cl=.2126,wl=.7152,Tl=.0722;function El(e,t){if(t===1)return;let n=e[0]*Cl+e[1]*wl+e[2]*Tl;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}var Dl=null,Ol=null;async function kl(){if(!Dl){let[e,t]=await Promise.all([import(`oidn-web`),import(`@tensorflow/tfjs-core`)]);Dl=e.initUNetFromURL,Ol=t.engine}return Dl}function Al(){if(Ol)try{let e=Ol();e?.registryFactory&&`webgpu-oidn`in e.registryFactory&&e.removeBackend(`webgpu-oidn`)}catch(e){console.warn(`OIDNDenoiser: failed to clear cached TFJS backend`,e)}}var jl=new Float32Array(3),Ml={QUALITY_MODELS:{fast:`rt_hdr_alb_nrm_small`,balance:`rt_hdr_alb_nrm`,high:`rt_hdr_calb_cnrm_large`},DEFAULT_OPTIONS:{enableOIDN:!0,oidnQuality:`fast`,debugGbufferMaps:!0,tileSize:256}},Nl=class extends r.EventDispatcher{constructor(e,t,n,i,a={}){if(super(),!e||!t||!n||!i)throw Error(`OIDNDenoiser requires output canvas, renderer, scene, and camera`);this.renderer=t,this.scene=n,this.camera=i,this.input=t.domElement,this.output=e,this.extractGBufferData=a.extractGBufferData||null,this.getMRTRenderTarget=a.getMRTRenderTarget||null,this.backendParamsGetter=a.backendParams||null,this.getGPUTextures=a.getGPUTextures||null,this.getExposure=a.getExposure||(()=>1),this.getToneMapping=a.getToneMapping||(()=>r.ACESFilmicToneMapping),this.getSaturation=a.getSaturation||(()=>1),this.getTransparentBackground=a.getTransparentBackground||(()=>!1),this.isGPUMode=!!this.backendParamsGetter,this.gpuDevice=null,this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputBufferSize={width:0,height:0},this._gpuInputPadBuffer=null,this._gpuInputPaddedRowBytes=0,this._alphaReadbackBuffer=null,this._alphaReadbackMapped=!1,this._cachedAlpha=null,this._cachedAlphaWidth=0,this.config={...Ml.DEFAULT_OPTIONS,...a},this.enabled=this.config.enableOIDN,this.quality=this.config.oidnQuality,this.debugGbufferMaps=this.config.debugGbufferMaps,this.tileSize=this.config.tileSize,this.state={isDenoising:!1,isLoading:!1,abortController:null},this._pendingStagingBuffers=new Set,this._pendingTileBlits=[],this.currentTZAUrl=null,this.unet=null,this._pendingStart=!1,this._initialize().catch(e=>{console.error(`Failed to initialize OIDNDenoiser:`,e),this.dispatchEvent({type:`error`,error:e})})}async _initialize(){try{this._setupCanvas(),await this._setupUNetDenoiser()}catch(e){throw Error(`Initialization failed: ${e.message}`)}}_setupCanvas(){if(!this.output.getContext)throw Error(`Output must be a valid Canvas element`);this.output.willReadFrequently=!0,this.output.width=this.input.width,this.output.height=this.input.height,Object.assign(this.output.style,{position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,borderRadius:`5px`,background:`repeating-conic-gradient(#808080 0% 25%, transparent 0% 50%) 50% / 20px 20px`}),this.ctx=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0})}async _setupUNetDenoiser(){if(this.state.isLoading)return;this.state.isLoading=!0;let e=this._generateTzaUrl();if(this.currentTZAUrl===e&&this.unet){this.state.isLoading=!1;return}try{this.dispatchEvent({type:`loading`,message:`Loading UNet denoiser...`}),this.unet&&=(this.unet.dispose(),null);let t;if(this.isGPUMode&&this.backendParamsGetter){let e=this.backendParamsGetter();this.gpuDevice=e?.device??null,t=e?.device?e:void 0}this.unet=await(await kl())(e,t,{aux:!0,hdr:!0,maxTileSize:this.tileSize}),this.currentTZAUrl=e,this.dispatchEvent({type:`loaded`}),console.log(`UNet denoiser loaded successfully:`,e)}catch(e){console.error(`Failed to load UNet denoiser:`,e),this.dispatchEvent({type:`error`,error:Error(`Denoiser loading failed: ${e.message}`)})}finally{this.state.isLoading=!1,this._pendingStart&&this.unet&&this.enabled&&(this._pendingStart=!1,this.start())}}_generateTzaUrl(){let{oidnWeightsBaseUrl:e}=na(),{QUALITY_MODELS:t}=Ml;return`${e}${t[this.quality]||t.balance}.tza`}async updateConfiguration(e){Object.keys(e).some(t=>this.config[t]!==e[t])&&(Object.assign(this.config,e),this.quality=this.config.oidnQuality,this.debugGbufferMaps=this.config.debugGbufferMaps,this.tileSize=this.config.tileSize,await this._setupUNetDenoiser())}async updateQuality(e){if(!Object.prototype.hasOwnProperty.call(Ml.QUALITY_MODELS,e))throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(Ml.QUALITY_MODELS).join(`, `)}`);await this.updateConfiguration({oidnQuality:e})}async start(){if(!this.enabled||this.state.isDenoising)return!1;if(this.state.isLoading)return this._pendingStart=!0,!1;this.dispatchEvent({type:`start`});let e=performance.now(),t=await this.execute();if(t){this.renderer?.resetState?.(),this.input.style.opacity=`0`;let t=performance.now()-e;console.log(`Denoising completed in ${t.toFixed(1)}ms (quality: ${this.quality})`)}return t}async execute(){if(!this.enabled||!this.unet)return!1;this.state.abortController=new AbortController,this.state.isDenoising=!0,this.input.style.opacity=`0`,this.output.style.display=`block`;try{return await this._executeUNet(),!0}catch(e){return e.name===`AbortError`?console.log(`Denoising was aborted`):console.error(`Denoising error:`,e),this.input.style.opacity=`1`,!1}finally{this.state.isDenoising=!1,this.state.abortController=null,this.dispatchEvent({type:`end`})}}async _executeUNet(){return this._executeUNetGPU()}async _executeUNetGPU(){let{width:e,height:t}=this.output;if(!this.getGPUTextures)return console.warn(`OIDNDenoiser: GPU mode enabled but getGPUTextures not provided`),!1;let n=this.getGPUTextures();if(!n?.color)return console.warn(`OIDNDenoiser: GPU textures not ready yet`),!1;let r=this.gpuDevice;if(!r)return console.warn(`OIDNDenoiser: gpuDevice not available`),!1;this._ensureGPUInputBuffers(e,t);let i=r.createCommandEncoder({label:`oidn-tex-to-buf`}),a=e*16,o=this._gpuInputPaddedRowBytes,s=o>a,c=this._gpuInputPadBuffer,l=(n,r)=>{if(!s)i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:r,offset:0,bytesPerRow:a,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});else{i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:c,offset:0,bytesPerRow:o,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});for(let e=0;e<t;e++)i.copyBufferToBuffer(c,e*o,r,e*a,a)}};l(n.color,this._gpuInputBuffers.color),l(n.albedo,this._gpuInputBuffers.albedo),l(n.normal,this._gpuInputBuffers.normal),r.queue.submit([i.finish()]),this.getTransparentBackground()?await this._cacheInputAlpha(r,e,t):this._cachedAlpha=null,this.ctx.drawImage(this.input,0,0,e,t);let u={color:{data:this._gpuInputBuffers.color,width:e,height:t},albedo:{data:this._gpuInputBuffers.albedo,width:e,height:t},normal:{data:this._gpuInputBuffers.normal,width:e,height:t}};return this._executeWithAbortGPU(u)}_ensureGPUInputBuffers(e,t){let{width:n,height:r}=this._gpuInputBufferSize;if(n===e&&r===t&&this._gpuInputBuffers.color)return;this._destroyGPUInputBuffers();let i=this.gpuDevice,a=e*t*16,o=GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC;this._gpuInputBuffers.color=i.createBuffer({label:`oidn-in-color`,size:a,usage:o}),this._gpuInputBuffers.albedo=i.createBuffer({label:`oidn-in-albedo`,size:a,usage:o}),this._gpuInputBuffers.normal=i.createBuffer({label:`oidn-in-normal`,size:a,usage:o}),this._gpuInputBufferSize={width:e,height:t};let s=e*16,c=Math.ceil(s/256)*256;c===s?this._gpuInputPaddedRowBytes=s:(this._gpuInputPadBuffer=i.createBuffer({label:`oidn-in-pad`,size:c*t,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),this._gpuInputPaddedRowBytes=c)}_destroyGPUInputBuffers(){if(this._gpuInputBuffers.color?.destroy(),this._gpuInputBuffers.albedo?.destroy(),this._gpuInputBuffers.normal?.destroy(),this._gpuInputPadBuffer?.destroy(),this._alphaReadbackMapped&&this._alphaReadbackBuffer)try{this._alphaReadbackBuffer.unmap()}catch{}this._alphaReadbackBuffer?.destroy(),this._alphaReadbackMapped=!1,this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputPadBuffer=null,this._gpuInputPaddedRowBytes=0,this._alphaReadbackBuffer=null,this._gpuInputBufferSize={width:0,height:0}}async _cacheInputAlpha(e,t,n){let r=t*n*16;this._alphaReadbackBuffer===null&&(this._alphaReadbackBuffer=e.createBuffer({label:`oidn-alpha-readback`,size:r,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}));let i=this._alphaReadbackBuffer,a=e.createCommandEncoder();a.copyBufferToBuffer(this._gpuInputBuffers.color,0,i,0,r),e.queue.submit([a.finish()]),this._alphaReadbackMapped=!0;try{await i.mapAsync(GPUMapMode.READ)}catch{this._alphaReadbackMapped=!1;return}let o=new Float32Array(i.getMappedRange()),s=t*n,c=new Uint8Array(s);for(let e=0;e<s;e++)c[e]=Math.min(Math.max(o[e*4+3]*255,0),255)|0;i.unmap(),this._alphaReadbackMapped=!1,this._cachedAlpha=c,this._cachedAlphaWidth=t}_executeWithAbortGPU(e){return new Promise((t,n)=>{if(this.state.abortController?.signal.aborted){n(new DOMException(`Aborted`,`AbortError`));return}let i=null;this._pendingTileBlits=[];let a=()=>{i&&=(i(),null),n(new DOMException(`Aborted`,`AbortError`))};this.state.abortController.signal.addEventListener(`abort`,a,{once:!0}),i=this.unet.tileExecute({...e,done:async e=>{this.state.abortController.signal.removeEventListener(`abort`,a),i=null;try{this._pendingTileBlits.length>0?await Promise.allSettled(this._pendingTileBlits):await this._displayGPUOutput(e),t()}catch(e){n(e)}},progress:(e,t,n)=>{if(!e?.data||!n)return;let i=this.gpuDevice,a=e.width,o=e.height,s=Math.min(n.width,a-n.x),c=Math.min(n.height,o-n.y);if(s<=0||c<=0)return;let l=s*16,u=s*c*16,d=i.createBuffer({size:u,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});this._pendingStagingBuffers.add(d);let f=i.createCommandEncoder();for(let t=0;t<c;t++){let r=((n.y+t)*a+n.x)*16,i=t*l;f.copyBufferToBuffer(e.data,r,d,i,l)}i.queue.submit([f.finish()]);let p=d.mapAsync(GPUMapMode.READ).then(()=>{let e=new Float32Array(d.getMappedRange()),t=new ImageData(s,c),i=this.getExposure(),l=this.getSaturation(),u=bl.get(this.getToneMapping())||bl.get(r.ACESFilmicToneMapping),f=this._cachedAlpha,p=this._cachedAlphaWidth;for(let r=0,a=e.length;r<a;r+=4){let a=e[r]*i,o=e[r+1]*i,c=e[r+2]*i;if(l!==1&&(jl[0]=a,jl[1]=o,jl[2]=c,El(jl,l),a=jl[0],o=jl[1],c=jl[2]),u(a,o,c,1,jl),t.data[r]=Sl(jl[0])*255+.5|0,t.data[r+1]=Sl(jl[1])*255+.5|0,t.data[r+2]=Sl(jl[2])*255+.5|0,f){let e=(r>>2)%s,i=(r>>2)/s|0;t.data[r+3]=f[(n.y+i)*p+n.x+e]}else t.data[r+3]=255}d.unmap(),d.destroy(),this._pendingStagingBuffers.delete(d),this.ctx.putImageData(t,n.x,n.y),this.dispatchEvent({type:`tileProgress`,tile:{x:n.x,y:n.y,width:s,height:c},imageWidth:a,imageHeight:o})}).catch(()=>{d.destroy(),this._pendingStagingBuffers.delete(d)});this._pendingTileBlits.push(p)}})})}async _displayGPUOutput({data:e,width:t,height:n}){let i=this.gpuDevice;if(!i){console.error(`OIDNDenoiser: gpuDevice not available for output readback`);return}let a=t*n*4*4,o=i.createBuffer({label:`oidn-output-staging`,size:a,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});try{let s=i.createCommandEncoder({label:`oidn-readback`});s.copyBufferToBuffer(e,0,o,0,a),i.queue.submit([s.finish()]),await o.mapAsync(GPUMapMode.READ);let c=new Float32Array(o.getMappedRange()),l=new ImageData(t,n),u=this.getExposure(),d=this.getSaturation(),f=bl.get(this.getToneMapping())||bl.get(r.ACESFilmicToneMapping),p=this._cachedAlpha;for(let e=0,t=c.length;e<t;e+=4){let t=c[e]*u,n=c[e+1]*u,r=c[e+2]*u;d!==1&&(jl[0]=t,jl[1]=n,jl[2]=r,El(jl,d),t=jl[0],n=jl[1],r=jl[2]),f(t,n,r,1,jl),l.data[e]=Sl(jl[0])*255+.5|0,l.data[e+1]=Sl(jl[1])*255+.5|0,l.data[e+2]=Sl(jl[2])*255+.5|0,l.data[e+3]=p?p[e>>2]:255}o.unmap(),this.ctx.putImageData(l,0,0)}finally{o.destroy()}}abort(){this._pendingStart=!1,!(!this.enabled||!this.state.isDenoising)&&(this.state.abortController?.abort(),this._destroyPendingStagingBuffers(),this.input.style.opacity=`1`,this.state.isDenoising=!1,this.dispatchEvent({type:`end`}),console.log(`Denoising aborted`))}setSize(e,t){if(e<=0||t<=0)throw Error(`Invalid dimensions: ${e}x${t}`);this.output.width=e,this.output.height=t,this._setupUNetDenoiser().catch(e=>{console.error(`Failed to reinitialize denoiser after size change:`,e)})}_destroyPendingStagingBuffers(){for(let e of this._pendingStagingBuffers)e.destroy();this._pendingStagingBuffers.clear()}dispose(){this.abort(),this._destroyPendingStagingBuffers(),this.unet?.dispose(),Al(),this._destroyGPUInputBuffers(),this.output?.parentNode&&this.output.remove(),this.unet=null,this.ctx=null,this.state.abortController=null,this.removeAllListeners?.(),console.log(`OIDNDenoiser disposed`)}},Pl=``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/AIUpscalerWorker-AXN-lKWN.js`).href:new URL(`assets/AIUpscalerWorker-AXN-lKWN.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href),Fl={fast:{2:`2x-spanx2-ch48.onnx`,4:`4xNomos8k_span_otf_strong_fp32_opset17.onnx`},balanced:{2:`2xNomosUni_compact_otf_medium.onnx`,4:`RealESRGAN_x4plus.onnx`},quality:{2:`2x-realesrgan-x2plus.onnx`,4:`4xNomos2_hq_mosr_fp32.onnx`}};function Il(){let{upscalerModelBaseUrl:e}=na(),t={};for(let n in Fl){t[n]={};for(let r in Fl[n])t[n][r]=e+Fl[n][r]}return t}var Ll={get QUALITY_PRESETS(){return Il()},TILE_SIZE:512,TILE_OVERLAP:16,SESSION_OPTIONS:{executionProviders:[{name:`webgpu`,preferredLayout:`NCHW`}],graphOptimizationLevel:`all`}},Rl=class extends r.EventDispatcher{constructor(e,t,n={}){if(super(),!e||!t)throw Error(`AIUpscaler requires output canvas and renderer`);this.renderer=t,this.input=t.domElement,this.output=e,this.getSourceCanvas=n.getSourceCanvas||null,this.getGPUTextures=n.getGPUTextures||null,this.getExposure=n.getExposure||(()=>1),this.getToneMapping=n.getToneMapping||(()=>r.ACESFilmicToneMapping),this.getSaturation=n.getSaturation||(()=>1),this.enabled=!1,this.hdr=!1,this.scaleFactor=n.scaleFactor||2,this.quality=n.quality||`fast`,this.tileSize=n.tileSize||Ll.TILE_SIZE,this._tileSizeOverride=!!n.tileSize,this.state={isUpscaling:!1,isLoading:!1,abortController:null},this._worker=null,this._currentModelUrl=null,this._tileId=0,this._pendingWorkerHandlers=new Set,this._upscaledAlpha=null,this._upscaledAlphaWidth=0,this._backupCanvas=null,this._baseWidth=e.width,this._baseHeight=e.height,this._hdrStagingBuffer=null,this._hdrStagingWidth=0,this._hdrStagingHeight=0}async _ensureSession(){let e=Ll.QUALITY_PRESETS[this.quality];if(!e)throw Error(`Unknown quality preset: ${this.quality}`);let t=e[this.scaleFactor];if(!t)throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);if(!(this._worker&&this._currentModelUrl===t)){this.state.isLoading=!0,this.dispatchEvent({type:`loading`,message:`Loading ${this.scaleFactor}x upscale model...`});try{if(!this._worker)try{this._worker=new Worker(Pl,{type:`module`})}catch(e){if(e.name!==`SecurityError`)throw e;this._worker=await Xe(Pl)}await new Promise((e,n)=>{let r=t=>{t.data.type===`loaded`?(this._worker.removeEventListener(`message`,r),t.data.tileSize&&!this._tileSizeOverride&&(this.tileSize=t.data.tileSize),console.log(`AI Upscaler: ${this.scaleFactor}x model loaded, backend: ${t.data.backend}, tileSize: ${this.tileSize}`),e()):t.data.type===`error`&&(this._worker.removeEventListener(`message`,r),n(Error(t.data.message)))},{ortRuntimeUrl:i,ortWasmPaths:a,cacheNamespace:o}=na();this._worker.addEventListener(`message`,r),this._worker.postMessage({type:`load`,url:t,sessionOptions:Ll.SESSION_OPTIONS,ortRuntimeUrl:i,ortWasmPaths:a,cacheNamespace:o})}),this._currentModelUrl=t,this.dispatchEvent({type:`loaded`})}catch(e){throw console.error(`AI Upscaler: Failed to load model:`,e),this.dispatchEvent({type:`error`,error:e}),e}finally{this.state.isLoading=!1}}}async start(){if(!this.enabled||this.state.isUpscaling||this.state.isLoading)return!1;this.dispatchEvent({type:`start`});let e=performance.now(),t=await this.execute();if(t){this.renderer?.resetState?.();let t=performance.now()-e;console.log(`AI Upscaler: ${this.scaleFactor}x upscale completed in ${t.toFixed(1)}ms`)}return t}async execute(){if(!this.enabled)return!1;this.state.abortController=new AbortController,this.state.isUpscaling=!0,this.input.style.opacity=`0`,this.output.style.display=`block`,this.hdr&&this.getGPUTextures?this._capturedSource=await this._captureSourceHDR():this._capturedSource=this._captureSource(),this._createBackup(this._capturedSource);let e=this._capturedSource.width*this.scaleFactor,t=this._capturedSource.height*this.scaleFactor;this.output.width=e,this.output.height=t;let n=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});n.imageSmoothingEnabled=!0,n.imageSmoothingQuality=`high`,n.drawImage(this._backupCanvas,0,0,e,t);try{return await this._ensureSession(),await this._runUpscale(),this.dispatchEvent({type:`resolution_changed`,width:this.output.width,height:this.output.height}),!0}catch(e){return e.name===`AbortError`?console.log(`AI Upscaler: Upscaling was aborted`):(console.error(`AI Upscaler: Upscaling error:`,e),this.dispatchEvent({type:`error`,error:e}),this._restoreBackup(),this.input.style.opacity=`1`,this.dispatchEvent({type:`resolution_changed`,width:this._baseWidth,height:this._baseHeight})),!1}finally{this._capturedSource=null,this._upscaledAlpha=null,this._backupCanvas=null,this.state.isUpscaling&&(this.state.isUpscaling=!1,this.state.abortController=null,this.dispatchEvent({type:`end`}))}}abort(){this.state.isUpscaling&&(this.state.abortController?.abort(),this._cleanupPendingWorkerHandlers(),this.input.style.opacity=`1`,this._restoreBackup(),this.dispatchEvent({type:`resolution_changed`,width:this._baseWidth,height:this._baseHeight}),this.state.isUpscaling=!1,this.dispatchEvent({type:`end`}),console.log(`AI Upscaler: Aborted`))}async _runUpscale(){let e=this.state.abortController.signal,t=this._capturedSource;this._capturedSource=null;let{width:n,height:i}=t,a=this.scaleFactor,o=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});this._cacheUpscaledAlpha(t,n*a,i*a),t.isHDR&&(this._hdrToneMapFn=bl.get(this.getToneMapping())||bl.get(r.ACESFilmicToneMapping),this._hdrExposure=this.getExposure(),this._hdrSaturation=this.getSaturation(),this._tmOut=new Float32Array(3));let s=Ll.TILE_OVERLAP,c=this.tileSize,l=c-s*2,u=Math.ceil(n/l),d=Math.ceil(i/l),f=u*d,p=0;for(let r=0;r<d;r++)for(let s=0;s<u;s++){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`);let u=Math.min(s*l,Math.max(0,n-c)),d=Math.min(r*l,Math.max(0,i-c)),m=Math.min(c,n-u),h=Math.min(c,i-d),g=this._extractTile(t,u,d,m,h),_=await this._inferTile(g,m,h),v=u*a,y=d*a,b=m*a,x=h*a,S=this._tensorToImageData(_,b,x,v,y);o.putImageData(S,v,y),p++,this.dispatchEvent({type:`progress`,progress:p/f,tile:{x:s,y:r,total:f,completed:p}}),this.dispatchEvent({type:`tileProgress`,tile:{x:v,y,width:b,height:x},imageWidth:n*a,imageHeight:i*a})}}_captureSource(){let e=this.getSourceCanvas?this.getSourceCanvas():null;if(e&&e!==this.output){let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);return n.drawImage(e,0,0),n.getImageData(0,0,t.width,t.height)}return this.output.getContext(`2d`,{willReadFrequently:!0}).getImageData(0,0,this.output.width,this.output.height)}async _captureSourceHDR(){let e=this.getGPUTextures();if(!e?.color)throw Error(`No GPU color texture available for HDR capture`);let t=this.renderer.backend.device,n=e.color,r=n.width,i=n.height,a=Math.ceil(r*16/256)*256,o=a*i;(this._hdrStagingWidth!==r||this._hdrStagingHeight!==i)&&(this._hdrStagingBuffer?.destroy(),this._hdrStagingBuffer=t.createBuffer({label:`aiupscaler-hdr-readback`,size:o,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this._hdrStagingWidth=r,this._hdrStagingHeight=i);let s=this._hdrStagingBuffer,c=t.createCommandEncoder();c.copyTextureToBuffer({texture:n},{buffer:s,bytesPerRow:a,rowsPerImage:i},{width:r,height:i,depthOrArrayLayers:1}),t.queue.submit([c.finish()]),await s.mapAsync(GPUMapMode.READ);let l=new Float32Array(s.getMappedRange()),u=r*4,d=a/4,f=new Float32Array(r*i*4);for(let e=0;e<i;e++){let t=e*d,n=e*u;f.set(l.subarray(t,t+u),n)}return s.unmap(),{data:f,width:r,height:i,isHDR:!0}}_extractTile(e,t,n,r,i){let{data:a,width:o}=e,s=e.isHDR,c=r*i,l=new Float32Array(3*c);for(let e=0;e<i;e++)for(let i=0;i<r;i++){let u=((n+e)*o+(t+i))*4,d=e*r+i;if(s){let e=this._hdrToneMapFn,t=this._hdrExposure,n=this._hdrSaturation,r=a[u]*t,i=a[u+1]*t,o=a[u+2]*t;n!==1&&(this._tmOut[0]=r,this._tmOut[1]=i,this._tmOut[2]=o,El(this._tmOut,n),r=this._tmOut[0],i=this._tmOut[1],o=this._tmOut[2]),e(r,i,o,1,this._tmOut),l[d]=this._tmOut[0]**+xl,l[c+d]=this._tmOut[1]**+xl,l[2*c+d]=this._tmOut[2]**+xl}else l[d]=a[u]/255,l[c+d]=a[u+1]/255,l[2*c+d]=a[u+2]/255}return l}async _inferTile(e,t,n){let r=++this._tileId;return new Promise((i,a)=>{let o=e=>{e.data.id===r&&(this._worker.removeEventListener(`message`,o),this._pendingWorkerHandlers.delete(o),e.data.type===`inferred`?i(e.data.outputData):e.data.type===`error`&&a(Error(e.data.message)))};this._pendingWorkerHandlers.add(o),this._worker.addEventListener(`message`,o),this._worker.postMessage({type:`infer`,tileData:e,width:t,height:n,id:r},[e.buffer])})}_tensorToImageData(e,t,n,r,i){let a=new ImageData(t,n),o=a.data,s=t*n,c=this._upscaledAlpha,l=this._upscaledAlphaWidth;for(let n=0;n<s;n++)if(o[n*4]=Math.min(255,Math.max(0,e[n]*255+.5))|0,o[n*4+1]=Math.min(255,Math.max(0,e[s+n]*255+.5))|0,o[n*4+2]=Math.min(255,Math.max(0,e[2*s+n]*255+.5))|0,c){let e=n/t|0,a=n%t;o[n*4+3]=c[(i+e)*l+(r+a)]}else o[n*4+3]=255;return a}_cacheUpscaledAlpha(e,t,n){let{data:r,width:i,height:a}=e,o=e.isHDR,s=o?1:255,c=!1;for(let e=3;e<r.length;e+=4)if(r[e]<s){c=!0;break}if(!c){this._upscaledAlpha=null,this._upscaledAlphaWidth=0;return}let l=document.createElement(`canvas`);l.width=i,l.height=a;let u=l.getContext(`2d`),d=u.createImageData(i,a);for(let e=0,t=i*a;e<t;e++){let t=o?Math.min(Math.max(r[e*4+3]*255,0),255)|0:r[e*4+3];d.data[e*4]=t,d.data[e*4+1]=t,d.data[e*4+2]=t,d.data[e*4+3]=255}u.putImageData(d,0,0);let f=document.createElement(`canvas`);f.width=t,f.height=n;let p=f.getContext(`2d`);p.imageSmoothingEnabled=!0,p.imageSmoothingQuality=`high`,p.drawImage(l,0,0,t,n);let m=p.getImageData(0,0,t,n).data,h=new Uint8Array(t*n);for(let e=0,r=t*n;e<r;e++)h[e]=m[e*4];this._upscaledAlpha=h,this._upscaledAlphaWidth=t}_createBackup(e){this._backupCanvas=document.createElement(`canvas`),this._backupCanvas.width=e.width,this._backupCanvas.height=e.height;let t=this._backupCanvas.getContext(`2d`);if(e.isHDR){let{data:n,width:i,height:a}=e,o=t.createImageData(i,a),s=o.data,c=bl.get(this.getToneMapping())||bl.get(r.ACESFilmicToneMapping),l=this.getExposure(),u=this.getSaturation(),d=new Float32Array(3);for(let e=0,t=i*a;e<t;e++){let t=e*4,r=n[t]*l,i=n[t+1]*l,a=n[t+2]*l;u!==1&&(d[0]=r,d[1]=i,d[2]=a,El(d,u),r=d[0],i=d[1],a=d[2]),c(r,i,a,1,d),s[t]=d[0]**+xl*255+.5|0,s[t+1]=d[1]**+xl*255+.5|0,s[t+2]=d[2]**+xl*255+.5|0,s[t+3]=255}t.putImageData(o,0,0)}else t.putImageData(e,0,0)}_restoreBackup(){this._backupCanvas&&=(this.output.width=this._backupCanvas.width,this.output.height=this._backupCanvas.height,this.output.getContext(`2d`).drawImage(this._backupCanvas,0,0),null)}toggleHDR(e){this.hdr=!!e}setQuality(e){if(!Ll.QUALITY_PRESETS[e]){console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);return}this.quality=e}setScaleFactor(e){if(e=Number(e),e!==2&&e!==4){console.warn(`AIUpscaler: Invalid scale factor ${e}, must be 2 or 4`);return}this.scaleFactor=e}setBaseSize(e,t){this._baseWidth=e,this._baseHeight=t}_cleanupPendingWorkerHandlers(){if(this._worker)for(let e of this._pendingWorkerHandlers)this._worker.removeEventListener(`message`,e);this._pendingWorkerHandlers.clear()}async dispose(){this.abort(),this._cleanupPendingWorkerHandlers(),this._worker&&=(this._worker.postMessage({type:`dispose`}),this._worker.terminate(),null),this._currentModelUrl=null,this._backupCanvas=null,this._upscaledAlpha=null,this.state.abortController=null,this._hdrStagingBuffer?.destroy(),this._hdrStagingBuffer=null,this._hdrStagingWidth=0,this._hdrStagingHeight=0,console.log(`AIUpscaler disposed`)}},zl=class extends r.EventDispatcher{constructor({renderer:e,mainCanvas:t,scene:n,camera:r,stages:i,pipeline:a,getExposure:o,getSaturation:s,getTransparentBg:c}){super(),this.renderer=e,this.mainCanvas=t,this.denoiserCanvas=this._createDenoiserCanvas(t),this.scene=n,this.camera=r,this.pipeline=a,this._stages=i,this._getExposure=o,this._getSaturation=s,this._getTransparentBg=c,this.denoiser=null,this.upscaler=null,this._lastRenderWidth=0,this._lastRenderHeight=0,this._pendingStartUpscaler=null,this._denoiserStartHandler=null,this._denoiserEndHandler=null,this._upscalerResChangedHandler=null,this._upscalerStartHandler=null,this._upscalerProgressHandler=null,this._upscalerEndHandler=null}_createDenoiserCanvas(e){let t=e.parentNode;if(!t)return null;let n=document.createElement(`canvas`);return n.width=e.width,n.height=e.height,n.style.position=`absolute`,n.style.inset=`0`,n.style.width=`100%`,n.style.height=`100%`,t.insertBefore(n,e),n}setRenderSize(e,t){this._lastRenderWidth=e,this._lastRenderHeight=t,this.denoiser?.setSize(e,t),this.upscaler?.setBaseSize(e,t)}restoreBaseResolution(){if(!this.denoiserCanvas||!this._lastRenderWidth||!this._lastRenderHeight)return!1;let e=this.denoiserCanvas.width!==this._lastRenderWidth||this.denoiserCanvas.height!==this._lastRenderHeight;return this.denoiserCanvas.width=this._lastRenderWidth,this.denoiserCanvas.height=this._lastRenderHeight,e}setupDenoiser(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.denoiser=new Nl(this.denoiserCanvas,this.renderer,this.scene,this.camera,{...B,backendParams:()=>({device:this.renderer.backend.device,adapterInfo:null}),getGPUTextures:()=>{if(!e?.storageTextures?.readTarget)return null;let t=e.storageTextures.getReadTextures(),{backend:n}=this.renderer;return{color:n.get(t.color).texture,normal:n.get(t.normalDepth).texture,albedo:n.get(t.albedo).texture}},getExposure:()=>this._getEffectiveExposure(),getToneMapping:()=>this._getToneMapping(),getSaturation:()=>this._getSaturation(),getTransparentBackground:()=>this._getTransparentBg(),getMRTRenderTarget:()=>e?.storageTextures?.readTarget??null}),this.denoiser.enabled=B.enableOIDN,this._denoiserStartHandler=()=>this.dispatchEvent({type:F.DENOISING_START}),this._denoiserEndHandler=()=>this.dispatchEvent({type:F.DENOISING_END}),this.denoiser.addEventListener(`start`,this._denoiserStartHandler),this.denoiser.addEventListener(`end`,this._denoiserEndHandler)}setupUpscaler(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.upscaler=new Rl(this.denoiserCanvas,this.renderer,{scaleFactor:B.upscalerScale||2,quality:B.upscalerQuality||`fast`,getSourceCanvas:()=>this.denoiser?.enabled?null:this.renderer.domElement,getGPUTextures:()=>{if(!e?.storageTextures?.readTarget)return null;let t=e.storageTextures.getReadTextures();return{color:this.renderer.backend.get(t.color).texture}},getExposure:()=>this._getEffectiveExposure(),getToneMapping:()=>this._getToneMapping(),getSaturation:()=>this._getSaturation()}),this.upscaler.enabled=B.enableUpscaler||!1,this._upscalerResChangedHandler=e=>this.dispatchEvent({type:`resolution_changed`,width:e.width,height:e.height}),this._upscalerStartHandler=()=>this.dispatchEvent({type:F.UPSCALING_START}),this._upscalerProgressHandler=e=>this.dispatchEvent({type:F.UPSCALING_PROGRESS,progress:e.progress}),this._upscalerEndHandler=()=>this.dispatchEvent({type:F.UPSCALING_END}),this.upscaler.addEventListener(`resolution_changed`,this._upscalerResChangedHandler),this.upscaler.addEventListener(`start`,this._upscalerStartHandler),this.upscaler.addEventListener(`progress`,this._upscalerProgressHandler),this.upscaler.addEventListener(`end`,this._upscalerEndHandler)}setDenoiserStrategy(e,t){let n=this._stages;switch(n.asvgf&&(n.asvgf.enabled=!1),n.variance&&(n.variance.enabled=!1),n.bilateralFilter&&(n.bilateralFilter.enabled=!1),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!1),this._clearDenoiserTextures(),e){case`asvgf`:n.asvgf.enabled=!0,n.variance&&(n.variance.enabled=!0),n.bilateralFilter&&(n.bilateralFilter.enabled=!0),n.asvgf.setTemporalEnabled?.(!0),this._applyASVGFPreset(t||`medium`);break;case`edgeaware`:n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!0);break}this._syncGBufferStages()}setASVGFEnabled(e,t){let n=this._stages;n.asvgf&&(n.asvgf.enabled=e),n.variance&&(n.variance.enabled=e),n.bilateralFilter&&(n.bilateralFilter.enabled=e),e&&(n.asvgf?.setTemporalEnabled?.(!0),this._applyASVGFPreset(t||`medium`)),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!e),this._syncGBufferStages()}applyASVGFPreset(e){this._applyASVGFPreset(e)}setAutoExposureEnabled(e,t){let n=this._stages;n.autoExposure&&(n.autoExposure.enabled=e,!e&&this.renderer&&(this.renderer.toneMappingExposure=t))}_syncGBufferStages(){let e=this._stages,t=e.normalDepth,n=e.motionVector,r=!!e.asvgf?.enabled,i=r||!!(e.edgeFilter?.enabled||e.bilateralFilter?.enabled);t&&(i&&!t.enabled&&t.reset(),t.enabled=i),n&&(r&&!n.enabled&&(n.matricesInitialized=!1,n.isFirstFrame=!0,n.frameCount=0),n.enabled=r),e.pathTracer?.setAuxGBufferEnabled?.(i||!!this.denoiser?.enabled);for(let r of[e.asvgf,e.variance,e.bilateralFilter,e.edgeFilter,t,n])r&&!r.enabled&&r.releaseGPUMemory?.()}_cleanupCompletionListener(){this._pendingStartUpscaler&&this.denoiser&&this.denoiser.removeEventListener(`end`,this._pendingStartUpscaler),this._pendingStartUpscaler=null}onRenderComplete({isStillComplete:e,context:t}){this._cleanupCompletionListener(),(this.denoiser?.enabled||this.upscaler?.enabled)&&this.denoiserCanvas&&(this.denoiserCanvas.style.display=`block`);let n=()=>{this._pendingStartUpscaler=null,e()&&this.upscaler?.enabled&&this.upscaler.start()};this.denoiser?.enabled?(this._pendingStartUpscaler=n,this.denoiser.addEventListener(`end`,n,{once:!0}),this.denoiser.start()):(this.upscaler?.enabled&&this._stages.compositor&&t&&this._stages.compositor.render(t),n())}abort(e){this._cleanupCompletionListener(),e&&(e.style.opacity=`1`),this.upscaler&&this.upscaler.abort(),this.denoiser&&(this.denoiser.enabled&&this.denoiser.abort(),this.denoiser.output&&(this.denoiser.output.style.display=`none`))}dispose(){this._cleanupCompletionListener(),this.denoiser&&=(this._denoiserStartHandler&&this.denoiser.removeEventListener(`start`,this._denoiserStartHandler),this._denoiserEndHandler&&this.denoiser.removeEventListener(`end`,this._denoiserEndHandler),this.denoiser.dispose(),null),this.upscaler&&=(this._upscalerResChangedHandler&&this.upscaler.removeEventListener(`resolution_changed`,this._upscalerResChangedHandler),this._upscalerStartHandler&&this.upscaler.removeEventListener(`start`,this._upscalerStartHandler),this._upscalerProgressHandler&&this.upscaler.removeEventListener(`progress`,this._upscalerProgressHandler),this._upscalerEndHandler&&this.upscaler.removeEventListener(`end`,this._upscalerEndHandler),this.upscaler.dispose(),null),this._denoiserStartHandler=null,this._denoiserEndHandler=null,this._upscalerResChangedHandler=null,this._upscalerStartHandler=null,this._upscalerProgressHandler=null,this._upscalerEndHandler=null,this.denoiserCanvas?.parentNode&&(this.denoiserCanvas.parentNode.removeChild(this.denoiserCanvas),this.denoiserCanvas=null)}setOverlayManager(e){this._overlayManager=e}setResetCallback(e){this._onReset=e}setSettings(e){this._settings=e}setASVGFParams(e){this._stages.asvgf?.updateParameters(e)}toggleASVGFHeatmap(e){this._stages.asvgf?.setHeatmapEnabled?.(e)}configureASVGFForMode(e){this._stages.asvgf&&(this._stages.asvgf.enabled=e.enabled,this._stages.variance&&(this._stages.variance.enabled=e.enabled),this._stages.bilateralFilter&&(this._stages.bilateralFilter.enabled=e.enabled),e.enabled&&this._stages.asvgf.updateParameters(e),this._syncGBufferStages())}setEdgeAwareParams(e){this._stages.edgeFilter?.updateUniforms(e)}setAutoExposureParams(e){this._stages.autoExposure?.updateParameters(e)}setOIDNEnabled(e){this.denoiser&&(this.denoiser.enabled=e),this._syncGBufferStages()}setOIDNQuality(e){this.denoiser?.updateQuality(e)}setTileHelperEnabled(e){this._setTileHelper(e)}setUpscalerEnabled(e){this.upscaler&&(this.upscaler.enabled=e)}setUpscalerScaleFactor(e){this.upscaler?.setScaleFactor(e)}setUpscalerQuality(e){this.upscaler?.setQuality(e)}setAutoExposure(e){this.setAutoExposureEnabled(e,this._getExposure()),this._onReset?.()}setStrategy(e,t){this.setDenoiserStrategy(e,t),this._onReset?.()}_setTileHelper(e){let t=this._overlayManager?.getHelper(`tiles`);t&&(t.enabled=e,e||t.hide())}_getEffectiveExposure(){return this._stages.autoExposure?.enabled?this.renderer.toneMappingExposure:this._getExposure()}_getToneMapping(){return this.renderer.toneMapping}_clearDenoiserTextures(){let e=this.pipeline?.context;e&&[`asvgf:output`,`asvgf:demodulated`,`asvgf:gradient`,`variance:output`,`bilateralFiltering:output`,`edgeFiltering:output`].forEach(t=>e.removeTexture(t))}_applyASVGFPreset(e){let t=U[e];t&&(this._stages.asvgf?.updateParameters(t),this._stages.bilateralFilter?.updateParameters(t),this._stages.variance&&t.varianceBoost!==void 0&&(this._stages.variance.varianceBoost.value=t.varianceBoost))}},Bl=class{constructor(){this.layer=`hud`,this.visible=!1,this._tileBounds=null,this._imageWidth=1,this._imageHeight=1,this.enabled=!0,this._borderColor=`rgba(255, 0, 0, 0.6)`,this._borderWidthRatio=1/540,this._borderWidthMin=1.5,this._borderWidthMax=4}setActiveTile(e){this._tileBounds=e}setRenderSize(e,t){this._imageWidth=e,this._imageHeight=t}render(e,t,n){if(!this._tileBounds)return;let r=this._tileBounds,i=t/this._imageWidth,a=n/this._imageHeight,o=r.x*i,s=r.y*a,c=r.width*i,l=r.height*a,u=Math.min(this._borderWidthMax,Math.max(this._borderWidthMin,Math.min(t,n)*this._borderWidthRatio));e.strokeStyle=this._borderColor,e.lineWidth=u,e.strokeRect(o,s,c,l)}show(){this.enabled&&(this.visible=!0)}hide(){this.visible=!1,this._tileBounds=null}dispose(){this.visible=!1}},Vl=class{constructor(e,i,a){this.layer=`scene`,this.visible=!0,this._outlineNode=(0,h.outline)(i,a,{selectedObjects:[],edgeThickness:(0,n.uniform)(1),edgeGlow:(0,n.uniform)(0)}),this._displayWidth=1,this._displayHeight=1;let o=this._outlineNode.setSize.bind(this._outlineNode);this._outlineNode.setSize=()=>{o(this._displayWidth,this._displayHeight)};let s=(0,n.uniform)(3),c=(0,n.uniform)(new r.Color(16777215)),l=(0,n.uniform)(new r.Color(1640965)),{visibleEdge:u,hiddenEdge:d}=this._outlineNode,f=u.mul(c).add(d.mul(l)).mul(s);this._material=new t.MeshBasicNodeMaterial,this._material.colorNode=(0,n.vec4)(f,1),this._material.blending=r.AdditiveBlending,this._material.toneMapped=!1,this._material.depthTest=!1,this._material.depthWrite=!1,this._quad=new t.QuadMesh(this._material)}setSelectedObjects(e){this._outlineNode.selectedObjects=e}render(e){if(this._outlineNode.selectedObjects.length===0)return;let t=e.autoClear;e.autoClear=!1,e.setRenderTarget(null),this._quad.render(e),e.autoClear=t}setSize(e,t){this._displayWidth=e,this._displayHeight=t,this._outlineNode.setSize(e,t)}show(){this.visible=!0}hide(){this.visible=!1}dispose(){this.visible=!1,this._outlineNode?.dispose(),this._material?.dispose(),this._quad=null}},Hl=class{constructor(e,t){this.renderer=e,this.camera=t,this._helpers=new Map,this._hudCanvas=document.createElement(`canvas`),this._hudCanvas.style.cssText=`position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;`,this._hudCtx=this._hudCanvas.getContext(`2d`),this._helperScene=null}setHelperScene(e){this._helperScene=e}getHUDCanvas(){return this._hudCanvas}mount(e){!e||this._hudCanvas.parentElement===e||e.appendChild(this._hudCanvas)}setupDefaultHelpers({helperScene:e,meshScene:t,pipeline:n,denoisingManager:r,app:i,renderWidth:a,renderHeight:o}){this.setHelperScene(e);let s=new Bl;this.register(`tiles`,s),s.setRenderSize(a||1,o||1),i.addEventListener(`resolution_changed`,e=>{s.setRenderSize(e.width,e.height)}),n.eventBus.on(`pipeline:reset`,()=>s.hide()),this._wireDenoiserTileEvents(s,r);let c=new Vl(this.renderer,t,this.camera);this.register(`outline`,c)}_wireDenoiserTileEvents(e,t){let n=[t?.denoiser,t?.upscaler];for(let t of n)t&&(t.addEventListener(`tileProgress`,t=>{t.tile&&(e.setRenderSize(t.imageWidth,t.imageHeight),e.setActiveTile(t.tile),e.show(),this.refreshHUD())}),t.addEventListener(`end`,()=>{e.hide(),this.refreshHUD()}))}register(e,t){this._helpers.has(e)&&(console.warn(`OverlayManager: helper "${e}" already registered — replacing.`),this._helpers.get(e).dispose?.()),this._helpers.set(e,t)}unregister(e){let t=this._helpers.get(e);t&&(t.dispose?.(),this._helpers.delete(e))}show(e){this._helpers.get(e)?.show()}hide(e){this._helpers.get(e)?.hide()}toggle(e){let t=this._helpers.get(e);t&&(t.visible?t.hide():t.show())}getHelper(e){return this._helpers.get(e)??null}isVisible(e){return this._helpers.get(e)?.visible??!1}showAll(){for(let e of this._helpers.values())e.show()}hideAll(){for(let e of this._helpers.values())e.hide()}render(){this._helperScene&&this._helperScene.render(this.renderer,this.camera);for(let e of this._helpers.values())e.visible&&e.layer===`scene`&&e.render&&e.render(this.renderer,this.camera);this.refreshHUD()}setSize(e,t){for(let n of this._helpers.values())n.setSize?.(e,t)}refreshHUD(){let e=this._hudCanvas,t=this._hudCtx,n=!1;for(let e of this._helpers.values())if(e.visible&&e.layer===`hud`&&e.render){n=!0;break}if(!n){e.style.display!==`none`&&(e.style.display=`none`);return}let r=window.devicePixelRatio||1,i=e.clientWidth,a=e.clientHeight,o=Math.round(i*r),s=Math.round(a*r);(e.width!==o||e.height!==s)&&(e.width=o,e.height=s),t.clearRect(0,0,o,s),t.save(),t.scale(r,r);for(let e of this._helpers.values())e.visible&&e.layer===`hud`&&e.render&&e.render(t,i,a);t.restore(),e.style.display!==``&&(e.style.display=``)}dispose(){for(let e of this._helpers.values())e.dispose?.();this._helpers.clear(),this._hudCanvas.parentElement&&this._hudCanvas.parentElement.removeChild(this._hudCanvas)}},Ul=class extends r.EventDispatcher{constructor(){super(),this.mixer=null,this.timer=new r.Timer,this.actions=[],this.isPlaying=!1,this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._tempVec=new r.Vector3,this._skinnedCache=null,this._clipsCache=null,this._savedTimeScale=1,this.onFinished=null,this.wakeCallback=null}init(e,t,n,i){if(this.dispose(),!i||i.length===0)return;this._scene=e,this._mixerRoot=t,this._meshes=n,this.mixer=new r.AnimationMixer(t);let a=i.map(e=>this.mixer.clipAction(e)),o=(e,t)=>e.name===t||e.getObjectByName(t)!==void 0;!a.some(e=>e.getClip().tracks.some(e=>{let n=e.name.split(`.`)[0];return o(t,n)}))&&t!==e&&(console.log(`[AnimationManager] Tracks did not resolve from model root, retrying with scene root`),this.mixer=new r.AnimationMixer(e),this._mixerRoot=e,a=i.map(e=>this.mixer.clipAction(e))),this.actions=a,this.mixer.addEventListener(`finished`,()=>{this.isPlaying=!1,this.timer.reset(),this.onFinished&&this.onFinished()}),this._meshTriRanges=[],this._skinnedCache=[];let s=0;for(let e of n){let t=e.geometry,n=t.attributes.position,r=t.index?t.index.array:null,i=r?r.length/3:n.count/3,a=n.count;this._meshTriRanges.push({start:s,count:i,uniqueVerts:a,indices:r}),this._skinnedCache.push(new Float32Array(a*3)),s+=i}this._posBuffer=new Float32Array(s*9);let c=n.filter(e=>e.isSkinnedMesh).length;console.debug(`[AnimationManager] Init: ${i.length} clips, ${n.length} meshes (${c} skinned), ${s} triangles`)}play(e=0){if(!(!this.mixer||this.actions.length===0)){if(this.mixer.stopAllAction(),e===-1)for(let e of this.actions)e.play();else e>=0&&e<this.actions.length&&this.actions[e].play();this.timer.reset(),this.isPlaying=!0,this.wakeCallback?.(),this.dispatchEvent({type:F.ANIMATION_STARTED})}}pause(){this.mixer&&(this.mixer.timeScale=0,this.timer.reset(),this.isPlaying=!1,this.dispatchEvent({type:F.ANIMATION_PAUSED}))}resume(){this.mixer&&(this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!0,this.wakeCallback?.(),this.dispatchEvent({type:F.ANIMATION_STARTED}))}stop(){this.mixer&&(this.mixer.stopAllAction(),this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!1,this.dispatchEvent({type:F.ANIMATION_STOPPED}))}setSpeed(e){this._savedTimeScale=e,this.mixer&&this.isPlaying&&(this.mixer.timeScale=e)}setLoop(e){let t=e?r.LoopRepeat:r.LoopOnce;for(let n of this.actions)n.setLoop(t),n.clampWhenFinished=!e}seekTo(e,t=0){if(!this.mixer||this.actions.length===0)return null;if(this.mixer.stopAllAction(),t===-1)for(let e of this.actions)e.play();else t>=0&&t<this.actions.length&&this.actions[t].play();this.mixer.setTime(e);for(let e of this.actions)e.isRunning()&&(e.paused=!0);return this._computePositions(),this._posBuffer}get currentTime(){return this.mixer?.time||0}update(){if(!this.isPlaying||!this.mixer)return null;this.timer.update();let e=this.timer.getDelta();return this.mixer.update(e),this._computePositions(),this._posBuffer}_computePositions(){let e=this._tempVec,t=this._posBuffer;this._mixerRoot.updateMatrixWorld(!0);for(let n=0;n<this._meshes.length;n++){let r=this._meshes[n],{start:i,count:a,uniqueVerts:o,indices:s}=this._meshTriRanges[n],c=this._skinnedCache[n],l=r.matrixWorld;for(let t=0;t<o;t++)r.getVertexPosition(t,e),e.applyMatrix4(l),c[t*3]=e.x,c[t*3+1]=e.y,c[t*3+2]=e.z;if(s)for(let e=0;e<a;e++){let n=e*3,r=s[n]*3,a=s[n+1]*3,o=s[n+2]*3,l=(i+e)*9;t[l]=c[r],t[l+1]=c[r+1],t[l+2]=c[r+2],t[l+3]=c[a],t[l+4]=c[a+1],t[l+5]=c[a+2],t[l+6]=c[o],t[l+7]=c[o+1],t[l+8]=c[o+2]}else for(let e=0;e<a;e++){let n=e*3*3,r=(e*3+1)*3,a=(e*3+2)*3,o=(i+e)*9;t[o]=c[n],t[o+1]=c[n+1],t[o+2]=c[n+2],t[o+3]=c[r],t[o+4]=c[r+1],t[o+5]=c[r+2],t[o+6]=c[a],t[o+7]=c[a+1],t[o+8]=c[a+2]}}}get hasAnimations(){return this.actions.length>0}get clips(){return this._clipsCache||=this.actions.map((e,t)=>{let n=e.getClip();return{index:t,name:n.name||`Clip ${t}`,duration:n.duration}}),this._clipsCache}dispose(){this.mixer&&=(this.mixer.stopAllAction(),this.mixer.uncacheRoot(this._mixerRoot),null),this.actions=[],this.isPlaying=!1,this.timer.reset(),this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._skinnedCache=null,this._clipsCache=null}},Wl=class{constructor({camera:e,canvas:t,orbitControls:n,app:i}){this._app=i,this._orbitControls=n,this._camera=e,this._controls=new g.TransformControls(e,t),this._gizmoScene=new r.Scene,this._gizmoScene.add(this._controls.getHelper()),this._attached=null,this._isDragging=!1,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._normalBuffer=null,this._skinnedCache=null,this._normalCache=null,this._tempVec=new r.Vector3,this._normalMatrix=new r.Matrix3,this._refitInFlight=!1,this._baselineComputed=!1,this._onDraggingChanged=this._onDraggingChanged.bind(this),this._onObjectChange=this._onObjectChange.bind(this),this._controls.addEventListener(`dragging-changed`,this._onDraggingChanged),this._controls.addEventListener(`objectChange`,this._onObjectChange)}setMeshData(e){this._meshes=e,this._meshTriRanges=[],this._skinnedCache=[],this._normalCache=[];let t=0;for(let n of e){let e=n.geometry,r=e.attributes.position,i=e.index?e.index.array:null,a=i?i.length/3:r.count/3,o=r.count;this._meshTriRanges.push({start:t,count:a,uniqueVerts:o,indices:i}),this._skinnedCache.push(new Float32Array(o*3)),this._normalCache.push(new Float32Array(o*3)),t+=a}this._posBuffer=new Float32Array(t*9),this._normalBuffer=new Float32Array(t*9),this._baselineComputed=!1}attach(e){this._attached!==e&&(this._controls.attach(e),this._attached=e)}detach(){this._attached&&=(this._controls.detach(),null)}setMode(e){this._controls.setMode(e),this._app?.dispatchEvent({type:F.TRANSFORM_MODE_CHANGED,mode:e})}setSpace(e){this._controls.setSpace(e)}get isDragging(){return this._isDragging}get attachedObject(){return this._attached}get controls(){return this._controls}render(e){if(!this._attached)return;let t=e.autoClear;e.autoClear=!1,e.clearDepth(),e.setRenderTarget(null),e.render(this._gizmoScene,this._camera),e.autoClear=t}_onDraggingChanged(e){this._isDragging=e.value,this._orbitControls&&(this._orbitControls.enabled=!e.value),e.value?this._app.dispatchEvent({type:F.OBJECT_TRANSFORM_START}):(this._recomputeAndRefit(),this._app.dispatchEvent({type:F.OBJECT_TRANSFORM_END}))}_onObjectChange(){this._app.needsReset=!0,this._app.wake()}_recomputeAndRefit(){if(!this._meshes||!this._posBuffer||this._refitInFlight||!this._attached)return;this._attached.updateMatrixWorld(!0);let e=this._findAffectedMeshIndices(this._attached);if(e.length!==0){if(!this._baselineComputed)this._computeAllPositions(),this._baselineComputed=!0;else for(let t of e)this._computeMeshPositions(t);this._refitInFlight=!0;try{this._app.refitBLASes(e,this._posBuffer,this._normalBuffer)}catch(e){console.error(`Transform refit error:`,e)}finally{this._refitInFlight=!1}}}_findAffectedMeshIndices(e){let t=[];for(let n=0;n<this._meshes.length;n++){let r=this._meshes[n];(r===e||this._isDescendantOf(r,e))&&t.push(n)}return t}_isDescendantOf(e,t){let n=e.parent;for(;n;){if(n===t)return!0;n=n.parent}return!1}_computeAllPositions(){for(let e=0;e<this._meshes.length;e++)this._computeMeshPositions(e)}_computeMeshPositions(e){let t=this._meshes[e],{start:n,count:r,uniqueVerts:i,indices:a}=this._meshTriRanges[e],o=this._skinnedCache[e],s=this._normalCache[e],c=this._tempVec,l=this._posBuffer,u=this._normalBuffer;t.updateMatrixWorld(!0);let d=t.matrixWorld;this._normalMatrix.getNormalMatrix(d);let f=this._normalMatrix.elements,p=t.geometry.attributes.normal;for(let e=0;e<i;e++)if(t.getVertexPosition(e,c),c.applyMatrix4(d),o[e*3]=c.x,o[e*3+1]=c.y,o[e*3+2]=c.z,p){let t=p.getX(e),n=p.getY(e),r=p.getZ(e);s[e*3]=f[0]*t+f[3]*n+f[6]*r,s[e*3+1]=f[1]*t+f[4]*n+f[7]*r,s[e*3+2]=f[2]*t+f[5]*n+f[8]*r}if(a)for(let e=0;e<r;e++){let t=e*3,r=a[t]*3,i=a[t+1]*3,c=a[t+2]*3,d=(n+e)*9;l[d]=o[r],l[d+1]=o[r+1],l[d+2]=o[r+2],l[d+3]=o[i],l[d+4]=o[i+1],l[d+5]=o[i+2],l[d+6]=o[c],l[d+7]=o[c+1],l[d+8]=o[c+2],u[d]=s[r],u[d+1]=s[r+1],u[d+2]=s[r+2],u[d+3]=s[i],u[d+4]=s[i+1],u[d+5]=s[i+2],u[d+6]=s[c],u[d+7]=s[c+1],u[d+8]=s[c+2]}else for(let e=0;e<r;e++){let t=e*3*3,r=(e*3+1)*3,i=(e*3+2)*3,a=(n+e)*9;l[a]=o[t],l[a+1]=o[t+1],l[a+2]=o[t+2],l[a+3]=o[r],l[a+4]=o[r+1],l[a+5]=o[r+2],l[a+6]=o[i],l[a+7]=o[i+1],l[a+8]=o[i+2],u[a]=s[t],u[a+1]=s[t+1],u[a+2]=s[t+2],u[a+3]=s[r],u[a+4]=s[r+1],u[a+5]=s[r+2],u[a+6]=s[i],u[a+7]=s[i+1],u[a+8]=s[i+2]}}dispose(){this._controls.removeEventListener(`dragging-changed`,this._onDraggingChanged),this._controls.removeEventListener(`objectChange`,this._onObjectChange),this.detach(),this._gizmoScene.remove(this._controls.getHelper()),this._controls.dispose(),this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._normalBuffer=null,this._skinnedCache=null,this._normalCache=null,this._baselineComputed=!1,this._app=null,this._orbitControls=null,this._camera=null,this._controls=null,this._gizmoScene=null}},Gl=new WeakMap,Kl=class extends r.EventDispatcher{constructor(e,t={}){super();try{Gl.get(e)?.dispose()}catch(e){console.warn(`PathTracerApp: prior canvas owner dispose failed`,e)}Gl.set(e,this),this.canvas=e,this._autoResize=t.autoResize!==!1,this._container=t.container||null,this.settings=new Xc(B),this.renderer=null,this.scene=null,this.meshScene=null,this._sceneHelpers=null,this.assetLoader=null,this._sdf=null,this._animRefitInFlight=!1,this._maxTextureSize=B.maxTextureSize,this.pipeline=null,this.stages={},this.cameraManager=null,this.lightManager=null,this.goboManager=null,this.iesManager=null,this.denoisingManager=null,this.overlayManager=null,this.interactionManager=null,this.transformManager=null,this.animationManager=new Ul,this.environmentManager=null,this.isInitialized=!1,this.pauseRendering=!1,this.pathTracerEnabled=!0,this.animationManagerId=null,this.needsReset=!1,this._loadingInProgress=!1,this._needsDisplayRefresh=!1,this._paused=!1,this.completion=new dc,this._resizeDebounceTimer=null,this._trackedListeners=[],this._disposed=!1,this._deviceLost=!1}_addTrackedListener(e,t,n){e&&(e.addEventListener(t,n),this._trackedListeners.push({target:e,type:t,handler:n}))}_removeTrackedListeners(){for(let{target:e,type:t,handler:n}of this._trackedListeners)try{e.removeEventListener(t,n)}catch(e){console.warn(`PathTracerApp: failed to remove listener`,t,e)}this._trackedListeners.length=0}async init(){return await this._initRenderer(),this._initCameraManager(),this._initScenes(),this._initAssetPipeline(),this._initPipeline(),this._initManagers(),this._wireEvents(),this.stages.pathTracer.setTriangleData(new Float32Array(32),0),this.stages.pathTracer.setBVHData(new Float32Array(16)),this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)),this.stages.pathTracer.setupMaterial(),this.isInitialized=!0,console.log(`WebGPU Path Tracer App initialized`),this}animate(){if(!this._deviceLost){if(this.animationManagerId=requestAnimationFrame(()=>this.animate()),this._loadingInProgress||this._sdf?.isProcessing){this.dispatchEvent({type:F.FRAME});return}if(this.cameraManager.controls&&this.cameraManager.controls.update(),this.animationManager?.isPlaying&&!this._animRefitInFlight){let e=this.animationManager.update();e&&(this._animRefitInFlight=!0,this.refitBVH(e).catch(e=>console.error(`Animation refit error:`,e)).finally(()=>{this._animRefitInFlight=!1}))}if(this.needsReset&&=(this.reset(!0),!1),this.cameraManager.camera.updateMatrixWorld(),!this.pathTracerEnabled){this.renderer.render(this.meshScene,this.cameraManager.camera),this._renderHelperOverlay();return}if(!this.pauseRendering){if(this.cameraManager.updateAutoFocus(),this.stages.pathTracer?.isReady){if(this.stages.pathTracer.isComplete&&this.completion.renderCompleteDispatched){this._needsDisplayRefresh&&(this._needsDisplayRefresh=!1,this.stages.compositor.render(this.pipeline.context),this._renderHelperOverlay()),this.stopAnimation();return}this.pipeline.render(),this.stages.pathTracer.isComplete||this.completion.updateTime(),this._ensureVRAMWiring();let e=this.stages.pathTracer?.vramTracker,t=this.stages.pathTracer?.frameCount??0;e&&(t<=1||t%30==0)&&e.measure(),Ce({timeElapsed:this.completion.timeElapsed,samples:L(this.stages.pathTracer),memoryUsed:e?.current??0,memoryPeak:e?.peak??0}),this.completion.isTimeLimitReached(this.settings.get(`renderLimitMode`),this.settings.get(`renderTimeLimit`))&&(this.stages.pathTracer.isComplete=!0),this.stages.pathTracer.isComplete&&this.completion.markComplete()&&(this.denoisingManager.onRenderComplete({isStillComplete:()=>this.completion.renderCompleteDispatched,context:this.pipeline?.context}),this.dispatchEvent({type:`RenderComplete`}),this.dispatchEvent({type:F.RENDER_COMPLETE}))}this._renderHelperOverlay(),this.dispatchEvent({type:F.FRAME})}}}stopAnimation(){this.animationManagerId&&=(cancelAnimationFrame(this.animationManagerId),null)}_handleDeviceLost(e){this._deviceLost||(this._deviceLost=!0,console.error(`WebGPU device lost (${e?.reason||`unknown`}): ${e?.message||``}`),this.stopAnimation(),this.dispatchEvent({type:F.DEVICE_LOST,reason:e?.reason,message:e?.message}))}wake(){this._deviceLost||!this.animationManagerId&&this.isInitialized&&!this._paused&&this.animate()}pause(){this._paused=!0,this.stopAnimation()}resume(){this._paused=!1,this.animationManagerId||this.animate()}reset(e=!1){if(this.pipeline&&(this.pipeline.reset(),e||this.pipeline.eventBus.emit(`asvgf:reset`)),this.denoisingManager?.abort(this.canvas),this.denoisingManager?.restoreBaseResolution()){let e=this.denoisingManager._lastRenderWidth,t=this.denoisingManager._lastRenderHeight;this.dispatchEvent({type:`resolution_changed`,width:e,height:t})}this.completion.reset(),this.wake(),this.dispatchEvent({type:`RenderReset`}),this.dispatchEvent({type:F.RENDER_RESET})}dispose(){if(!this._disposed){if(this._disposed=!0,this.dispatchEvent({type:F.DISPOSE}),this.stopAnimation(),clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=null,this._removeTrackedListeners(),xe(null),this.interactionManager?.deselect?.(),this.transformManager?.detach?.(),this.animationManager?.dispose(),this.transformManager?.dispose(),this.overlayManager?.dispose(),this.lightManager?.dispose(),this.goboManager?.dispose(),this.iesManager?.dispose(),this.denoisingManager?.dispose(),this.interactionManager?.dispose(),this.cameraManager?.dispose(),this.pipeline?.dispose(),this._sdf?.dispose(),this._sdf=null,this.assetLoader?.dispose(),this.assetLoader=null,this.meshScene){this.meshScene.environment?.dispose(),this.meshScene.environment=null;for(let e of[...this.meshScene.children])R(e);this.meshScene.clear(),this.meshScene=null}this._sceneHelpers?.clear(),this._sceneHelpers=null,this.scene?.clear(),this.scene=null,this.renderer?._canvasTarget&&this.renderer._onCanvasTargetResize&&this.renderer._canvasTarget.removeEventListener(`resize`,this.renderer._onCanvasTargetResize);try{let e=(0,n.texture)().value,t=(0,n.cubeTexture)().value;e?._listeners?.dispose&&(e._listeners.dispose.length=0),t?._listeners?.dispose&&(t._listeners.dispose.length=0)}catch(e){console.warn(`PathTracerApp: failed to clear TSL texture singleton listeners`,e)}this.renderer?.dispose(),this.renderer&&(this.renderer._canvasTarget=null),this.renderer=null,this.stages={},this.isInitialized=!1}}unloadScene(){if(this.isInitialized){if(this._loadingInProgress)throw Error(`PathTracerApp.unloadScene: cannot unload while a load is in progress`);this._disposed||(this.animationManager?.dispose(),this._animRefitInFlight=!1,this.interactionManager?.deselect(),this.transformManager?.detach?.(),this.assetLoader?.releaseTargetModel(),this.lightManager?.clearLights?.(),this.stages.pathTracer&&(this.stages.pathTracer.setTriangleData(new Float32Array(32),0),this.stages.pathTracer.setBVHData(new Float32Array(16)),this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)),this.stages.pathTracer.setEmissiveTriangleData?.(new Float32Array,0,0),this.stages.pathTracer.setupMaterial()),this.reset(),this.dispatchEvent({type:`SceneUnloaded`}))}}async loadModel(e){await this._loadWithSceneRebuild(()=>this.assetLoader.loadModel(e),{type:`ModelLoaded`,url:e})}async loadObject3D(e,t=`object3d`){await this._loadWithSceneRebuild(()=>this.assetLoader.loadObject3D(e,t),{type:`Object3DLoaded`,name:t})}async loadEnvironment(e){if(this._loadingInProgress)throw Error(`PathTracerApp.loadEnvironment: another load is already in progress`);this._loadingInProgress=!0;try{await this.assetLoader.loadEnvironment(e);let t=this.meshScene.environment;t&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(t),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),this.dispatchEvent({type:`EnvironmentLoaded`,url:e})}finally{this._loadingInProgress=!1}}async loadExampleModels(e,t){await this._loadWithSceneRebuild(()=>this.assetLoader.loadExampleModels(e,t),{type:`ModelLoaded`,index:e})}cancelLoad(){this._loadingInProgress&&this.assetLoader?.cancelActiveLoad()}async setMaxTextureSize(e,{reprocess:t=!0}={}){let n=this._maxTextureSize;if(this._maxTextureSize=this._sdf?.setMaxTextureSize(e)??e,typeof this.stages?.pathTracer?.sdfs?.setMaxTextureSize==`function`&&this.stages.pathTracer.sdfs.setMaxTextureSize(this._maxTextureSize),t&&this._maxTextureSize!==n&&this._sdf?.triangleData&&!this._loadingInProgress){this._loadingInProgress=!0;try{await this.loadSceneData(),this.reset(),this.dispatchEvent({type:`TexturesReprocessed`,maxTextureSize:this._maxTextureSize})}finally{this._loadingInProgress=!1}}}async _loadWithSceneRebuild(e,t){if(this._loadingInProgress)throw Error(`PathTracerApp: another load is already in progress`);this._loadingInProgress=!0;try{await e(),this._clearAppendedModels(),this._syncControlsAfterLoad(),await this.loadSceneData(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),this.cameraManager.currentCameraIndex=0,this.dispatchEvent(t),this.dispatchEvent({type:`CamerasUpdated`,cameras:this.cameraManager.cameras,cameraNames:this.cameraManager.getCameraNames()})}finally{this._loadingInProgress=!1}}async loadSceneData(){this._preserveSelectionOnRebuild||this.interactionManager?.deselect(),this.animationManager.dispose(),this._animRefitInFlight=!1,this._tagPrimarySceneObject();let e=new Wi(`loadSceneData`),t=this.meshScene.environment,n=null;if(t?.image?.data&&(e.start(`Environment CDF build (worker)`),this.stages.pathTracer.scene.environment=t,n=this.stages.pathTracer.environment.buildEnvironmentCDF().then(()=>e.end(`Environment CDF build (worker)`))),e.start(`BVH build (SceneProcessor)`),this._sdf.setMaxTextureSize(this._maxTextureSize),await this._sdf.buildBVH(this.meshScene),e.end(`BVH build (SceneProcessor)`),I({status:`Transferring data to GPU...`,progress:86}),await new Promise(e=>setTimeout(e,0)),e.start(`GPU data transfer`),!this._sdf.uploadToPathTracer(this.stages.pathTracer,this.lightManager,this.meshScene,t))return!1;this.stages.pathTracer._meshRefs=this.stages.pathTracer._collectMeshRefs(this.meshScene),this.stages.pathTracer.setMeshVisibilityData(this.stages.pathTracer._meshRefs),e.end(`GPU data transfer`),I({status:`Compiling shaders...`,progress:90}),await new Promise(e=>setTimeout(e,0)),e.start(`Material setup (TSL compile)`),this.stages.pathTracer.setupMaterial(),e.end(`Material setup (TSL compile)`),e.start(`Pipeline precompile`);try{await this.renderer.compileAsync(this.meshScene,this.cameraManager.camera)}catch(e){console.warn(`PathTracerApp: raster fallback precompile failed`,e)}e.end(`Pipeline precompile`),n&&(I({status:`Finalizing environment map...`,progress:95}),await n,this.stages.pathTracer.environment.applyCDFResults());let r=this.getSceneMinY();return this.settings.set(`groundProjectionLevel`,r,{reset:!1}),this.settings.set(`groundCatcherHeight`,r,{reset:!1}),e.start(`Apply settings`),this.settings.applyAll(),this.stages.compositor.setTransparentBackground(this.settings.get(`transparentBackground`)),e.end(`Apply settings`),e.print(),Se(),this._initAnimationAndTransforms(),this.dispatchEvent({type:`SceneRebuild`}),!0}_tagPrimarySceneObject(){let e=this.assetLoader?.targetModel;e&&(e.userData.__rayzeeSceneObject=!0,e.userData.__rayzeeExternal=e===this.assetLoader._externalModel)}_clearAppendedModels(){let e=this.meshScene;if(!e)return;let t=this.assetLoader?.floorPlane,n=this.assetLoader?.targetModel;for(let r of[...e.children])r===t||r===n||r.userData?.__rayzeeSceneObject&&this.assetLoader.removeModelRoot(r,{external:!!r.userData.__rayzeeExternal})}async _finishRebuildNoReframe(e){await this.loadSceneData(),this._recalibrateControlLimits(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),e&&this.dispatchEvent(e)}async addModel(e,{name:t}={}){if(this._loadingInProgress)throw Error(`PathTracerApp.addModel: another load is already in progress`);this._loadingInProgress=!0,this._preserveSelectionOnRebuild=!0;try{let{root:n}=await this.assetLoader.appendModel(e);return n.userData.__rayzeeSceneObject=!0,n.userData.__rayzeeExternal=!1,t&&(n.userData.__rayzeeName=t),await this._finishRebuildNoReframe({type:`ModelAdded`,url:e,id:n.uuid}),n.uuid}finally{this._preserveSelectionOnRebuild=!1,this._loadingInProgress=!1}}async addModelFromObject3D(e,{name:t}={}){if(this._loadingInProgress)throw Error(`PathTracerApp.addModelFromObject3D: another load is already in progress`);this._loadingInProgress=!0,this._preserveSelectionOnRebuild=!0;try{let{root:n}=this.assetLoader.appendObject3D(e,t||`object3d`);return n.userData.__rayzeeSceneObject=!0,n.userData.__rayzeeExternal=!0,t&&(n.userData.__rayzeeName=t),await this._finishRebuildNoReframe({type:`ModelAdded`,id:n.uuid}),n.uuid}finally{this._preserveSelectionOnRebuild=!1,this._loadingInProgress=!1}}async removeSceneObject(e){let t=this.meshScene;if(!t)return!1;let n=this.assetLoader?.floorPlane;if(n&&n.uuid===e)return!1;let r=t.children.find(t=>t.uuid===e&&t.userData?.__rayzeeSceneObject);if(!r)return!1;if(this._loadingInProgress)throw Error(`PathTracerApp.removeSceneObject: another load is already in progress`);this._loadingInProgress=!0;try{return this.interactionManager?.deselect(),this.transformManager?.detach?.(),r===this.assetLoader.targetModel?this.assetLoader.releaseTargetModel():this.assetLoader.removeModelRoot(r,{external:!!r.userData.__rayzeeExternal}),await this._finishRebuildNoReframe({type:`SceneObjectRemoved`,id:e}),!0}finally{this._loadingInProgress=!1}}setSceneObjectVisibility(e,t){return this.setMeshVisibilityByUuid(e,t)}async refitBVH(e,t){let n=await this._sdf.refitBVH(e,t);return this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset(),n}refitBLASes(e,t,n){let r=this._sdf.refitBLASes(e,t,n),{triRanges:i,bvhRanges:a}=this._sdf.computeBLASDirtyRanges(e);return this.stages.pathTracer.updateBufferRanges(i,a),this.reset(),this._sdf.scheduleBackgroundRebuild(e,()=>{this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset()}),r}_isRenderSizeSupported(e,t){return e>2048||t>2048?(console.warn(`[Rayzee] Render resolution ${e}×${t} exceeds the ${H}px limit (compute storage textures are pre-allocated at ${H}px). Ignoring resize — use a resolution ≤ ${H}.`),!1):!0}onResize(){let e=this.canvas.clientWidth,t=this.canvas.clientHeight;if(e===0||t===0||!this._isRenderSizeSupported(e,t))return;this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this.cameraManager.camera.aspect=e/t,this.cameraManager.camera.updateProjectionMatrix();let n=window.devicePixelRatio||1;this.overlayManager?.setSize(Math.round(e*n),Math.round(t*n));let r=this.denoisingManager?._lastRenderWidth??0,i=this.denoisingManager?._lastRenderHeight??0;e===r&&t===i||(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{this._applyRenderResize(e,t)},300))}_applyRenderResize(e,t){this._isRenderSizeSupported(e,t)&&(this.pipeline?.setSize(e,t),this.denoisingManager?.setRenderSize(e,t),this.needsReset=!0,this.dispatchEvent({type:`resolution_changed`,width:e,height:t}))}setCanvasSize(e,t){e===0||t===0||this._isRenderSizeSupported(e,t)&&(this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this.cameraManager.camera.aspect=e/t,this.cameraManager.camera.updateProjectionMatrix(),clearTimeout(this._resizeDebounceTimer),this._applyRenderResize(e,t))}configureForMode(e,t={}){let n=e===`production`,r=n?Re:ze;this.cameraManager.controls.enabled=!n,this.settings.setMany({maxSamples:r.maxSamples,maxBounces:r.bounces,transmissiveBounces:r.transmissiveBounces,maxSubsurfaceSteps:r.maxSubsurfaceSteps},{silent:!0}),this.stages.pathTracer?.setUniform(`renderMode`,parseInt(r.renderMode)),this.stages.pathTracer?.setUniform(`enableAlphaShadows`,r.enableAlphaShadows??!1),this.stages.pathTracer?.updateCompletionThreshold?.();let i=this.denoisingManager?.denoiser;if(i&&(i.abort(),i.enabled=r.enableOIDN,i.updateQuality(r.oidnQuality)),this.denoisingManager?._syncGBufferStages?.(),this.denoisingManager?.upscaler?.abort(),t.canvasWidth&&t.canvasHeight&&this.setCanvasSize(t.canvasWidth,t.canvasHeight),this.needsReset=!1,this.pauseRendering=!1,n){let e=this.stages.pathTracer?.vramTracker;e&&(e.measure(),e.resetPeak())}this.reset()}refreshFrame(){this._needsDisplayRefresh=!0,this.wake()}getCanvas(){if(!this.renderer?.domElement)return null;let e=this.denoisingManager;return(e?.denoiser?.enabled||e?.upscaler?.enabled)&&e?.denoiserCanvas&&this.stages.pathTracer?.isComplete?e.denoiserCanvas:(this.stages.compositor&&this.pipeline?.context&&this.stages.compositor.render(this.pipeline.context),this.renderer.domElement)}screenshot({type:e=`image/png`,quality:t}={}){let n=this.getCanvas();return n?new Promise(r=>n.toBlob(r,e,t)):Promise.resolve(null)}getStatistics(){try{return this._sdf?.getStatistics?.()??null}catch{return null}}get isLoading(){return this._loadingInProgress}isComplete(){return this.stages.pathTracer?.isComplete??!1}getFrameCount(){return this.stages.pathTracer?.frameCount||0}get vram(){return this.stages.pathTracer?.vramTracker??null}getMemoryInfo(){return this.stages.pathTracer?.vramTracker?.measure()??{current:0,peak:0,byCategory:{}}}_ensureVRAMWiring(){if(this._vramWired)return;let e=this.stages.pathTracer?.vramTracker;if(!e)return;e.register(`stages`,()=>this._collectStageTextures());let t=()=>e.measure();this._addTrackedListener(this,`SceneRebuild`,t),this._addTrackedListener(this,`EnvironmentLoaded`,t),this._addTrackedListener(this,`resolution_changed`,t),this._vramWired=!0}_collectStageTextures(){let e=[],t=this.stages||{},n=t.pathTracer;for(let r in t){let i=t[r];if(!(!i||i===n||typeof i!=`object`))for(let t in i){let n=i[t];n&&(n.isTexture||n.isRenderTarget)&&e.push(n)}}return e}getSceneMinY(){if(!this.meshScene)return 0;let e=new r.Box3().setFromObject(this.meshScene);return Number.isFinite(e.min.y)?e.min.y:0}setMaterialProperty(e,t,n){if(this.stages.pathTracer?.materialData.updateMaterialProperty(e,t,n),[`emissive`,`emissiveIntensity`].includes(t)&&this.stages.pathTracer?.enableEmissiveTriangleSampling?.value){let r=this._sdf.updateMaterialEmissive(e,t,n);r&&(this.stages.pathTracer.setEmissiveTriangleData(r.rawData,r.emissiveCount,r.totalPower,r.bitTrailMap),r.lightBVHNodeData&&this.stages.pathTracer.setLightBVHData(r.lightBVHNodeData,r.lightBVHNodeCount))}this.reset()}setMeshVisibility(e,t){this.stages.pathTracer?.updateMeshVisibility(e,t),this.reset()}updateAllMeshVisibility(){this.stages.pathTracer?.updateAllMeshVisibility(),this.reset()}getScene(){return this.meshScene||this.scene}setMeshVisibilityByUuid(e,t){let n=this.getScene()?.getObjectByProperty(`uuid`,e);if(!n)return null;let r=typeof t==`function`?!!t(n.visible):!!t;return n.visible=r,this.updateAllMeshVisibility(),r}setTextureTransform(e,t,n){this.stages.pathTracer?.materialData.updateTextureTransform(e,t,n),this.reset()}async rebuildMaterials(e){await this.stages.pathTracer?.rebuildMaterials(e||this.meshScene),this.reset()}async _initRenderer(){if(xe(e=>this.dispatchEvent(e)),!navigator.gpu)throw Error(`WebGPU is not supported in this browser`);let e=await navigator.gpu.requestAdapter({powerPreference:`high-performance`});if(!e)throw Error(`Failed to get WebGPU adapter`);let n=e.limits;this.renderer=new t.WebGPURenderer({canvas:this.canvas,alpha:!0,powerPreference:`high-performance`,requiredLimits:{maxBufferSize:n.maxBufferSize,maxStorageBufferBindingSize:n.maxStorageBufferBindingSize,maxColorAttachmentBytesPerSample:128,maxStorageBuffersPerShaderStage:Math.min(n.maxStorageBuffersPerShaderStage,10)}}),await this.renderer.init();let a=this.renderer.backend?.device;a?.lost&&(a.lost.then(e=>{this._disposed||this._handleDeviceLost(e)}),a.onuncapturederror=e=>console.error(`WebGPU uncaptured error:`,e.error)),t.RectAreaLightNode.setLTC(i.RectAreaLightTexturesLib.init()),this.renderer.outputColorSpace=t.SRGBColorSpace,this.renderer.toneMapping=r.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1,this.renderer.setPixelRatio(1)}_initCameraManager(){this.cameraManager=new Zc(this.canvas)}_initScenes(){this.scene=new r.Scene,this.meshScene=new r.Scene,this._sceneHelpers=new O}_initAssetPipeline(){this._sdf=new Ki,this.assetLoader=new qc(this.meshScene,this.cameraManager.camera,this.cameraManager.controls),this.assetLoader.setRenderer(this.renderer),this.assetLoader.createFloorPlane(),this._addTrackedListener(this.cameraManager.controls,`change`,()=>{this.needsReset=!0,this.wake()})}_initPipeline(){this._createStages();let{clientWidth:e,clientHeight:t}=this.canvas;this.pipeline=new uc(this.renderer,e||1,t||1),this.pipeline.addStage(this.stages.pathTracer),this.pipeline.addStage(this.stages.normalDepth),this.pipeline.addStage(this.stages.motionVector),this.pipeline.addStage(this.stages.asvgf),this.pipeline.addStage(this.stages.variance),this.pipeline.addStage(this.stages.bilateralFilter),this.pipeline.addStage(this.stages.edgeFilter),this.pipeline.addStage(this.stages.autoExposure),this.pipeline.addStage(this.stages.compositor);let n=this.canvas.clientWidth||1,r=this.canvas.clientHeight||1;this.pipeline.setSize(n,r)}_initManagers(){this.interactionManager=new fc({scene:this.meshScene,camera:this.cameraManager.camera,canvas:this.canvas,assetLoader:this.assetLoader,pathTracer:null,floorPlane:this.assetLoader.floorPlane}),this.interactionManager.wireAppEvents(this),this.cameraManager.setInteractionManager(this.interactionManager),this.lightManager=new Qc(this.scene,this._sceneHelpers,this.stages.pathTracer,{onReset:()=>this.reset()}),this.goboManager=new $c(this.stages.pathTracer,{onReset:()=>this.reset()}),this.iesManager=new ul(this.stages.pathTracer,{onReset:()=>this.reset()}),this._setupDenoisingManager(),this._setupOverlayManager(),this.transformManager=new Wl({camera:this.cameraManager.camera,canvas:this.canvas,orbitControls:this.cameraManager.controls,app:this}),this.interactionManager.setDependencies({overlayManager:this.overlayManager,transformManager:this.transformManager,appDispatch:e=>this.dispatchEvent(e),orbitControls:this.cameraManager.controls}),this.denoisingManager.setOverlayManager(this.overlayManager),this.denoisingManager.setResetCallback(()=>this.reset()),this.denoisingManager.setSettings(this.settings),this.environmentManager=this.stages.pathTracer.environment,this.environmentManager.callbacks.onAutoExposureReset=()=>this.pipeline.eventBus.emit(`autoexposure:resetHistory`)}_wireEvents(){this._addTrackedListener(this.cameraManager,`CameraSwitched`,e=>this.dispatchEvent(e)),this._addTrackedListener(this.cameraManager,F.AUTO_FOCUS_UPDATED,e=>this.dispatchEvent(e)),this._forwardEvents(this.denoisingManager,[F.DENOISING_START,F.DENOISING_END,F.UPSCALING_START,F.UPSCALING_PROGRESS,F.UPSCALING_END,`resolution_changed`]),this._setupAutoExposureListener(),this.animationManager.wakeCallback=()=>this.wake(),this._forwardEvents(this.animationManager,[F.ANIMATION_STARTED,F.ANIMATION_PAUSED,F.ANIMATION_STOPPED]),this._addTrackedListener(this.animationManager,F.ANIMATION_PAUSED,()=>{this._animRefitInFlight=!1}),this._addTrackedListener(this.animationManager,F.ANIMATION_STOPPED,()=>{this._animRefitInFlight=!1}),this.cameraManager.initCallbacks({onResize:()=>this.onResize(),onReset:()=>this.reset(),getSettings:e=>this.settings.get(e)}),this.cameraManager.initAutoFocus({meshScene:this.meshScene,assetLoader:this.assetLoader,floorPlane:this.assetLoader.floorPlane,pathTracer:this.stages.pathTracer,settings:this.settings,softReset:()=>this.reset(!0),hardReset:()=>this.reset()}),this.settings.bind({stages:this.stages,renderer:this.renderer,resetCallback:()=>this.reset(),reconcileCompletion:()=>this._reconcileCompletion()}),this.renderer.toneMappingExposure=this.settings.get(`exposure`)??1,this.onResize(),this.resizeHandler=()=>this.onResize(),this._autoResize&&this._addTrackedListener(window,`resize`,this.resizeHandler),this._onAssetLoaded=async e=>{if(!this._loadingInProgress){if(e.model)this._clearAppendedModels(),await this.loadSceneData();else if(e.texture){let e=this.meshScene.environment;e&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(e),Se()}this.pauseRendering=!1,this.reset()}},this._addTrackedListener(this.assetLoader,`load`,this._onAssetLoaded),this._addTrackedListener(this.assetLoader,`modelProcessed`,e=>{let t=[this.cameraManager.camera,...e.cameras||[]];this.cameraManager.setCameras(t),this.interactionManager&&(this.interactionManager.floorPlane=this.assetLoader.floorPlane)})}_initAnimationAndTransforms(){let e=this.assetLoader?.animations||[];if(e.length>0){let t=this.assetLoader?.targetModel||this.meshScene;this.animationManager.init(this.meshScene,t,this._sdf.meshes,e),this.animationManager.onFinished=()=>{this._animRefitInFlight=!1,this.dispatchEvent({type:F.ANIMATION_FINISHED})}}this.transformManager?.setMeshData(this._sdf.meshes)}_createStages(){this.stages.pathTracer=new Hs(this.renderer,this.scene,this.cameraManager.camera),this.stages.normalDepth=new Us(this.renderer,{pathTracer:this.stages.pathTracer}),this.stages.motionVector=new Ws(this.renderer,this.cameraManager.camera,{pathTracer:this.stages.pathTracer}),this.stages.asvgf=new qs(this.renderer,{enabled:!1}),this.stages.variance=new Xs(this.renderer,{enabled:!1}),this.stages.bilateralFilter=new Qs(this.renderer,{enabled:!1}),this.stages.edgeFilter=new $s(this.renderer,{enabled:!1}),this.stages.autoExposure=new oc(this.renderer,{enabled:B.autoExposure??!1}),this.stages.compositor=new sc(this.renderer,{saturation:this.settings.get(`saturation`)??B.saturation})}_setupDenoisingManager(){this.denoisingManager=new zl({renderer:this.renderer,mainCanvas:this.canvas,scene:this.scene,camera:this.cameraManager.camera,stages:{pathTracer:this.stages.pathTracer,normalDepth:this.stages.normalDepth,motionVector:this.stages.motionVector,asvgf:this.stages.asvgf,variance:this.stages.variance,bilateralFilter:this.stages.bilateralFilter,edgeFilter:this.stages.edgeFilter,autoExposure:this.stages.autoExposure,compositor:this.stages.compositor},pipeline:this.pipeline,getExposure:()=>this.settings.get(`exposure`)??1,getSaturation:()=>this.settings.get(`saturation`)??1,getTransparentBg:()=>this.settings.get(`transparentBackground`)??!1}),this.denoisingManager.setupDenoiser(),this.denoisingManager.setupUpscaler(),this.denoisingManager._syncGBufferStages();let e=this.canvas.clientWidth||1,t=this.canvas.clientHeight||1;this.denoisingManager.setRenderSize(e,t)}_reconcileCompletion(){let e=this.stages.pathTracer;if(!e)return;let t=this.completion.isLimitReached(e,this.settings.get(`renderLimitMode`),this.settings.get(`renderTimeLimit`));t&&!e.isComplete?e.isComplete=!0:!t&&e.isComplete&&(e.isComplete=!1,this.completion.resumeFromPause(),this.denoisingManager?.abort(this.canvas),this.dispatchEvent({type:F.RENDER_RESET}),this.wake())}_setupAutoExposureListener(){this.stages.autoExposure&&this.stages.autoExposure.on(`autoexposure:updated`,e=>{this.dispatchEvent({type:F.AUTO_EXPOSURE_UPDATED,exposure:e.exposure,luminance:e.luminance})})}_renderHelperOverlay(){this.scene.updateMatrixWorld(),this.overlayManager?.render(),this.transformManager?.render(this.renderer)}_setupOverlayManager(){this.overlayManager=new Hl(this.renderer,this.cameraManager.camera),this.overlayManager.setupDefaultHelpers({helperScene:this._sceneHelpers,meshScene:this.meshScene,pipeline:this.pipeline,denoisingManager:this.denoisingManager,app:this,renderWidth:this.denoisingManager?._lastRenderWidth||this.canvas.clientWidth||1,renderHeight:this.denoisingManager?._lastRenderHeight||this.canvas.clientHeight||1}),this._container=this._container||this.canvas.parentNode||null,this.overlayManager.mount(this._container)}_syncControlsAfterLoad(){this.cameraManager.controls.saveState(),this.cameraManager.controls.update()}_recalibrateControlLimits(){if(!this.meshScene||!this.cameraManager)return;let e=new r.Box3,t=new r.Box3;for(let n of this.meshScene.children)n.userData?.__rayzeeSceneObject&&(t.setFromObject(n),t.isEmpty()||e.union(t));if(e.isEmpty())return;let n=Math.max(e.max.x-e.min.x,e.max.y-e.min.y,e.max.z-e.min.z);if(!Number.isFinite(n)||n<=0)return;let{camera:i,controls:a}=this.cameraManager,o=i.fov*(Math.PI/180),s=Math.abs(n/Math.sin(o/2)/2);this.cameraManager.currentCameraIndex===0&&(i.near=n/100,i.far=n*100,i.updateProjectionMatrix());let c=i.position.distanceTo(a.target);a.minDistance=Math.min(n/1e3,c),a.maxDistance=Math.max(s*10,c*1.1),a.update()}_forwardEvents(e,t){if(e)for(let n of t)this._addTrackedListener(e,n,e=>this.dispatchEvent(e))}},ql=class{constructor(e){this._app=e,this._cancelled=!1,this._rendering=!1}async renderAnimation(e={}){let{clipIndex:t=0,fps:n=30,speed:r=1,samplesPerFrame:i=Re.maxSamples,enableOIDN:a=!0,onFrame:o,onProgress:s,onComplete:c}=e,l=this._app;if(!l.animationManager?.hasAnimations){console.warn(`VideoRenderManager: No animation clips available`),c?.(!1);return}let u=l.animationManager.clips[t];if(!u){console.warn(`VideoRenderManager: Invalid clip index ${t}`),c?.(!1);return}let d=u.duration/(r||1),f=e.totalFrames||Math.ceil(d*n),p=1/n;this._cancelled=!1,this._rendering=!0;let m=this._saveState();l.stopAnimation(),l.configureForMode(`production`),l.settings.setMany({maxSamples:i},{silent:!0}),l.stages.pathTracer?.updateCompletionThreshold?.(),l.cameraManager.controls&&(l.cameraManager.controls.enabled=!1);try{for(let e=0;e<f&&!this._cancelled;e++){let n=e*p*r,i=l.animationManager.seekTo(n,t);if(i?await l.refitBVH(i):l.reset(),l.stopAnimation(),await this._accumulateFrame(l),this._cancelled||(a&&l.denoisingManager?.denoiser?.enabled&&await this._waitForDenoise(l),this._cancelled))break;let c=l.getCanvas();if(c&&o){let t=await createImageBitmap(c);await o(t,e,f),t.close()}let u={frame:e+1,totalFrames:f,percent:(e+1)/f*100};s?.(u),l.dispatchEvent({type:F.VIDEO_RENDER_PROGRESS,...u})}}catch(e){console.error(`VideoRenderManager: Render error:`,e),this._cancelled=!0}finally{this._restoreState(m),this._rendering=!1;let e=!this._cancelled;c?.(e),l.dispatchEvent({type:F.VIDEO_RENDER_COMPLETE,success:e})}}cancel(){this._cancelled=!0}get isRendering(){return this._rendering}async _accumulateFrame(e){let t=e.stages.pathTracer;if(t?.isReady)for(;!t.isComplete&&!this._cancelled;)e.cameraManager.camera.updateMatrixWorld(),e.pipeline.render(),t.frameCount%4==0&&(Ce({samples:L(t)}),await new Promise(e=>setTimeout(e,0)))}_waitForDenoise(e){return new Promise(t=>{let n,r=()=>{e.removeEventListener(F.DENOISING_END,i),clearTimeout(n)},i=()=>{r(),t()};n=setTimeout(()=>{console.warn(`VideoRenderManager: Denoise timed out, skipping`),r(),t()},3e4),e.addEventListener(F.DENOISING_END,i),e.denoisingManager.onRenderComplete({isStillComplete:()=>!this._cancelled,context:e.pipeline?.context})})}_saveState(){let e=this._app;return{maxSamples:e.settings.get(`maxSamples`),maxBounces:e.settings.get(`maxBounces`),transmissiveBounces:e.settings.get(`transmissiveBounces`),renderMode:e.stages.pathTracer?.renderMode?.value,controlsEnabled:e.cameraManager.controls?.enabled,oidnEnabled:e.denoisingManager?.denoiser?.enabled,oidnQuality:e.denoisingManager?.denoiser?.quality,wasPlaying:e.animationManager?.isPlaying,pauseRendering:e.pauseRendering}}_restoreState(e){let t=this._app;t.settings.setMany({maxSamples:e.maxSamples,maxBounces:e.maxBounces,transmissiveBounces:e.transmissiveBounces},{silent:!0}),t.stages.pathTracer&&e.renderMode!==void 0&&t.stages.pathTracer?.setUniform(`renderMode`,parseInt(e.renderMode)),t.stages.pathTracer?.updateCompletionThreshold?.(),t.cameraManager.controls&&(t.cameraManager.controls.enabled=e.controlsEnabled??!0),t.denoisingManager?.denoiser&&(t.denoisingManager.denoiser.enabled=e.oidnEnabled??!1,e.oidnQuality&&t.denoisingManager.denoiser.updateQuality(e.oidnQuality)),t.pauseRendering=e.pauseRendering??!1,t.animationManager?.stop(),t.reset(),t.wake()}};e.AF_DEFAULTS=Ne,e.ASVGF_QUALITY_PRESETS=U,e.AUTO_FOCUS_MODES=Me,e.AnimationManager=Ul,e.BVH_LEAF_MARKERS=Pe,e.CAMERA_PRESETS=je,e.CAMERA_RANGES=ke,e.CameraManager=Zc,e.DEFAULT_TEXTURE_MATRIX=Le,e.DenoisingManager=zl,e.ENGINE_DEFAULTS=B,e.EngineEvents=F,e.GoboManager=$c,e.IESManager=ul,e.INTERACTIVE_RENDER_CONFIG=ze,e.InteractionManager=fc,e.LightManager=Qc,e.MEMORY_CONSTANTS=Be,e.OverlayManager=Hl,e.PRODUCTION_RENDER_CONFIG=Re,e.PathTracerApp=Kl,e.PipelineContext=cc,e.RenderPipeline=uc,e.RenderSettings=Xc,e.RenderStage=ve,e.SKY_PRESETS=Ae,e.StageExecutionMode=_e,e.TEXTURE_CONSTANTS=K,e.TRIANGLE_DATA_LAYOUT=W,e.TransformManager=Wl,e.VRAMTracker=qa,e.VideoRenderManager=ql,e.bufferBytes=Ga,e.configureAssets=ta,e.getAssetConfig=na,e.textureBytes=Ka});
731
+ `),uc=class extends ve{constructor(e,r={}){super(`AutoExposure`,{...r,executionMode:_e.ALWAYS}),this.renderer=e,this.REDUCTION_SIZE=64,this.keyValueU=(0,n.uniform)(r.keyValue??.18),this.minExposureU=(0,n.uniform)(r.minExposure??.1),this.maxExposureU=(0,n.uniform)(r.maxExposure??20),this.adaptSpeedBrightU=(0,n.uniform)(r.adaptSpeedBright??3),this.adaptSpeedDarkU=(0,n.uniform)(r.adaptSpeedDark??.5),this.epsilonU=(0,n.uniform)(r.epsilon??1e-4),this.deltaTimeU=(0,n.uniform)(1/60),this.isFirstFrameU=(0,n.uniform)(1),this.previousExposureU=(0,n.uniform)(r.initialExposure??1),this.lowPercentileU=(0,n.uniform)(r.lowPercentile??.1),this.highPercentileU=(0,n.uniform)(r.highPercentile??.9),this.centerWeightU=(0,n.uniform)(r.centerWeight??8),this.inputResW=(0,n.uniform)(1),this.inputResH=(0,n.uniform)(1),this._inputTexNode=new t.TextureNode,this._reductionReadTexNode=new t.TextureNode,this.currentExposure=r.initialExposure??1,this.currentLuminance=.18,this.targetExposure=1,this.lastTime=performance.now(),this.isFirstFrame=!0,this._pendingReadback=!1,this._readbackGeneration=0,this._initRenderTargets(),this._buildCompute()}_initRenderTargets(){let e={type:r.FloatType,format:r.RGBAFormat,minFilter:r.NearestFilter,magFilter:r.NearestFilter,depthBuffer:!1,stencilBuffer:!1};this._downsampleTarget=new t.RenderTarget(this.REDUCTION_SIZE,this.REDUCTION_SIZE,e),this._downsampleStorageTex=new t.StorageTexture(this.REDUCTION_SIZE,this.REDUCTION_SIZE),this._downsampleStorageTex.type=r.FloatType,this._downsampleStorageTex.format=r.RGBAFormat,this._downsampleStorageTex.minFilter=r.NearestFilter,this._downsampleStorageTex.magFilter=r.NearestFilter,this._reductionStorageTex=new t.StorageTexture(1,1),this._reductionStorageTex.type=r.FloatType,this._reductionStorageTex.format=r.RGBAFormat,this._reductionStorageTex.minFilter=r.NearestFilter,this._reductionStorageTex.magFilter=r.NearestFilter,this._reductionReadTarget=new t.RenderTarget(1,1,e),this._adaptationResult=(0,n.attributeArray)(1,`vec4`),this._readbackBuffer=new t.ReadbackBuffer(16),this._readbackBuffer.name=`AutoExposureAdaptation`,this._histogramBuffer=(0,n.attributeArray)(ic,`uint`).toAtomic()}_buildCompute(){this._buildDownsampleCompute(),this._buildHistogramCompute(),this._buildHistogramAnalyzeCompute(),this._buildAdaptationCompute()}_buildDownsampleCompute(){let e=this._inputTexNode,t=this._downsampleStorageTex,r=this.epsilonU,i=this.inputResW,a=this.inputResH;this._downsampleComputeNode=(0,n.Fn)(()=>{let o=(0,n.int)(n.workgroupId.x).mul(8).add((0,n.int)(n.localId.x)),s=(0,n.int)(n.workgroupId.y).mul(8).add((0,n.int)(n.localId.y)),c=i.div((0,n.float)(64)),l=a.div((0,n.float)(64)),u=(0,n.float)(o).mul(c),d=(0,n.float)(s).mul(l),f=(0,n.float)(0).toVar(),p=(0,n.float)(0).toVar();for(let t=0;t<4;t++)for(let i=0;i<4;i++){let a=tn((0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(u.add((0,n.float)((i+.5)/4).mul(c))),(0,n.int)(d.add((0,n.float)((t+.5)/4).mul(l))))).xyz);(0,n.If)(a.greaterThan(r),()=>{f.addAssign(a.add(r).log()),p.addAssign(1)})}(0,n.textureStore)(t,(0,n.uvec2)((0,n.uint)(o),(0,n.uint)(s)),(0,n.vec4)(f,p,0,1)).toWriteOnly()})().compute([64/8,64/8,1],[8,8,1])}_buildHistogramCompute(){let e=this._downsampleTarget.texture,t=this._histogramBuffer,r=this.centerWeightU;this._histogramComputeNode=(0,n.Fn)(()=>{let i=n.localId.x;(0,n.atomicStore)(t.element(i),(0,n.uint)(0)),(0,n.workgroupBarrier)();for(let a=0;a<16;a++){let o=i.mul(16).add(a),s=o.mod(64),c=o.div(64),l=(0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(s),(0,n.int)(c))),u=l.x,d=l.y;(0,n.If)(d.greaterThan(0),()=>{let e=(0,n.uint)(u.div(d).sub((0,n.float)(ac)).div((0,n.float)(oc)).mul((0,n.float)(ic)).floor().clamp(0,(0,n.float)(ic-1))),i=(0,n.float)(s).add(.5).div((0,n.float)(64)),a=(0,n.float)(c).add(.5).div((0,n.float)(64)),o=i.sub(.5),l=a.sub(.5),f=(0,n.uint)(o.mul(o).add(l.mul(l)).mul(r).negate().exp().mul((0,n.float)(cc)));(0,n.atomicAdd)(t.element(e),f)})}})().compute([1,1,1],[256,1,1])}_buildHistogramAnalyzeCompute(){let e=this._histogramBuffer,t=this._reductionStorageTex,r=this.lowPercentileU,i=this.highPercentileU;this._histogramAnalyzeNode=(0,n.Fn)(()=>{let a=(0,n.float)(0).toVar();(0,n.Loop)(ic,({i:t})=>{a.addAssign((0,n.float)((0,n.atomicLoad)(e.element(t))))});let o=a.mul(r),s=a.mul(i),c=(0,n.float)(0).toVar(),l=(0,n.float)(0).toVar(),u=(0,n.float)(0).toVar(),d=(0,n.float)(0).toVar();(0,n.Loop)(ic,({i:t})=>{let r=(0,n.float)((0,n.atomicLoad)(e.element(t)));d.assign(c),c.addAssign(r),(0,n.If)(d.lessThan(s).and(c.greaterThan(o)),()=>{let e=(0,n.float)(ac).add((0,n.float)(t).add(.5).mul((0,n.float)(sc)));l.addAssign(e.mul(r)),u.addAssign(r)})});let f=(0,n.max)(u,(0,n.float)(1)),p=l.div(f),m=p.exp();(0,n.textureStore)(t,(0,n.uvec2)((0,n.uint)(0),(0,n.uint)(0)),(0,n.vec4)(m,a,p,1)).toWriteOnly()})().compute(1,[1,1,1])}_buildAdaptationCompute(){let e=this._reductionReadTexNode,t=this._adaptationResult,r=this.keyValueU,i=this.minExposureU,a=this.maxExposureU,o=this.adaptSpeedBrightU,s=this.adaptSpeedDarkU,c=this.deltaTimeU,l=this.isFirstFrameU,u=this.previousExposureU;this._adaptationComputeNode=(0,n.Fn)(()=>{let d=(0,n.textureLoad)(e,(0,n.ivec2)((0,n.int)(0),(0,n.int)(0))).x,f=lc(d,u,r,i,a,o,s,c,l);t.element((0,n.uint)(0)).assign(f)})().compute(1,[1,1,1])}setupEventListeners(){this.on(`pipeline:reset`,()=>this.reset()),this.on(`autoexposure:resetHistory`,()=>this.resetHistory()),this.on(`autoexposure:toggle`,e=>{this.enabled=e}),this.on(`autoexposure:updateParameters`,e=>e&&this.updateParameters(e))}render(e){if(!this.enabled)return;let t=e.getTexture(`edgeFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`);if(!t)return;let n=performance.now(),r=Math.min((n-this.lastTime)/1e3,.1);if(this.lastTime=n,this.deltaTimeU.value=this.isFirstFrame?1:r,this.isFirstFrameU.value=+!!this.isFirstFrame,this.previousExposureU.value=this.currentExposure,this.inputResW.value=t.image?.width||1,this.inputResH.value=t.image?.height||1,this._inputTexNode.value=t,this.renderer.compute(this._downsampleComputeNode),this.renderer.copyTextureToTexture(this._downsampleStorageTex,this._downsampleTarget.texture),this.renderer.compute(this._histogramComputeNode),this.renderer.compute(this._histogramAnalyzeNode),this.renderer.copyTextureToTexture(this._reductionStorageTex,this._reductionReadTarget.texture),this._reductionReadTexNode.value=this._reductionReadTarget.texture,this.renderer.compute(this._adaptationComputeNode),!this._pendingReadback){this._pendingReadback=!0;let e=this._readbackGeneration;this.renderer.getArrayBufferAsync(this._adaptationResult.value,this._readbackBuffer).then(t=>{let n=t&&t.buffer?new Float32Array(t.buffer.slice(0)):null;this._readbackBuffer.release(),this._pendingReadback=!1,n&&e===this._readbackGeneration&&this._applyReadback(n)}).catch(()=>{try{this._readbackBuffer.release()}catch{}this._pendingReadback=!1})}e.setState(`autoexposure:value`,this.currentExposure),e.setState(`autoexposure:avgLuminance`,this.currentLuminance),this.emit(`autoexposure:updated`,{exposure:this.currentExposure,luminance:this.currentLuminance,targetExposure:this.targetExposure}),this.isFirstFrame=!1}_applyReadback(e){if(!this.enabled||!e||e.length<3)return;let t=e[0],n=e[1],r=e[2];(!isFinite(t)||t<=0)&&(t=1),(!isFinite(n)||n<=0)&&(n=.18),(!isFinite(r)||r<=0)&&(r=t),this.currentExposure=t,this.currentLuminance=n,this.targetExposure=r,this.renderer.toneMappingExposure=t}reset(){this.lastTime=performance.now(),this._readbackGeneration++,this._pendingReadback=!1}resetHistory(){this.isFirstFrame=!0,this.currentExposure=1,this.currentLuminance=.18,this.targetExposure=1,this.lastTime=performance.now(),this._readbackGeneration++,this._pendingReadback=!1}setSize(){}setExposure(e){this.currentExposure=e,this.previousExposureU.value=e,this.renderer.toneMappingExposure=e}getExposure(){return this.currentExposure}getLuminance(){return this.currentLuminance}updateParameters(e){e.keyValue!==void 0&&(this.keyValueU.value=e.keyValue),e.minExposure!==void 0&&(this.minExposureU.value=e.minExposure),e.maxExposure!==void 0&&(this.maxExposureU.value=e.maxExposure),e.adaptSpeedBright!==void 0&&(this.adaptSpeedBrightU.value=e.adaptSpeedBright),e.adaptSpeedDark!==void 0&&(this.adaptSpeedDarkU.value=e.adaptSpeedDark),e.lowPercentile!==void 0&&(this.lowPercentileU.value=e.lowPercentile),e.highPercentile!==void 0&&(this.highPercentileU.value=e.highPercentile),e.centerWeight!==void 0&&(this.centerWeightU.value=e.centerWeight)}dispose(){this._downsampleComputeNode?.dispose(),this._histogramComputeNode?.dispose(),this._histogramAnalyzeNode?.dispose(),this._adaptationComputeNode?.dispose(),this._downsampleTarget?.dispose(),this._downsampleStorageTex?.dispose(),this._reductionStorageTex?.dispose(),this._reductionReadTarget?.dispose(),this._readbackBuffer?.dispose(),this._inputTexNode?.dispose(),this._reductionReadTexNode?.dispose()}},dc=class extends ve{constructor(e,i={}){super(`Compositor`,{...i,executionMode:_e.ALWAYS}),this.renderer=e,this.saturation=(0,n.uniform)(i.saturation??1),this._transparentBackground=(0,n.uniform)(0,`int`),this._sourceTexNode=new t.TextureNode;let a=this._sourceTexNode.sample((0,n.uv)()),o=(0,n.mix)((0,n.vec3)((0,n.dot)(a.xyz,Xt)),a.xyz,this.saturation),s=(0,n.select)(this._transparentBackground,a.w,1);this.compositorMaterial=new t.MeshBasicNodeMaterial,this.compositorMaterial.colorNode=(0,n.vec4)(o,s),this.compositorMaterial.blending=r.NoBlending,this.compositorQuad=new t.QuadMesh(this.compositorMaterial)}_resolveSourceTexture(e){return e.getTexture(`bloom:output`)||e.getTexture(`edgeFiltering:output`)||e.getTexture(`bilateralFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`pathtracer:color`)}render(e){if(!this.enabled)return;let t=this._resolveSourceTexture(e);t&&(this._sourceTexNode.value=t,this.renderer.setRenderTarget(null),this.compositorQuad.render(this.renderer))}setSaturation(e){this.saturation.value=e}setTransparentBackground(e){this._transparentBackground.value=+!!e}dispose(){this._sourceTexNode?.dispose(),this.compositorMaterial?.dispose(),this.compositorQuad=null}},fc=class{constructor(){this.textures=new Map,this.renderTargets=new Map,this.uniforms=new Map,this.state={frame:0,accumulatedFrames:0,renderMode:0,interactionMode:!1,isComplete:!1,tileInfo:null,currentTile:0,totalTiles:0,cameraChanged:!1,cameraMoving:!1,width:0,height:0,time:0,deltaTime:0,enableASVGF:!1,enableEdgeFiltering:!1},this._stateChangeCallbacks=new Map}setTexture(e,t){this.textures.set(e,t)}getTexture(e){return this.textures.get(e)}hasTexture(e){return this.textures.has(e)}removeTexture(e){this.textures.delete(e)}getTextureNames(){return Array.from(this.textures.keys())}clearTextures(){this.textures.clear()}setRenderTarget(e,t){this.renderTargets.set(e,t)}getRenderTarget(e){return this.renderTargets.get(e)}hasRenderTarget(e){return this.renderTargets.has(e)}removeRenderTarget(e){this.renderTargets.delete(e)}getRenderTargetNames(){return Array.from(this.renderTargets.keys())}clearRenderTargets(){this.renderTargets.clear()}setUniform(e,t){this.uniforms.has(e)?this.uniforms.get(e).value=t:this.uniforms.set(e,{value:t})}getUniform(e){return this.uniforms.get(e)}getUniformValue(e){return this.uniforms.get(e)?.value}hasUniform(e){return this.uniforms.has(e)}removeUniform(e){this.uniforms.delete(e)}getUniformNames(){return Array.from(this.uniforms.keys())}clearUniforms(){this.uniforms.clear()}setState(e,t){let n=this.state[e],r=n!==t;return r&&(this.state[e]=t,this._notifyStateChange(e,t,n)),r}getState(e){return this.state[e]}getAllState(){return this.state}setStates(e){let t=[];for(let[n,r]of Object.entries(e))this.setState(n,r)&&t.push(n);return t}hasState(e){return e in this.state}watchState(e,t){this._stateChangeCallbacks.has(e)||this._stateChangeCallbacks.set(e,[]),this._stateChangeCallbacks.get(e).push(t)}unwatchState(e,t){if(!this._stateChangeCallbacks.has(e))return;let n=this._stateChangeCallbacks.get(e),r=n.indexOf(t);r>-1&&n.splice(r,1)}_notifyStateChange(e,t,n){if(!this._stateChangeCallbacks.has(e))return;let r=this._stateChangeCallbacks.get(e);for(let i of r)try{i(t,n)}catch(t){console.error(`Error in state change callback for '${e}':`,t)}}reset(){this.state.frame=0,this.state.accumulatedFrames=0,this.state.isComplete=!1,this.state.cameraChanged=!0,this.state.currentTile=0}incrementFrame(){return this.state.frame++,this.state.accumulatedFrames++,this.state.frame}dispose(){this.textures.clear(),this.renderTargets.clear(),this.uniforms.clear(),this._stateChangeCallbacks.clear(),this.state={}}},pc=class extends r.EventDispatcher{constructor(){super(),this._onceCallbacks=new Map}on(e,t){this.addEventListener(e,t)}once(e,t){let n=r=>{t(r),this.off(e,n),this._onceCallbacks.delete(t)};this._onceCallbacks.set(t,n),this.on(e,n)}off(e,t){let n=this._onceCallbacks.get(t);n?(this.removeEventListener(e,n),this._onceCallbacks.delete(t)):this.removeEventListener(e,t)}emit(e,t){t&&typeof t==`object`&&t.type?this.dispatchEvent(t):this.dispatchEvent({type:e,...t})}removeAllListeners(e){if(e){for(let[t,n]of this._onceCallbacks.entries())this.hasEventListener(e,n)&&(this.removeEventListener(e,n),this._onceCallbacks.delete(t));this._listeners&&this._listeners[e]&&delete this._listeners[e]}else this._onceCallbacks.clear(),this._listeners&&={}}listenerCount(e){return!this._listeners||!this._listeners[e]?0:this._listeners[e].length}clear(){this.removeAllListeners()}eventNames(){return this._listeners?Object.keys(this._listeners):[]}},mc=class{constructor(e,t,n){this.renderer=e,this.width=t,this.height=n,this.stages=[],this.context=new fc,this.eventBus=new pc,this.context.setState(`width`,t),this.context.setState(`height`,n),this.stats={enabled:!1,logSkipped:!1,timings:new Map,frameCount:0}}addStage(e){this.stages.push(e),e.initialize(this.context,this.eventBus),this.stats.enabled&&console.log(`[Pipeline] Added stage: ${e.name}`)}getStage(e){return this.stages.find(t=>t.name===e)}removeStage(e){let t=this.stages.findIndex(t=>t.name===e);if(t>-1){let e=this.stages[t];return this.stages.splice(t,1),e.dispose&&e.dispose(),this.stats.timings.delete(e.name),!0}return!1}setStageEnabled(e,t){let n=this.getStage(e);n&&(t?n.enable():n.disable())}render(e=null){let t=this.stats.enabled?performance.now():0;for(let t of this.stages){if(!t.shouldExecuteThisFrame(this.context)){this.stats.enabled&&this.stats.logSkipped&&console.log(`[Pipeline] Skipped stage '${t.name}' (executionMode: ${t.executionMode})`);continue}try{let n=this.stats.enabled?performance.now():0;if(t.render(this.context,e),this.stats.enabled){let e=performance.now()-n;this.stats.timings.has(t.name)||this.stats.timings.set(t.name,[]);let r=this.stats.timings.get(t.name);r.push(e),r.length>60&&r.shift()}}catch(e){console.error(`[Pipeline] Error in stage '${t.name}':`,e)}}if(this.context.incrementFrame(),this.eventBus.emit(`frame:complete`,{frame:this.context.getState(`frame`),accumulatedFrames:this.context.getState(`accumulatedFrames`)}),this.stats.enabled){let e=performance.now()-t;this.stats.timings.has(`_total`)||this.stats.timings.set(`_total`,[]);let n=this.stats.timings.get(`_total`);n.push(e),n.length>60&&n.shift(),this.stats.frameCount++}}reset(){this.eventBus.emit(`pipeline:reset`);for(let e of this.stages)if(e.reset)try{e.reset()}catch(t){console.error(`[Pipeline] Error resetting stage '${e.name}':`,t)}this.context.reset(),this.stats.enabled&&(this.stats.timings.clear(),this.stats.frameCount=0)}setSize(e,t){this.width=e,this.height=t,this.context.setState(`width`,e),this.context.setState(`height`,t),this.eventBus.emit(`pipeline:resize`,{width:e,height:t});for(let n of this.stages)if(n.setSize)try{n.setSize(e,t)}catch(e){console.error(`[Pipeline] Error resizing stage '${n.name}':`,e)}}dispose(){for(let e of this.stages)if(e.dispose)try{e.dispose()}catch(t){console.error(`[Pipeline] Error disposing stage '${e.name}':`,t)}this.stages=[],this.context.dispose(),this.eventBus.clear(),this.stats.timings.clear()}setStatsEnabled(e){this.stats.enabled=e,e||(this.stats.timings.clear(),this.stats.frameCount=0)}getStats(){if(!this.stats.enabled)return null;let e={frameCount:this.stats.frameCount,stages:{},total:0};for(let[t,n]of this.stats.timings.entries()){if(n.length===0)continue;let r=n.reduce((e,t)=>e+t,0)/n.length,i=Math.min(...n),a=Math.max(...n);t===`_total`?(e.total=r,e.totalMin=i,e.totalMax=a):e.stages[t]={avg:r,min:i,max:a}}return e}logStats(){let e=this.getStats();if(!e){console.log(`[Pipeline] Stats not enabled`);return}console.group(`[Pipeline] Performance Stats`),console.log(`Frames: ${e.frameCount}`),e.totalMin===void 0?console.log(`Total: no frames recorded yet (pipeline.render() has not run since stats were enabled — the path tracer may have converged and stopped its animation loop)`):console.log(`Total: ${e.total.toFixed(2)}ms (min: ${e.totalMin.toFixed(2)}ms, max: ${e.totalMax.toFixed(2)}ms)`);for(let[t,n]of Object.entries(e.stages))console.log(` ${t}: ${n.avg.toFixed(2)}ms (min: ${n.min.toFixed(2)}ms, max: ${n.max.toFixed(2)}ms)`);console.groupEnd()}getInfo(){return{stageCount:this.stages.length,enabledStages:this.stages.filter(e=>e.enabled).length,stages:this.stages.map(e=>({name:e.name,enabled:e.enabled})),contextState:this.context.getAllState(),textures:this.context.getTextureNames(),renderTargets:this.context.getRenderTargetNames(),uniforms:this.context.getUniformNames(),events:this.eventBus.eventNames()}}logInfo(){let e=this.getInfo();console.group(`[Pipeline] Info`),console.log(`Stages:`,e.stages),console.log(`Context Textures:`,e.textures),console.log(`Context Render Targets:`,e.renderTargets),console.log(`Context Uniforms:`,e.uniforms),console.log(`Event Types:`,e.events),console.log(`State:`,e.contextState),console.groupEnd()}},hc=class{constructor(){this.timeElapsed=0,this.lastResetTime=performance.now(),this.renderCompleteDispatched=!1}updateTime(){this.timeElapsed=(performance.now()-this.lastResetTime)/1e3}isTimeLimitReached(e,t){return e===`time`&&t>0&&this.timeElapsed>=t}isLimitReached(e,t,n){return e?this.isTimeLimitReached(t,n)?!0:e.frameCount>=e.completionThreshold:!1}markComplete(){return this.renderCompleteDispatched?!1:(this.renderCompleteDispatched=!0,!0)}reset(){this.timeElapsed=0,this.lastResetTime=performance.now(),this.renderCompleteDispatched=!1}resumeFromPause(){this.renderCompleteDispatched=!1,this.lastResetTime=performance.now()-this.timeElapsed*1e3}},gc=class extends r.EventDispatcher{constructor({scene:e,camera:t,canvas:n,assetLoader:i,pathTracer:a,floorPlane:o}){super(),this.scene=e,this.camera=t,this.canvas=n,this.assetLoader=i,this.pathTracer=a,this.floorPlane=o,this.raycaster=new r.Raycaster,this.focusMode=!1,this.focusPointIndicator=null,this.afPointPlacementMode=!1,this.handleAFPointClick=this.handleAFPointClick.bind(this),this.selectedObject=null,this.selectMode=!1,this.clickTimeout=null,this.mouseDownPosition=null,this.dragThreshold=5,this.handleFocusClick=this.handleFocusClick.bind(this),this.handleSelectClick=this.handleSelectClick.bind(this),this.handleSelectDoubleClick=this.handleSelectDoubleClick.bind(this),this.handleMouseDown=this.handleMouseDown.bind(this),this.handleMouseUp=this.handleMouseUp.bind(this),this.handleContextMenu=this.handleContextMenu.bind(this),this.handleContextPointerDown=this.handleContextPointerDown.bind(this),this.handleContextPointerUp=this.handleContextPointerUp.bind(this),this.contextPointerDownPosition=null,this.canvas.addEventListener(`pointerdown`,this.handleContextPointerDown),this.canvas.addEventListener(`pointerup`,this.handleContextPointerUp),this.canvas.addEventListener(`contextmenu`,this.handleContextMenu),this._overlayManager=null,this._transformManager=null,this._appDispatch=null,this._orbitControls=null}setDependencies({overlayManager:e,transformManager:t,appDispatch:n,orbitControls:r}){this._overlayManager=e||null,this._transformManager=t||null,this._appDispatch=n||null,this._orbitControls=r||null}select(e){let t=this._overlayManager?.getHelper(`outline`);t&&t.setSelectedObjects(e?[e]:[]),this.selectedObject=e||null,e?this._transformManager?.attach(e):this._transformManager?.detach(),this._appDispatch?.({type:F.OBJECT_SELECTED,object:e||null})}deselect(){this.select(null)}disableMode(){this.disableSelectMode(),this._transformManager?.detach()}on(e,t){return this.addEventListener(e,t),()=>this.removeEventListener(e,t)}toggleFocusMode(){return this.focusMode=!this.focusMode,this.canvas.style.cursor=this.focusMode?`crosshair`:`auto`,this.focusMode?this.canvas.addEventListener(`click`,this.handleFocusClick):this.canvas.removeEventListener(`click`,this.handleFocusClick),this._orbitControls&&(this._orbitControls.enabled=!this.focusMode),this.dispatchEvent({type:`focusModeChanged`,enabled:this.focusMode}),this.focusMode}handleFocusClick(e){let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0);if(n.length>0){let e=n[0],t=e.distance;this.showFocusPoint(e.point),this.toggleFocusMode(),this.dispatchEvent({type:`focusChanged`,distance:t/this.assetLoader.getSceneScale(),worldDistance:t})}}showFocusPoint(e){this.focusPointIndicator&&this.scene.remove(this.focusPointIndicator),this.focusPointIndicator=new r.Mesh(new r.SphereGeometry(this.assetLoader.getSceneScale()*.02,16,16),new r.MeshBasicMaterial({color:65280,transparent:!0,opacity:.8,depthTest:!1})),this.focusPointIndicator.position.copy(e),this.scene.add(this.focusPointIndicator),setTimeout(()=>{this.focusPointIndicator&&=(this.scene.remove(this.focusPointIndicator),null)},2e3)}enterAFPointPlacementMode(){this.afPointPlacementMode=!0,this.canvas.style.cursor=`crosshair`,this.canvas.addEventListener(`click`,this.handleAFPointClick)}exitAFPointPlacementMode(){this.afPointPlacementMode=!1,this.canvas.style.cursor=`auto`,this.canvas.removeEventListener(`click`,this.handleAFPointClick)}handleAFPointClick(e){let t=this.canvas.getBoundingClientRect(),n=(e.clientX-t.left)/t.width,r=(e.clientY-t.top)/t.height;this.exitAFPointPlacementMode(),this.dispatchEvent({type:`afPointPlaced`,point:{x:n,y:r}})}toggleSelectMode(){return this.selectMode=!this.selectMode,this.canvas.style.cursor=this.selectMode?`pointer`:`auto`,this.selectMode?(this.canvas.addEventListener(`mousedown`,this.handleMouseDown),this.canvas.addEventListener(`mouseup`,this.handleMouseUp),this.canvas.addEventListener(`click`,this.handleSelectClick),this.canvas.addEventListener(`dblclick`,this.handleSelectDoubleClick)):(this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null),this.dispatchEvent({type:`selectModeChanged`,enabled:this.selectMode}),this.selectMode}disableSelectMode(){this.selectMode&&(this.selectMode=!1,this.canvas.style.cursor=`auto`,this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null,this.dispatchEvent({type:`selectModeChanged`,enabled:!1}))}handleMouseDown(e){this.mouseDownPosition={x:e.clientX,y:e.clientY,button:e.button}}wasMouseDragged(e){if(!this.mouseDownPosition)return!1;let t=Math.abs(e.clientX-this.mouseDownPosition.x),n=Math.abs(e.clientY-this.mouseDownPosition.y);return Math.sqrt(t*t+n*n)>this.dragThreshold}handleSelectClick(e){if(this.wasMouseDragged(e)){this.mouseDownPosition=null;return}if(this.mouseDownPosition=null,this.clickTimeout){clearTimeout(this.clickTimeout),this.clickTimeout=null;return}this.clickTimeout=setTimeout(()=>{this.clickTimeout=null;let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0),r=this.filterValidIntersects(n);if(r.length>0){let e=r[0].object,t=this.selectedObject;t&&t.uuid===e.uuid?this.dispatchEvent({type:`objectDeselected`,object:e,uuid:e.uuid}):this.dispatchEvent({type:`objectSelected`,object:e,uuid:e.uuid})}else this.dispatchEvent({type:`objectDeselected`})},250)}handleSelectDoubleClick(e){if(this.wasMouseDragged(e)){this.mouseDownPosition=null;return}this.mouseDownPosition=null,this.clickTimeout&&=(clearTimeout(this.clickTimeout),null);let t=this.getMouseCoordinates(e);this.raycaster.setFromCamera(t,this.camera);let n=this.raycaster.intersectObjects(this.scene.children,!0),r=this.filterValidIntersects(n);if(r.length>0){let e=r[0].object;this.dispatchEvent({type:`objectDoubleClicked`,object:e,uuid:e.uuid})}}handleMouseUp(){}handleContextPointerDown(e){e.button===2&&(this.contextPointerDownPosition={x:e.clientX,y:e.clientY})}handleContextPointerUp(e){if(e.button!==2)return;if(this.contextPointerDownPosition){let t=Math.abs(e.clientX-this.contextPointerDownPosition.x),n=Math.abs(e.clientY-this.contextPointerDownPosition.y);if(Math.sqrt(t*t+n*n)>this.dragThreshold){this.contextPointerDownPosition=null;return}}else return;this.contextPointerDownPosition=null;let t=this.selectedObject;t&&this.dispatchEvent({type:`contextMenuRequested`,x:e.clientX,y:e.clientY,selectedObject:t})}handleContextMenu(e){e.preventDefault()}getMouseCoordinates(e){let t=this.canvas.getBoundingClientRect();return{x:(e.clientX-t.left)/t.width*2-1,y:-((e.clientY-t.top)/t.height)*2+1}}filterValidIntersects(e){return e.filter(e=>{let t=e.object;return t!==this.focusPointIndicator&&t!==this.floorPlane&&!t.name.includes(`Helper`)&&t.type===`Mesh`})}updateDependencies({scene:e,camera:t,floorPlane:n}){e&&(this.scene=e),t&&(this.camera=t),n&&(this.floorPlane=n)}wireAppEvents(e){this.addEventListener(`objectSelected`,t=>{this.select(t.object),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_SELECTED,object:t.object,uuid:t.uuid})}),this.addEventListener(`objectDeselected`,t=>{this.select(null),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_DESELECTED,object:t.object,uuid:t.uuid})}),this.addEventListener(`selectModeChanged`,t=>{e.dispatchEvent({type:F.SELECT_MODE_CHANGED,enabled:t.enabled})}),this.addEventListener(`objectDoubleClicked`,t=>{this.select(t.object),e.refreshFrame(),e.dispatchEvent({type:F.OBJECT_DOUBLE_CLICKED,object:t.object,uuid:t.uuid})}),this.addEventListener(`focusChanged`,t=>{e.settings.set(`focusDistance`,t.worldDistance),e.dispatchEvent({type:`focusChanged`,distance:t.distance})}),this.addEventListener(`afPointPlaced`,t=>{e.dispatchEvent({type:F.AF_POINT_PLACED,point:t.point})})}dispose(){this.canvas.removeEventListener(`click`,this.handleAFPointClick),this.canvas.removeEventListener(`click`,this.handleFocusClick),this.canvas.removeEventListener(`mousedown`,this.handleMouseDown),this.canvas.removeEventListener(`mouseup`,this.handleMouseUp),this.canvas.removeEventListener(`click`,this.handleSelectClick),this.canvas.removeEventListener(`dblclick`,this.handleSelectDoubleClick),this.canvas.removeEventListener(`contextmenu`,this.handleContextMenu),this.canvas.removeEventListener(`pointerdown`,this.handleContextPointerDown),this.canvas.removeEventListener(`pointerup`,this.handleContextPointerUp),this.clickTimeout&&=(clearTimeout(this.clickTimeout),null),this.mouseDownPosition=null,this.contextPointerDownPosition=null,this.focusPointIndicator&&=(this.scene.remove(this.focusPointIndicator),null),this.canvas.style.cursor=`auto`,this.scene=null,this.camera=null,this.canvas=null,this.assetLoader=null,this.pathTracer=null,this.floorPlane=null,this.raycaster=null}},_c={STRING:`string`,NUMBER:`number`,WORD:`word`,LBRACKET:`[`,RBRACKET:`]`},vc=e=>e===` `||e===` `||e===`
732
+ `||e===`\r`||e===`\f`,yc=e=>e>=`0`&&e<=`9`,bc=(e,t,n)=>!!(yc(e)||e===`.`&&yc(t)||(e===`-`||e===`+`)&&(yc(t)||t===`.`&&yc(n)));function xc(e){let t=[],n=e.length,r=0;for(;r<n;){let i=e[r];if(vc(i)){r++;continue}if(i===`#`){for(;r<n&&e[r]!==`
733
+ `;)r++;continue}if(i===`[`){t.push({type:_c.LBRACKET}),r++;continue}if(i===`]`){t.push({type:_c.RBRACKET}),r++;continue}if(i===`"`){r++;let i=r;for(;r<n&&e[r]!==`"`;)r++;if(r>=n)throw Error(`PBRT tokenizer: unterminated string literal`);t.push({type:_c.STRING,value:e.slice(i,r)}),r++;continue}if(bc(i,e[r+1],e[r+2])){let i=r;for(r++;r<n;){let t=e[r];if(t>=`0`&&t<=`9`||t===`.`||t===`e`||t===`E`||t===`-`||t===`+`)r++;else break}let a=e.slice(i,r),o=Number(a);if(Number.isNaN(o))throw Error(`PBRT tokenizer: invalid number "${a}"`);t.push({type:_c.NUMBER,value:o});continue}{let i=r;for(;r<n&&!vc(e[r])&&e[r]!==`"`&&e[r]!==`[`&&e[r]!==`]`&&e[r]!==`#`;)r++;t.push({type:_c.WORD,value:e.slice(i,r)})}}return t}function Sc(){return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}function Cc(e,t){let n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],d=e[9],f=e[10],p=e[11],m=e[12],h=e[13],g=e[14],_=e[15],v=t[0],y=t[1],b=t[2],x=t[3],S=t[4],C=t[5],w=t[6],T=t[7],E=t[8],D=t[9],O=t[10],k=t[11],A=t[12],j=t[13],M=t[14],N=t[15];return[n*v+o*y+u*b+m*x,r*v+s*y+d*b+h*x,i*v+c*y+f*b+g*x,a*v+l*y+p*b+_*x,n*S+o*C+u*w+m*T,r*S+s*C+d*w+h*T,i*S+c*C+f*w+g*T,a*S+l*C+p*w+_*T,n*E+o*D+u*O+m*k,r*E+s*D+d*O+h*k,i*E+c*D+f*O+g*k,a*E+l*D+p*O+_*k,n*A+o*j+u*M+m*N,r*A+s*j+d*M+h*N,i*A+c*j+f*M+g*N,a*A+l*j+p*M+_*N]}function wc(e,t,n){return[1,0,0,0,0,1,0,0,0,0,1,0,e,t,n,1]}function Tc(e,t,n){return[e,0,0,0,0,t,0,0,0,0,n,0,0,0,0,1]}function Ec(e,t,n,r){let i=Math.hypot(t,n,r)||1;t/=i,n/=i,r/=i;let a=e*Math.PI/180,o=Math.cos(a),s=Math.sin(a),c=1-o,l=c*t*t+o,u=c*t*n-s*r,d=c*t*r+s*n,f=c*t*n+s*r,p=c*n*n+o,m=c*n*r-s*t;return[l,f,c*t*r-s*n,0,u,p,c*n*r+s*t,0,d,m,c*r*r+o,0,0,0,0,1]}function Dc(e,t){return[e[0]-t[0],e[1]-t[1],e[2]-t[2]]}function Oc(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function kc(e){let t=Math.hypot(e[0],e[1],e[2])||1;return[e[0]/t,e[1]/t,e[2]/t]}function Ac(e,t,n){let r=kc(Dc(t,e)),i=kc(Oc(kc(n),r)),a=Oc(r,i);return[i[0],i[1],i[2],0,a[0],a[1],a[2],0,r[0],r[1],r[2],0,e[0],e[1],e[2],1]}function jc(e){let t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],c=e[7],l=e[8],u=e[9],d=e[10],f=e[11],p=e[12],m=e[13],h=e[14],g=e[15],_=u*h*c-m*d*c+m*s*f-o*h*f-u*s*g+o*d*g,v=p*d*c-l*h*c-p*s*f+a*h*f+l*s*g-a*d*g,y=l*m*c-p*u*c+p*o*f-a*m*f-l*o*g+a*u*g,b=p*u*s-l*m*s-p*o*d+a*m*d+l*o*h-a*u*h,x=t*_+n*v+r*y+i*b;if(x===0)return Sc();let S=1/x;return[_*S,(m*d*i-u*h*i-m*r*f+n*h*f+u*r*g-n*d*g)*S,(o*h*i-m*s*i+m*r*c-n*h*c-o*r*g+n*s*g)*S,(u*s*i-o*d*i-u*r*c+n*d*c+o*r*f-n*s*f)*S,v*S,(l*h*i-p*d*i+p*r*f-t*h*f-l*r*g+t*d*g)*S,(p*s*i-a*h*i-p*r*c+t*h*c+a*r*g-t*s*g)*S,(a*d*i-l*s*i+l*r*c-t*d*c-a*r*f+t*s*f)*S,y*S,(p*u*i-l*m*i-p*n*f+t*m*f+l*n*g-t*u*g)*S,(a*m*i-p*o*i+p*n*c-t*m*c-a*n*g+t*o*g)*S,(l*o*i-a*u*i-l*n*c+t*u*c+a*n*f-t*o*f)*S,b*S,(l*m*r-p*u*r+p*n*d-t*m*d-l*n*h+t*u*h)*S,(p*o*r-a*m*r-p*n*s+t*m*s+a*n*h-t*o*h)*S,(a*u*r-l*o*r+l*n*s-t*u*s-a*n*d+t*o*d)*S]}var Mc=class{constructor(e={}){this.resolveInclude=e.resolveInclude||(()=>{throw Error(`PBRTParser: Include used but no resolveInclude provided`)}),this.ir={film:null,camera:null,namedMaterials:new Map,namedTextures:new Map,shapes:[],lights:[],instances:[],objects:new Map,warnings:[]},this.ctm=Sc(),this.state={material:null,areaLight:null,reverseOrientation:!1},this.attributeStack=[],this.transformStack=[],this.coordSystems=new Map,this.currentObject=null,this.objectBeginCTM=null,this.dirStack=[``],this.tokens=[],this.pos=0,this._warnedUnknown=new Set}parse(e,t=``){return this.dirStack=[t],this._run(xc(e)),this.ir}_peek(){return this.tokens[this.pos]}_next(){return this.tokens[this.pos++]}_expectNumber(e){let t=this._next();if(!t||t.type!==_c.NUMBER)throw Error(`PBRT parser: expected number for ${e}, got ${t?t.value:`EOF`}`);return t.value}_expectString(e){let t=this._next();if(!t||t.type!==_c.STRING)throw Error(`PBRT parser: expected string for ${e}, got ${t?t.value:`EOF`}`);return t.value}_readNumbers(e){let t=[];for(let n=0;n<e;n++)t.push(this._expectNumber(`matrix/transform`));return t}_readBracketedOrBareNumbers(e){if(this._peek()&&this._peek().type===_c.LBRACKET){this._next();let e=[];for(;this._peek()&&this._peek().type!==_c.RBRACKET;)e.push(this._expectNumber(`transform element`));return this._next(),e}return this._readNumbers(e)}_parseParams(){let e={};for(;this._peek()&&this._peek().type===_c.STRING;){let t=this._next().value.trim().split(/\s+/),n=t[0],r=t[1]===void 0?t[0]:t[1];e[r]={type:n,value:this._parseParamValue()}}return e}_parseParamValue(){let e=[];if(this._peek()&&this._peek().type===_c.LBRACKET){for(this._next();this._peek()&&this._peek().type!==_c.RBRACKET;)e.push(this._coerceValueToken(this._next()));this._next()}else e.push(this._coerceValueToken(this._next()));return e}_coerceValueToken(e){if(!e)throw Error(`PBRT parser: unexpected EOF in parameter value`);if(e.type===_c.NUMBER||e.type===_c.STRING)return e.value;if(e.type===_c.WORD)return e.value===`true`?!0:e.value===`false`?!1:e.value;throw Error(`PBRT parser: unexpected token in parameter value: ${e.type}`)}_run(e){let t=this.tokens,n=this.pos;for(this.tokens=e,this.pos=0;this.pos<this.tokens.length;){let e=this._next();if(e.type!==_c.WORD)throw Error(`PBRT parser: expected directive, got ${e.type} ${e.value??``}`);this._directive(e.value)}this.tokens=t,this.pos=n}_directive(e){switch(e){case`Identity`:this.ctm=Sc();break;case`Translate`:{let[e,t,n]=this._readNumbers(3);this.ctm=Cc(this.ctm,wc(e,t,n));break}case`Scale`:{let[e,t,n]=this._readNumbers(3);this.ctm=Cc(this.ctm,Tc(e,t,n));break}case`Rotate`:{let[e,t,n,r]=this._readNumbers(4);this.ctm=Cc(this.ctm,Ec(e,t,n,r));break}case`LookAt`:{let e=this._readNumbers(9),t=Ac([e[0],e[1],e[2]],[e[3],e[4],e[5]],[e[6],e[7],e[8]]);this.ctm=Cc(this.ctm,jc(t));break}case`Transform`:this.ctm=this._readBracketedOrBareNumbers(16);break;case`ConcatTransform`:{let e=this._readBracketedOrBareNumbers(16);this.ctm=Cc(this.ctm,e);break}case`CoordinateSystem`:this.coordSystems.set(this._expectString(`CoordinateSystem`),this.ctm.slice());break;case`CoordSysTransform`:{let e=this.coordSystems.get(this._expectString(`CoordSysTransform`));e&&(this.ctm=e.slice());break}case`Camera`:{let e=this._expectString(`Camera type`),t=this._parseParams();this.ir.camera={type:e,params:t,cameraToWorld:jc(this.ctm)};break}case`Film`:{this._expectString(`Film type`);let e=this._parseParams();this.ir.film={xresolution:this._num(e.xresolution,1280),yresolution:this._num(e.yresolution,720),filename:this._str(e.filename,null)};break}case`Integrator`:case`Sampler`:case`PixelFilter`:case`Filter`:case`Accelerator`:case`ColorSpace`:case`Option`:this._skipTypeAndParams();break;case`WorldBegin`:this.ctm=Sc(),this.state={material:null,areaLight:null,reverseOrientation:!1};break;case`WorldEnd`:break;case`AttributeBegin`:this.attributeStack.push({ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation});break;case`AttributeEnd`:{let e=this.attributeStack.pop();e&&(this.ctm=e.ctm,this.state={material:e.material,areaLight:e.areaLight,reverseOrientation:e.reverseOrientation});break}case`TransformBegin`:this.transformStack.push(this.ctm.slice());break;case`TransformEnd`:{let e=this.transformStack.pop();e&&(this.ctm=e);break}case`ReverseOrientation`:this.state.reverseOrientation=!this.state.reverseOrientation;break;case`Attribute`:this._expectString(`Attribute target`),this._parseParams();break;case`ActiveTransform`:this._next();break;case`TransformTimes`:this._readNumbers(2);break;case`MediumInterface`:this._peek()&&this._peek().type===_c.STRING&&this._next(),this._peek()&&this._peek().type===_c.STRING&&this._next();break;case`MakeNamedMedium`:this._skipNamedAndParams();break;case`Material`:{let e=this._expectString(`Material type`),t=this._parseParams();this.state.material={type:e,params:t};break}case`MakeNamedMaterial`:{let e=this._expectString(`MakeNamedMaterial name`),t=this._parseParams(),n=this._str(t.type,`diffuse`);this.ir.namedMaterials.set(e,{type:n,params:t});break}case`NamedMaterial`:{let e=this._expectString(`NamedMaterial name`),t=this.ir.namedMaterials.get(e);this.state.material=t||{type:`diffuse`,params:{},_missingRef:e},t||this._warn(`NamedMaterial "${e}" referenced before definition`);break}case`Texture`:{let e=this._expectString(`Texture name`),t=this._expectString(`Texture data type`),n=this._expectString(`Texture class`),r=this._parseParams();this.ir.namedTextures.set(e,{dataType:t,class:n,params:r});break}case`AreaLightSource`:{let e=this._expectString(`AreaLightSource type`),t=this._parseParams();this.state.areaLight={type:e,params:t};break}case`LightSource`:{let e=this._expectString(`LightSource type`),t=this._parseParams();this.ir.lights.push({type:e,params:t,ctm:this.ctm.slice()});break}case`Shape`:{let e={type:this._expectString(`Shape type`),params:this._parseParams(),ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation};this._emitShape(e);break}case`ObjectBegin`:{let e=this._expectString(`ObjectBegin name`);this.attributeStack.push({ctm:this.ctm.slice(),material:this.state.material,areaLight:this.state.areaLight,reverseOrientation:this.state.reverseOrientation}),this.currentObject=e,this.objectBeginCTM=this.ctm.slice(),this.ir.objects.has(e)||this.ir.objects.set(e,[]);break}case`ObjectEnd`:{this.currentObject=null,this.objectBeginCTM=null;let e=this.attributeStack.pop();e&&(this.ctm=e.ctm,this.state={material:e.material,areaLight:e.areaLight,reverseOrientation:e.reverseOrientation});break}case`ObjectInstance`:{let e=this._expectString(`ObjectInstance name`);this.ir.instances.push({name:e,ctm:this.ctm.slice()});break}case`Include`:case`Import`:{let t=this._expectString(e);this._include(t);break}default:this._warnUnknown(e),this._parseParams();break}}_emitShape(e){this.currentObject===null?this.ir.shapes.push(e):(e.relativeCTM=Cc(jc(this.objectBeginCTM),e.ctm),this.ir.objects.get(this.currentObject).push(e))}_include(e){let t=this.resolveInclude(e,this.dirStack[this.dirStack.length-1]);if(t==null){this._warn(`Include target not found: ${e}`);return}let n=e.includes(`/`)?e.slice(0,e.lastIndexOf(`/`)):``;this.dirStack.push(n),this._run(xc(t)),this.dirStack.pop()}_skipTypeAndParams(){this._peek()&&this._peek().type===_c.STRING&&this._next(),this._parseParams()}_skipNamedAndParams(){this._peek()&&this._peek().type===_c.STRING&&this._next(),this._parseParams()}_num(e,t){return e&&e.value.length?e.value[0]:t}_str(e,t){return e&&e.value.length?e.value[0]:t}_warn(e){this.ir.warnings.push(e)}_warnUnknown(e){this._warnedUnknown.has(e)||(this._warnedUnknown.add(e),this._warn(`Unsupported directive ignored: ${e}`))}},Nc={au:[1,.78,.34],gold:[1,.78,.34],cu:[.95,.64,.54],copper:[.95,.64,.54],ag:[.97,.96,.91],silver:[.97,.96,.91],al:[.91,.92,.92],aluminium:[.91,.92,.92],aluminum:[.91,.92,.92],mgo:[.9,.9,.9],tio2:[.9,.9,.9]},Pc=[.92,.92,.92];function Fc(e){let t=Math.max(1e3,Math.min(4e4,e))/100,n,r,i;t<=66?(n=255,r=99.47*Math.log(t)-161.12):(n=329.7*(t-60)**-.1332,r=288.12*(t-60)**-.0755),i=t>=66?255:t<=19?0:138.52*Math.log(t-10)-305.04;let a=e=>Math.max(0,Math.min(255,e))/255;return[a(n)**2.2,a(r)**2.2,a(i)**2.2]}function Ic(e,t,n){let r=e[t];return r&&typeof r.value[0]==`number`?r.value[0]:n}function Lc(e,t,n){let r=e[t];return r&&typeof r.value[0]==`string`?r.value[0]:n}async function Rc(e,t,n,r=null){let i=e[t];if(!i)return{rgb:r,texture:null};if(i.type===`texture`){let e=i.value[0],t=await n.resolveNamedTexture(e);return t&&t.texture?{rgb:t.constant??null,texture:t.texture}:t&&t.constant?{rgb:t.constant,texture:null}:(n.warn(`texture "${e}" could not be resolved`),{rgb:r,texture:null})}if(i.type===`rgb`||i.type===`color`)return{rgb:[i.value[0],i.value[1],i.value[2]],texture:null};if(i.type===`float`){let e=i.value[0];return{rgb:[e,e,e],texture:null}}if(i.type===`blackbody`)return{rgb:Fc(i.value[0]),texture:null};if(i.type===`spectrum`){if(typeof i.value[0]==`string`){let e=zc(i.value[0]);return e&&Nc[e]?{rgb:Nc[e].slice(),texture:null}:(n.warn(`named spectrum "${i.value[0]}" approximated to gray`),{rgb:[.5,.5,.5],texture:null})}let e=0,t=0;for(let n=1;n<i.value.length;n+=2)e+=i.value[n],t++;let r=t?e/t:.5;return{rgb:[r,r,r],texture:null}}return{rgb:r,texture:null}}function zc(e){let t=e.toLowerCase().match(/metal-([a-z]+)/);if(t)return t[1];for(let t of Object.keys(Nc))if(e.toLowerCase().includes(t))return t;return null}function Bc(e,t){if(e.roughness&&typeof e.roughness.value[0]==`number`)return e.roughness.value[0];let n=Ic(e,`uroughness`,null),r=Ic(e,`vroughness`,null);return n!==null&&r!==null?(n+r)/2:n===null?t:n}async function Vc(e,t){let n=e?.type||`diffuse`,i=e?.params||{},a=new r.MeshPhysicalMaterial({side:r.DoubleSide,roughness:1,metalness:0}),o=e=>{e&&a.color.setRGB(e[0],e[1],e[2])},s=e=>{o(e.rgb),e.texture&&(a.map=e.texture,e.rgb||a.color.setRGB(1,1,1))};switch(n){case`diffuse`:s(await Rc(i,`reflectance`,t,[.5,.5,.5])),a.roughness=1,a.metalness=0;break;case`conductor`:case`metal`:{let e=await Rc(i,`reflectance`,t,null),n=i.eta,r=i.k,c=n&&n.type===`spectrum`&&typeof n.value[0]==`string`;if(e.rgb||e.texture)s(e);else if(n&&r&&!c){let e=(await Rc(i,`eta`,t,[.2,.92,1.1])).rgb,n=(await Rc(i,`k`,t,[3.9,2.45,2.14])).rgb,r=(e,t)=>((e-1)**2+t**2)/((e+1)**2+t**2);o([r(e[0],n[0]),r(e[1],n[1]),r(e[2],n[2])])}else o(n?(await Rc(i,`eta`,t,Pc)).rgb||Pc:Nc.cu);a.metalness=1,a.roughness=Bc(i,.1);break}case`dielectric`:case`thindielectric`:a.transmission=1,a.metalness=0,a.color.setRGB(1,1,1),a.ior=Ic(i,`eta`,1.5),a.roughness=Bc(i,0),a.thickness=n===`thindielectric`?0:Ic(i,`thickness`,0);break;case`coateddiffuse`:s(await Rc(i,`reflectance`,t,[.5,.5,.5])),a.roughness=.6,a.metalness=0,a.clearcoat=1,a.clearcoatRoughness=Bc(i,0);break;case`diffusetransmission`:{let e=await Rc(i,`transmittance`,t,[.25,.25,.25]);s(await Rc(i,`reflectance`,t,[.25,.25,.25])),a.transmission=e.rgb?(e.rgb[0]+e.rgb[1]+e.rgb[2])/3:.5,a.roughness=1,a.ior=1;break}case`interface`:case`none`:case``:a.transmission=1,a.ior=1,a.roughness=0,a.color.setRGB(1,1,1);break;case`mix`:{let e=i.materials?.value||[],n=Math.max(0,Math.min(1,Ic(i,`amount`,.5))),o=e[0]?t.namedMaterials?.get(e[0]):null,s=e[1]?t.namedMaterials?.get(e[1]):null;if(o&&s){let[e,r]=await Promise.all([Vc(o,t),Vc(s,t)]),i=(e,t)=>e*(1-n)+t*n;a.color.lerpColors(e.color,r.color,n),a.roughness=i(e.roughness,r.roughness),a.metalness=i(e.metalness,r.metalness),a.ior=i(e.ior??1.5,r.ior??1.5),a.transmission=i(e.transmission??0,r.transmission??0),a.thickness=i(e.thickness??0,r.thickness??0),a.clearcoat=i(e.clearcoat??0,r.clearcoat??0),a.clearcoatRoughness=i(e.clearcoatRoughness??0,r.clearcoatRoughness??0),a.emissive.lerpColors(e.emissive,r.emissive,n),a.emissiveIntensity=i(e.emissiveIntensity??0,r.emissiveIntensity??0),a.map=(n<.5?e.map:r.map)||null;break}t.warn(`material "mix" — could not resolve inner materials [${e.join(`, `)}], falling back to diffuse`),a.color.set(new r.Color(.6,.6,.6));break}case`subsurface`:case`hair`:case`measured`:t.warn(`material "${n}" not supported — using diffuse approximation`),o((await Rc(i,`reflectance`,t,[.5,.5,.5])).rgb),a.roughness=1;break;default:t.warn(`unknown material "${n}" — using neutral diffuse`),a.color.set(new r.Color(.6,.6,.6));break}return a.roughness=Math.max(0,Math.min(1,a.roughness)),a}var Hc=[1,0,0,0,0,1,0,0,0,0,-1,0,0,0,0,1],Uc=class{constructor(e={}){this.resolvePLY=e.resolvePLY||(async()=>null),this.resolveImage=e.resolveImage||(async()=>null),this.resolveEnvironment=e.resolveEnvironment||e.resolveImage||(async()=>null),this.convertHandedness=e.convertHandedness===!0,this.warnings=[],this.report=[],this._materialCache=new Map,this._textureCache=new Map}warn(e){this.warnings.push(e)}async build(e){this.ir=e;let t=new r.Group;t.name=`PBRTScene`;for(let n=0;n<e.shapes.length;n++){let r=await this._buildShapeMesh(e.shapes[n],e.shapes[n].ctm,`shape_${n}`);r&&t.add(r)}await this._buildInstances(e,t);let n=null;e.camera&&(n=this._buildCamera(e.camera,e.film),n&&t.add(n));let i=await this._buildEnvironment(e.lights);return this._reportUnsupportedLights(e.lights),{group:t,camera:n,environment:i,report:this.report,warnings:this.warnings.concat(e.warnings||[])}}async _buildInstances(e,t){let n=0;for(let r of e.instances){let i=e.objects.get(r.name);if(!i){this.warn(`ObjectInstance "${r.name}" has no template`);continue}for(let e of i){let i=Cc(r.ctm,e.relativeCTM||e.ctm),a=await this._buildShapeMesh(e,i,`instance_${n++}`);a&&t.add(a)}}}async _buildShapeMesh(e,t,n){let[i,a]=await Promise.all([this._buildGeometry(e),this._getMaterial(e)]);if(!i)return null;let o=!!i.getAttribute(`uv`),s=a;a.map&&!o&&(this.warn(`${n} (${e.type}, "${e.material?.type||`diffuse`}") has a texture map but no UVs — dropping map, using base color`),s=a.clone(),s.map=null);let c=new r.Mesh(i,s);c.name=n;let l=this.convertHandedness?Cc(Hc,t):t;new r.Matrix4().fromArray(l).decompose(c.position,c.quaternion,c.scale),c.updateMatrix(),i.computeBoundingBox();let u=i.boundingBox?i.boundingBox.clone().applyMatrix4(c.matrix).getSize(new r.Vector3):new r.Vector3;return this.report.push({mesh:n,shape:e.type,material:e.material?.type||`diffuse`,color:`#`+s.color.getHexString(),map:s.map?`yes`:`-`,uv:o?`yes`:`NO`,normals:i.getAttribute(`normal`)?`yes`:`NO`,emissive:s.emissiveIntensity>0?`#${s.emissive.getHexString()}×${s.emissiveIntensity}`:`-`,size:`${u.x.toFixed(2)}×${u.y.toFixed(2)}×${u.z.toFixed(2)}`,tris:i.index?i.index.count/3:i.getAttribute(`position`).count/3}),c}async _buildGeometry(e){switch(e.type){case`trianglemesh`:return this._triangleMesh(e.params);case`bilinearmesh`:return this._bilinearMesh(e.params);case`plymesh`:return this._plyMesh(e.params);case`sphere`:return this._sphere(e.params);case`disk`:return this._disk(e.params);default:return this.warn(`shape "${e.type}" not supported — skipped`),null}}_triangleMesh(e){let t=e.P?.value;if(!t||t.length<9)return this.warn(`trianglemesh missing P`),null;let n=new r.BufferGeometry;n.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(t),3));let i=e.N?.value;i&&i.length===t.length&&n.setAttribute(`normal`,new r.Float32BufferAttribute(Float32Array.from(i),3));let a=(e.uv||e.st)?.value;a&&a.length===t.length/3*2&&n.setAttribute(`uv`,new r.Float32BufferAttribute(Float32Array.from(a),2));let o=e.indices?.value;return o&&o.length&&n.setIndex(o),i||n.computeVertexNormals(),n}_bilinearMesh(e){let t=e.P?.value,n=e.indices?.value;if(!t||!n)return this.warn(`bilinearmesh missing P/indices`),null;let i=[];for(let e=0;e+3<n.length;e+=4){let[t,r,a,o]=[n[e],n[e+1],n[e+2],n[e+3]];i.push(t,r,a,t,a,o)}let a=new r.BufferGeometry;return a.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(t),3)),a.setIndex(i),a.computeVertexNormals(),a}async _plyMesh(e){let t=Lc(e,`filename`,null);if(!t)return this.warn(`plymesh missing filename`),null;try{let e=await this.resolvePLY(t);return e?(e.getAttribute(`normal`)||e.computeVertexNormals(),e):(this.warn(`plymesh file not found: ${t}`),null)}catch(e){return this.warn(`failed to load plymesh ${t}: ${e.message}`),null}}_sphere(e){return new r.SphereGeometry(Ic(e,`radius`,1),48,32)}_disk(e){let t=Ic(e,`radius`,1),n=Ic(e,`innerradius`,0),i=Ic(e,`height`,0),a=[],o=[];for(let e=0;e<48;e++){let r=e/48*Math.PI*2,s=(e+1)/48*Math.PI*2,c=a.length/3;a.push(Math.cos(r)*n,Math.sin(r)*n,i),a.push(Math.cos(r)*t,Math.sin(r)*t,i),a.push(Math.cos(s)*t,Math.sin(s)*t,i),a.push(Math.cos(s)*n,Math.sin(s)*n,i),o.push(c,c+1,c+2,c,c+2,c+3)}let s=new r.BufferGeometry;return s.setAttribute(`position`,new r.Float32BufferAttribute(Float32Array.from(a),3)),s.setIndex(o),s.computeVertexNormals(),s}async _getMaterial(e){let t=this._materialCache.get(e.material);if(t||(t=new Map,this._materialCache.set(e.material,t)),t.has(e.areaLight))return t.get(e.areaLight);let n={resolveNamedTexture:e=>this._resolveNamedTexture(e),namedMaterials:this.ir.namedMaterials,warn:e=>this.warn(e)},r=await Vc(e.material,n);return e.areaLight&&await this._applyAreaLight(r,e.areaLight,n),t.set(e.areaLight,r),r}async _applyAreaLight(e,t,n){let r=await Rc(t.params,`L`,n,[1,1,1]),i=Ic(t.params,`scale`,1),a=r.rgb||[1,1,1];e.emissive.setRGB(a[0],a[1],a[2]),e.emissiveIntensity=i}async _resolveNamedTexture(e){if(this._textureCache.has(e))return this._textureCache.get(e);let t=this.ir.namedTextures.get(e),n=null;if(!t)this.warn(`named texture "${e}" not defined`);else if(t.class===`imagemap`){let r=Lc(t.params,`filename`,null);if(r)try{let t=await this.resolveImage(r);t?n={texture:t}:this.warn(`image not found for texture "${e}": ${r}`)}catch(t){this.warn(`failed to load texture "${e}" (${r}): ${t.message}`)}}else if(t.class===`constant`){let e=t.params.value;e&&e.type===`rgb`?n={constant:[e.value[0],e.value[1],e.value[2]]}:e&&(n={constant:[e.value[0],e.value[0],e.value[0]]})}else t.class===`scale`?n=await this._resolveScaleTexture(e,t):this.warn(`texture class "${t.class}" not supported (texture "${e}")`);return this._textureCache.set(e,n),n}async _resolveScaleTexture(e,t){let n=t.params.tex,r=null;if(n?.type===`texture`&&typeof n.value[0]==`string`)r=await this._resolveNamedTexture(n.value[0]);else if(n?.type===`rgb`||n?.type===`color`)r={constant:[n.value[0],n.value[1],n.value[2]]};else if(n?.type===`float`){let e=n.value[0];r={constant:[e,e,e]}}let i=t.params.scale,a=[1,1,1];if(i?.type===`rgb`||i?.type===`color`)a=[i.value[0],i.value[1],i.value[2]];else if(i?.type===`float`){let e=i.value[0];a=[e,e,e]}if(r?.texture){let e=r.constant||[1,1,1];return{texture:r.texture,constant:[e[0]*a[0],e[1]*a[1],e[2]*a[2]]}}let o=r?.constant||[1,1,1];return{constant:[o[0]*a[0],o[1]*a[1],o[2]*a[2]]}}_buildCamera(e,t){let n=new r.Matrix4().fromArray(e.cameraToWorld).elements,i=new r.Vector3(n[12],n[13],n[14]),a=new r.Vector3(n[8],n[9],n[10]),o=new r.Vector3(n[4],n[5],n[6]);this.convertHandedness&&(i.z*=-1,a.z*=-1,o.z*=-1);let s=i.clone().add(a),c=t&&t.yresolution?t.xresolution/t.yresolution:16/9,l=new r.PerspectiveCamera(this._verticalFov(e.params,c),c,.01,1e4);return l.name=`PBRT Camera`,l.up.copy(o.normalize()),l.position.copy(i),l.lookAt(s),l.updateMatrixWorld(!0),l}_verticalFov(e,t){let n=Ic(e,`fov`,90);if(t>=1)return n;let r=n*Math.PI/180;return 2*Math.atan(Math.tan(r/2)/t)*180/Math.PI}async _buildEnvironment(e){let t=e.find(e=>e.type===`infinite`);if(!t)return null;let n=Ic(t.params,`scale`,1),i=Lc(t.params,`filename`,null);if(i)try{let e=await this.resolveEnvironment(i);if(e)return e.mapping=r.EquirectangularReflectionMapping,{texture:e};this.warn(`infinite-light image not found: ${i}`)}catch(e){this.warn(`failed to load infinite-light image ${i}: ${e.message}`)}let a=((await Rc(t.params,`L`,{resolveNamedTexture:async()=>null,warn:e=>this.warn(e)},[1,1,1])).rgb||[1,1,1]).map(e=>e*n),o=new Float32Array(8);for(let e=0;e<2;e++)o[e*4+0]=a[0],o[e*4+1]=a[1],o[e*4+2]=a[2],o[e*4+3]=1;let s=new r.DataTexture(o,2,1,r.RGBAFormat,r.FloatType);return s.mapping=r.EquirectangularReflectionMapping,s.minFilter=r.LinearFilter,s.magFilter=r.LinearFilter,s.needsUpdate=!0,{texture:s}}_reportUnsupportedLights(e){for(let t of e)t.type!==`infinite`&&this.warn(`light "${t.type}" not supported (only infinite lights and emissive area lights are mapped)`)}},Wc=new TextDecoder;function Gc(e){let t=e.replace(/\\/g,`/`).split(`/`),n=[];for(let e of t)e===``||e===`.`||(e===`..`?n.pop():n.push(e));return n.join(`/`)}function Kc(e,t){return!e||t.startsWith(`/`)?Gc(t):Gc(`${e}/${t}`)}var qc=class{constructor(e){this.byPath=new Map,this.byBase=new Map;for(let t in e){let n=Gc(t).toLowerCase(),r={norm:n,bytes:e[t]};this.byPath.set(n,r);let i=n.split(`/`).pop(),a=this.byBase.get(i);a?a.push(r):this.byBase.set(i,[r])}}find(e){let t=Gc(e).toLowerCase();if(this.byPath.has(t))return this.byPath.get(t).bytes;let n=this.byBase.get(t.split(`/`).pop());return n?(n.find(e=>e.norm.endsWith(`/`+t))||n[0]).bytes:null}};function Jc(e){let t=Object.keys(e).filter(e=>e.toLowerCase().endsWith(`.pbrt`));if(t.length===0)return null;let n=t.filter(e=>/(^|\/)(scene|main)\.pbrt$/i.test(e)),r=n.length?n:t;return r.sort((e,t)=>{let n=e.split(`/`).length,r=t.split(`/`).length;return n===r?e.length-t.length:n-r}),r[0]}async function Yc(e){let{vfs:t,plyParser:n,imageFromBytes:r,envFromBytes:i,convertHandedness:a}=e,o=new qc(t),s=e.entryPath||Jc(t);if(!s)throw Error(`PBRT loader: no .pbrt file found in archive`);let c=o.find(s);if(!c)throw Error(`PBRT loader: entry "${s}" not readable`);let l=s.includes(`/`)?s.slice(0,s.lastIndexOf(`/`)):``,u=new Mc({resolveInclude:(e,t)=>{let n=o.find(Kc(t,e))||o.find(e);return n?Wc.decode(n):null}}).parse(Wc.decode(c),l),d=e=>e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength);return{...await new Uc({convertHandedness:a,resolvePLY:async e=>{let t=o.find(e);return t?n(d(t)):null},resolveImage:async e=>{let t=o.find(e);return t?r(t,e):null},resolveEnvironment:async e=>{let t=o.find(e);return t?(i||r)(t,e):null}}).build(u),entryPath:s}}var Xc={glb:{type:`model`,name:`GLB (GLTF Binary)`},gltf:{type:`model`,name:`GLTF`},fbx:{type:`model`,name:`FBX`},obj:{type:`model`,name:`OBJ`},stl:{type:`model`,name:`STL`},ply:{type:`model`,name:`PLY (Polygon File Format)`},dae:{type:`model`,name:`Collada`},"3mf":{type:`model`,name:`3D Manufacturing Format`},usdz:{type:`model`,name:`Universal Scene Description`},hdr:{type:`environment`,name:`HDR (High Dynamic Range)`},exr:{type:`environment`,name:`EXR (OpenEXR)`},png:{type:`image`,name:`PNG`},jpg:{type:`image`,name:`JPEG`},jpeg:{type:`image`,name:`JPEG`},webp:{type:`image`,name:`WebP`},zip:{type:`archive`,name:`ZIP Archive`}},Zc=class e extends r.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.camera=t,this.controls=n,this.targetModel=null,this._externalModel=null,this.floorPlane=null,this.sceneScale=1,this.loaderCache={},this.uploadedFileInfo=null,this.animations=[],this.renderer=null,this._loadingManager=new r.LoadingManager,this._loadCancelled=!1}cancelActiveLoad(){this._loadCancelled=!0,this._loadingManager.abort()}_isCancellation(e){return this._loadCancelled||e?.name===`AbortError`||e?.code===`LOAD_CANCELLED`}_cancellationError(){let e=Error(`Load cancelled`);return e.code=`LOAD_CANCELLED`,e}_downloadProgress(e,t){return n=>{let r=n?.loaded||0,i=n?.lengthComputable&&n.total||0;I({isLoading:!0,status:e,loadedBytes:r,totalBytes:i,canCancel:!!t,progress:i?Math.min(60,2+Math.round(r/i*58)):2})}}_downloadComplete(e=`Processing Data...`,t=62){I({status:e,progress:t,canCancel:!1,loadedBytes:null,totalBytes:null})}static _isNetworkUrl(e){return typeof e==`string`&&/^https?:/i.test(e)}releaseTargetModel(){this.targetModel&&(this.targetModel===this._externalModel?this.targetModel.parent?.remove(this.targetModel):R(this.targetModel),this.targetModel=null,this._externalModel=null,this.animations=[])}setRenderer(e){this.renderer=e}getFileFormat(e){return Xc[e.split(`.`).pop().toLowerCase()]||null}readFileAsArrayBuffer(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=e=>t(e.target.result),r.onerror=e=>n(e),r.readAsArrayBuffer(e)})}readFileAsText(e){return new Promise((t,n)=>{let r=new FileReader;r.onload=e=>t(e.target.result),r.onerror=e=>n(e),r.readAsText(e)})}async loadAssetFromFile(e){let t=e.name,n=this.getFileFormat(t);if(!n)throw Error(`Unsupported file format: ${t}`);I({isLoading:!0,status:`Loading ${n.name}...`,progress:2});try{let r;switch(n.type){case`model`:r=await this.loadModelFromFile(e,t);break;case`environment`:case`image`:r=await this.loadEnvironmentFromFile(e,t);break;case`archive`:r=await this.loadArchiveFromFile(e,t);break;default:throw Error(`Unknown asset type: ${n.type}`)}return r}catch(e){throw this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadModelFromFile(e,t){let n=t.split(`.`).pop().toLowerCase(),r=await this.readFileAsArrayBuffer(e);switch(n){case`glb`:case`gltf`:return await this.loadGLBFromArrayBuffer(r,t);case`fbx`:return await this.loadFBXFromArrayBuffer(r,t);case`obj`:return await this.loadOBJFromFile(e,t);case`stl`:return await this.loadSTLFromArrayBuffer(r,t);case`ply`:return await this.loadPLYFromArrayBuffer(r,t);case`dae`:return await this.loadColladaFromFile(e,t);case`3mf`:return await this.load3MFFromArrayBuffer(r,t);case`usdz`:return await this.loadUSDZFromArrayBuffer(r,t);default:throw Error(`Support for ${n} files is not yet implemented`)}}async loadEnvironmentFromFile(e,t){let n=URL.createObjectURL(e);this.uploadedFileInfo={name:t,type:e.type,size:e.size};try{let e=await this.loadEnvironment(n);return this.dispatchEvent({type:`load`,texture:e,filename:t}),e}finally{URL.revokeObjectURL(n)}}async loadEnvironment(e){this._loadCancelled=!1;try{this.dispatchEvent({type:`beforeEnvironmentLoad`,url:e});let t;if(e.startsWith(`blob:`))t=await this.loadEnvironmentFromBlob(e);else{let n=e.split(/[?#]/)[0].split(`.`).pop().toLowerCase();t=await this.loadEnvironmentByExtension(e,n)}return t.generateMipmaps=!0,this.applyEnvironmentToScene(t),this.dispatchEvent({type:`load`,texture:t}),t}catch(t){throw this._isCancellation(t)?this._cancellationError():(console.error(`Error loading environment:`,t),this.dispatchEvent({type:`error`,message:t.message,filename:e}),t)}}async loadEnvironmentFromBlob(e){let t=await(await fetch(e)).blob(),n=this.determineEnvironmentExtension(t,e),r=URL.createObjectURL(t);try{return await this.loadEnvironmentByExtension(r,n)}finally{URL.revokeObjectURL(r)}}determineEnvironmentExtension(e,t){let n;if(e.type===`image/x-exr`||e.type.includes(`exr`))n=`exr`;else if(e.type===`image/vnd.radiance`||e.type.includes(`hdr`))n=`hdr`;else{let e=t.split(`/`).pop();if(e){let t=e.match(/\.([^.]+)$/);t&&(n=t[1].toLowerCase())}}return!n&&this.uploadedFileInfo&&(n=this.uploadedFileInfo.name.split(`.`).pop().toLowerCase()),n}async loadEnvironmentByExtension(t,n){let i=e._isNetworkUrl(t),a=this._downloadProgress(`Downloading Environment...`,i),o;return n===`hdr`||n===`exr`?o=await(n===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new s.HDRLoader(this._loadingManager).setDataType(r.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new u.EXRLoader(this._loadingManager).setDataType(r.FloatType))).loadAsync(t,a):(this.loaderCache.texture||(this.loaderCache.texture=new r.TextureLoader(this._loadingManager)),o=await this.loaderCache.texture.loadAsync(t,a),o.colorSpace=r.SRGBColorSpace),this._downloadComplete(`Processing Environment...`,62),o.mapping=r.EquirectangularReflectionMapping,o.minFilter=r.LinearFilter,o.magFilter=r.LinearFilter,o}applyEnvironmentToScene(e){this.scene.background=e,this.scene.environment=e}async loadArchiveFromFile(e,t){try{let n=await this.readFileAsArrayBuffer(e),r=(0,p.unzipSync)(new Uint8Array(n));return Jc(r)?await this.loadPBRTFromZip(r,t):await this.processObjMtlPairsInZip(r,t)||await this.findAndLoadModelFromZip(r,t)}catch(e){throw console.error(`Error loading ZIP archive:`,e),e}}async loadPBRTFromZip(e,t){if(I({isLoading:!0,status:`Parsing PBRT scene...`,progress:5}),!this.loaderCache.ply){let{PLYLoader:e}=await import(`three/examples/jsm/loaders/PLYLoader.js`);this.loaderCache.ply=new e}let{group:n,environment:r,report:i,warnings:a,entryPath:o}=await Yc({vfs:e,plyParser:e=>this.loaderCache.ply.parse(e),imageFromBytes:(e,t)=>this._pbrtTextureFromBytes(e,t),envFromBytes:async(e,t)=>{let n=t.split(`.`).pop().toLowerCase(),r=URL.createObjectURL(new Blob([e]));try{return await this.loadEnvironmentByExtension(r,n)}finally{URL.revokeObjectURL(r)}}});return i&&i.length&&typeof console.table==`function`&&(console.groupCollapsed(`PBRT loader: ${i.length} mesh(es) from "${o}"`),console.table(i),console.groupEnd()),a&&a.length&&(console.warn(`PBRT loader: ${a.length} warning(s) parsing "${o}"`),a.forEach(e=>console.warn(` •`,e))),r?.texture&&(r.texture.generateMipmaps=!0,this.applyEnvironmentToScene(r.texture)),n.name=o||t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing PBRT geometry...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:`${o} (from ZIP)`}),n}async _pbrtTextureFromBytes(e,t){let n=t.split(`.`).pop().toLowerCase(),i;if(n===`exr`||n===`hdr`){let t=n===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new s.HDRLoader().setDataType(r.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new u.EXRLoader().setDataType(r.FloatType));i=await this._loadViaObjectURL(t,e)}else if(n===`tga`){if(!this.loaderCache.tga){let{TGALoader:e}=await import(`three/examples/jsm/loaders/TGALoader.js`);this.loaderCache.tga=new e}i=await this._loadViaObjectURL(this.loaderCache.tga,e),i.colorSpace=r.SRGBColorSpace}else i=new r.Texture(await createImageBitmap(new Blob([e]))),i.colorSpace=r.SRGBColorSpace;return i.wrapS=i.wrapT=r.RepeatWrapping,i.needsUpdate=!0,i}async _loadViaObjectURL(e,t){let n=URL.createObjectURL(new Blob([t]));try{return await e.loadAsync(n)}finally{URL.revokeObjectURL(n)}}async processObjMtlPairsInZip(e,t){let n=[],r=[];for(let t in e){let i=t.toLowerCase();i.endsWith(`.obj`)?n.push({path:t,content:e[t]}):i.endsWith(`.mtl`)&&r.push({path:t,content:e[t]})}if(n.length>0&&r.length>0){console.log(`Found ${n.length} OBJ files and ${r.length} MTL files in ZIP`);let i=this.findMatchingObjMtlPairs(n,r);if(i.length>0)return console.log(`Found ${i.length} matching OBJ+MTL pairs`),await this.loadOBJMTLPairFromZip(i[0].obj,i[0].mtl,e,t);if(i.length===0)return console.log(`No matching pairs by name, using first OBJ and MTL files`),await this.loadOBJMTLPairFromZip(n[0],r[0],e,t)}return null}findMatchingObjMtlPairs(e,t){let n=[];for(let r of e){let e=r.path.split(`/`).pop().replace(/\.obj$/i,``).toLowerCase();for(let i of t){let t=i.path.split(`/`).pop().replace(/\.mtl$/i,``).toLowerCase();if(e===t||e.includes(t)||t.includes(e)){n.push({obj:r,mtl:i});break}}}return n}async findAndLoadModelFromZip(e){for(let t of[`scene.gltf`,`scene.glb`,`model.gltf`,`model.glb`,`main.gltf`,`main.glb`,`asset.gltf`,`asset.glb`])if(e[t]){console.log(`Found main model file: ${t}`);let n=t.split(`.`).pop().toLowerCase();return await this.loadModelFromZipEntry(e[t],t,n,e)}for(let t in e){let n=t.split(`.`).pop().toLowerCase();if(Xc[n]&&Xc[n].type===`model`)return console.log(`Loading model file from ZIP: ${t}`),await this.loadModelFromZipEntry(e[t],t,n,e)}throw Error(`No supported model files found in the ZIP archive`)}async loadModelFromZipEntry(e,t,n,r){try{I({isLoading:!0,status:`Processing ${n.toUpperCase()} from ZIP...`,progress:5});let i=new Blob([e.buffer],{type:`application/octet-stream`}),a=URL.createObjectURL(i),o;switch(n){case`glb`:case`gltf`:o=await this.handleGltfFromZip(n,e,t,r);break;case`fbx`:o=await this.loadFBXFromArrayBuffer(e.buffer,t);break;case`obj`:o=await this.handleObjFromZip(e,t,r);break;case`stl`:o=await this.loadSTLFromArrayBuffer(e.buffer,t);break;case`ply`:o=await this.loadPLYFromArrayBuffer(e.buffer,t);break;case`dae`:{let n=(0,p.strFromU8)(e),r=new File([new Blob([n])],t);o=await this.loadColladaFromFile(r,t)}break;case`3mf`:o=await this.load3MFFromArrayBuffer(e.buffer,t);break;case`usdz`:o=await this.loadUSDZFromArrayBuffer(e.buffer,t);break;default:throw Error(`Support for ${n} files is not yet implemented`)}return URL.revokeObjectURL(a),this.dispatchEvent({type:`load`,model:this.targetModel,filename:`${t} (from ZIP)`}),o}catch(e){throw console.error(`Error loading ${n} from ZIP:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async handleGltfFromZip(e,t,n,i){if(e===`gltf`){let e=(0,p.strFromU8)(t),a=new r.LoadingManager,o=n.split(`/`).slice(0,-1).join(`/`);a.setURLModifier(e=>this.resolveZipResource(e,o,i));let s=await this.createGLTFLoader();s.manager=a;try{return await new Promise((t,n)=>{s.parse(e,``,e=>{this.releaseTargetModel(),this.targetModel=e.scene,this.onModelLoad(this.targetModel).then(()=>t(e))},e=>n(e))})}finally{this._disposeGLTFLoader(s)}}else return await this.loadGLBFromArrayBuffer(t.buffer,n)}async handleObjFromZip(e,t,n){let r=(0,p.strFromU8)(e),i=r.match(/mtllib\s+([^\s]+)/),a=null;i&&i[1]&&(a=await this.loadMtlFromZip(i[1],t,n));let{OBJLoader:o}=await import(`three/examples/jsm/loaders/OBJLoader.js`),s=new o;a&&s.setMaterials(a);let c=s.parse(r);return c.name=t,this.releaseTargetModel(),this.targetModel=c,await this.onModelLoad(this.targetModel),c}async loadMtlFromZip(e,t,n){let i=t.split(`/`).slice(0,-1).join(`/`),a=[e,`${i}/${e}`,e.split(`/`).pop()];for(let e of a)if(n[e]){let{MTLLoader:t}=await import(`three/examples/jsm/loaders/MTLLoader.js`),a=(0,p.strFromU8)(n[e]),o=new r.LoadingManager;o.setURLModifier(e=>this.resolveZipResource(e,i,n));let s=new t(o).parse(a,i);return s.preload(),s}return null}resolveZipResource(e,t,n){let r=e.replace(/^\.\/|^\//,``),i=[r,`${t}/${r}`,r.split(`/`).pop()];for(let e of i)if(n[e]){let t=new Blob([n[e].buffer],{type:`application/octet-stream`});return URL.createObjectURL(t)}return console.warn(`Resource not found in ZIP: ${e}`),e}async loadOBJMTLPairFromZip(e,t,n,i){let{MTLLoader:a}=await import(`three/examples/jsm/loaders/MTLLoader.js`),{OBJLoader:o}=await import(`three/examples/jsm/loaders/OBJLoader.js`),s=[],c=new r.LoadingManager,l=e.path.split(`/`).slice(0,-1).join(`/`),u=t.path.split(`/`).slice(0,-1).join(`/`);c.setURLModifier(e=>this.resolveTextureInZip(e,l,u,t,n,s));let d=this.prepareFixedMtlContent(t),f=new a(c).parse(d,u);f.preload();let m=new o(c);m.setMaterials(f);let h=(0,p.strFromU8)(e.content),g=m.parse(h);return this.releaseTargetModel(),this.targetModel=g,await this.onModelLoad(this.targetModel),s.forEach(e=>URL.revokeObjectURL(e)),this.dispatchEvent({type:`load`,model:g,filename:`${e.path} (from ${i})`}),g}prepareFixedMtlContent(e){return(0,p.strFromU8)(e.content).replace(RegExp(`${e.path.split(`/`).pop()}\\s+`,`g`),` `).replace(/([a-zA-Z_]+)([\\/])/g,`$1 $2`)}resolveTextureInZip(e,t,n,r,i,a){let o=e.split(`?`)[0].split(`#`)[0].replace(/^\.\/|^\//,``),s=r.path.split(`/`).pop();o.startsWith(s)&&(o=o.substring(s.length).replace(/^\.\/|^\/|^\./,``));let c=[o,`${t}/${o}`,`${n}/${o}`,`textures/${o}`,`texture/${o}`,`materials/${o}`,o.split(`/`).pop()];for(let e of c)if(i[e]){let t=new Blob([i[e].buffer],{type:`application/octet-stream`}),n=URL.createObjectURL(t);return a.push(n),n}return this.findTextureWithFuzzyMatch(o,i,a)||e}findTextureWithFuzzyMatch(e,t,n){let r=e.split(`/`).pop();for(let e in t)if(e.endsWith(r)){let r=new Blob([t[e].buffer],{type:`application/octet-stream`}),i=URL.createObjectURL(r);return n.push(i),i}if(r&&r.length>5)for(let e in t){let i=e.split(`/`).pop();if(i.includes(r)||r.includes(i)){let r=new Blob([t[e].buffer],{type:`application/octet-stream`}),i=URL.createObjectURL(r);return n.push(i),i}}return null}async createGLTFLoader(){let{dracoDecoderPath:e,ktx2TranscoderPath:t}=na(),n=new c.DRACOLoader;n.setDecoderConfig({type:`js`}),n.setDecoderPath(e);let r=new l.KTX2Loader;r.setTranscoderPath(t),this.renderer&&(r.detectSupport(this.renderer),r.workerConfig={astcSupported:!1,etc1Supported:!1,etc2Supported:!1,dxtSupported:!1,bptcSupported:!1,pvrtcSupported:!1});let i=new o.GLTFLoader(this._loadingManager);return i.setDRACOLoader(n),i.setKTX2Loader(r),i.setMeshoptDecoder(f.MeshoptDecoder),i}_disposeGLTFLoader(e){e&&(e.dracoLoader?.dispose(),e.ktx2Loader?.dispose())}async loadExampleModels(e,t){if(!t||!t[e])throw Error(`No model file at index ${e}`);let n=`${t[e].url}`;return await this.loadModel(n)}async loadModel(t){this._loadCancelled=!1;let n=await this.createGLTFLoader(),r=e._isNetworkUrl(t);try{I({isLoading:!0,status:`Downloading Model...`,progress:2,canCancel:r,loadedBytes:0,totalBytes:0});let e=await n.loadAsync(t,this._downloadProgress(`Downloading Model...`,r));return this._downloadComplete(),this.releaseTargetModel(),this.targetModel=e.scene,this.animations=e.animations||[],await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:e.scene,filename:t.split(`/`).pop()}),e}catch(e){throw this._isCancellation(e)?this._cancellationError():(console.error(`Error loading model:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e)}finally{this._disposeGLTFLoader(n)}}_processAndParent(e){this.processModelObjects(e),this.scene.add(e),e.updateMatrixWorld(!0)}async appendModel(t){this._loadCancelled=!1;let n=await this.createGLTFLoader(),r=e._isNetworkUrl(t);try{I({isLoading:!0,status:`Downloading Model...`,progress:2,canCancel:r,loadedBytes:0,totalBytes:0});let e=await n.loadAsync(t,this._downloadProgress(`Downloading Model...`,r));return this._downloadComplete(),this._processAndParent(e.scene),{root:e.scene,animations:e.animations||[]}}catch(e){throw this._isCancellation(e)?this._cancellationError():e}finally{this._disposeGLTFLoader(n)}}appendObject3D(e,t=`object3d`){return e.name=e.name||t,this._processAndParent(e),{root:e}}removeModelRoot(e,{external:t=!1}={}){e&&(t?e.parent?.remove(e):R(e))}async loadGLBFromArrayBuffer(e,t=`model.glb`){let n=await this.createGLTFLoader();try{I({isLoading:!0,status:`Processing GLB Data...`,progress:5}),await new Promise(e=>setTimeout(e,0));let r=await n.parseAsync(e,``);return this.releaseTargetModel(),this.targetModel=r.scene,this.animations=r.animations||[],I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r.scene,filename:t}),r}catch(e){throw console.error(`Error loading GLB:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}finally{this._disposeGLTFLoader(n)}}async loadFBXFromArrayBuffer(e,t=`model.fbx`){try{if(I({isLoading:!0,status:`Processing FBX Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.fbx){let{FBXLoader:e}=await import(`three/examples/jsm/loaders/FBXLoader.js`);this.loaderCache.fbx=new e}let n=this.loaderCache.fbx.parse(e);return this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading FBX:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadOBJFromFile(e,t=`model.obj`){try{if(I({isLoading:!0,status:`Processing OBJ Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.obj){let{OBJLoader:e}=await import(`three/examples/jsm/loaders/OBJLoader.js`);this.loaderCache.obj=new e}let n=await this.readFileAsText(e),r=this.loaderCache.obj.parse(n);return r.name=t,this.releaseTargetModel(),this.targetModel=r,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r,filename:t}),r}catch(e){throw console.error(`Error loading OBJ:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadSTLFromArrayBuffer(e,t=`model.stl`){try{if(I({isLoading:!0,status:`Processing STL Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.stl){let{STLLoader:e}=await import(`three/examples/jsm/loaders/STLLoader.js`);this.loaderCache.stl=new e}let n=new r.Mesh(this.loaderCache.stl.parse(e),new r.MeshStandardMaterial);return n.name=t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading STL:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadPLYFromArrayBuffer(e,t=`model.ply`){try{if(I({isLoading:!0,status:`Processing PLY Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.ply){let{PLYLoader:e}=await import(`three/examples/jsm/loaders/PLYLoader.js`);this.loaderCache.ply=new e}let n=this.loaderCache.ply.parse(e),i;if(n.index!==null)i=new r.Mesh(n,new r.MeshStandardMaterial);else{let e=new r.PointsMaterial({size:.01});e.vertexColors=n.hasAttribute(`color`),i=new r.Points(n,e)}return i.name=t,this.releaseTargetModel(),this.targetModel=i,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:i,filename:t}),i}catch(e){throw console.error(`Error loading PLY:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadColladaFromFile(e,t=`model.dae`){try{if(I({isLoading:!0,status:`Processing Collada Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.collada){let{ColladaLoader:e}=await import(`three/examples/jsm/loaders/ColladaLoader.js`);this.loaderCache.collada=new e}let n=await this.readFileAsText(e),r=this.loaderCache.collada.parse(n);return r.scene.name=t,this.releaseTargetModel(),this.targetModel=r.scene,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:r.scene,filename:t}),r}catch(e){throw console.error(`Error loading Collada:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async load3MFFromArrayBuffer(e,t=`model.3mf`){try{if(I({isLoading:!0,status:`Processing 3MF Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.threemf){let{ThreeMFLoader:e}=await import(`three/examples/jsm/loaders/3MFLoader.js`);this.loaderCache.threemf=new e}let n=this.loaderCache.threemf.parse(e);return this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading 3MF:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadUSDZFromArrayBuffer(e,t=`model.usdz`){try{if(I({isLoading:!0,status:`Processing USDZ Data...`,progress:5}),await new Promise(e=>setTimeout(e,0)),!this.loaderCache.usdz){let{USDZLoader:e}=await import(`three/examples/jsm/loaders/USDZLoader.js`);this.loaderCache.usdz=new e}let n=this.loaderCache.usdz.parse(e);return n.name=t,this.releaseTargetModel(),this.targetModel=n,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n,filename:t}),n}catch(e){throw console.error(`Error loading USDZ:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadObject3D(e,t=`object3d`){return e.name=e.name||t,this.releaseTargetModel(),this.targetModel=e,this._externalModel=e,I({isLoading:!0,status:`Processing Data...`,progress:10}),await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:e,filename:t}),e}async onModelLoad(e){let t=new Wi(`onModelLoad`);t.start(`Camera extraction`);let n=this.extractCamerasFromModel(e);t.end(`Camera extraction`),t.start(`Camera setup`);let i=new r.Box3().setFromObject(e),a=i.getCenter(new r.Vector3),o=i.getSize(new r.Vector3);this.controls.target.copy(a);let s=Math.max(o.x,o.y,o.z),c=this.camera.fov*(Math.PI/180),l=Math.abs(s/Math.sin(c/2)/2),u=Math.PI/6,d=new r.Vector3(Math.cos(u)*l,l/Math.sqrt(2),Math.sin(u)*l);if(this.camera.position.copy(d.add(a)),this.camera.lookAt(a),this.camera.near=s/100,this.camera.far=s*100,this.camera.updateProjectionMatrix(),this.controls.maxDistance=l*10,this.controls.saveState(),this.controls.update(),t.end(`Camera setup`),this.floorPlane){let e=i.min.y;this.floorPlane.position.y=e,this.floorPlane.rotation.x=-Math.PI/2,this.floorPlane.scale.setScalar(s*5)}t.start(`Process model objects`),this.processModelObjects(e),t.end(`Process model objects`),t.start(`Scene add`),this.scene.add(e),t.end(`Scene add`);let f=s;return t.start(`setupPathTracing`),await this.setupPathTracing(e,f),t.end(`setupPathTracing`),t.print(),this.dispatchEvent({type:`modelProcessed`,model:e,cameras:n,sceneData:{center:a,size:o,maxDim:s,sceneScale:f}}),this.dispatchEvent({type:`SceneRebuild`}),{center:a,size:o,maxDim:s,sceneScale:f}}extractCamerasFromModel(e){let t=[];return e.updateWorldMatrix(!0,!0),e.traverse(e=>{if(e.isCamera){let n=e.clone();e.getWorldPosition(n.position),e.getWorldQuaternion(n.quaternion),(!n.name||n.name===``)&&(n.name=`Model Camera ${t.length+1}`),n.isPerspectiveCamera&&(n.aspect=this.camera.aspect,n.updateProjectionMatrix()),t.push(n)}}),t}processModelObjects(e){let t=[];e.traverse(e=>{let n=e.userData;if(e.isRectAreaLight&&!t.includes(e.uuid)&&t.push(e.uuid),e.name.startsWith(`RectAreaLightPlaceholder`)&&n.name&&n.type===`RectAreaLight`){let i=new r.RectAreaLight(new r.Color(...n.color),n.intensity*.1,n.width,n.height);i.userData.normalize=n.normalize??!0,i.userData.spread=Number.isFinite(n.spread)?n.spread:Math.PI,i.userData.shape=n.shape??`rectangle`,i.position.z=-2,i.name=n.name,e.add(i),t.push(i.uuid)}if(e.isMesh&&Array.isArray(e.material)){console.log(`Found multi-material mesh:`,e.name);let t=(0,d.createMeshesFromMultiMaterialMesh)(e);e.parent&&(e.parent.add(t),e.parent.remove(e))}})}async setupPathTracing(e,t){this.sceneScale=t}createFloorPlane(){this.floorPlane=new r.Mesh(new r.CircleGeometry,new r.MeshPhysicalMaterial({transparent:!1,color:3158064,roughness:1,metalness:0,opacity:0,transmission:0})),this.floorPlane.name=`Ground`,this.floorPlane.visible=!1,this.scene.add(this.floorPlane)}setFloorPlane(e){this.floorPlane=e}getSceneScale(){return this.sceneScale}getTargetModel(){return this.targetModel}getSupportedFormats(e=null){if(e){let t={};for(let[n,r]of Object.entries(Xc))r.type===e&&(t[n]=r);return t}return Xc}dispose(){for(let e in this.loaderCache){let t=this.loaderCache[e];t&&typeof t.dispose==`function`&&t.dispose()}this.loaderCache={},this._listeners=void 0,this.releaseTargetModel()}removeAllEventListeners(){this._listeners=void 0}},Qc={maxBounces:{uniform:`maxBounces`,reset:!0},transmissiveBounces:{uniform:`transmissiveBounces`,reset:!0},maxSubsurfaceSteps:{uniform:`maxSubsurfaceSteps`,reset:!0},environmentIntensity:{uniform:`environmentIntensity`,reset:!0},backgroundIntensity:{uniform:`backgroundIntensity`,reset:!0},backgroundBlurriness:{uniform:`backgroundBlurriness`,reset:!0},backgroundBlurSamples:{uniform:`backgroundBlurSamples`,reset:!0},showBackground:{uniform:`showBackground`,reset:!0},enableEnvironment:{uniform:`enableEnvironment`,reset:!0},groundProjectionEnabled:{uniform:`groundProjectionEnabled`,reset:!0},groundProjectionRadius:{uniform:`groundProjectionRadius`,reset:!0},groundProjectionHeight:{uniform:`groundProjectionHeight`,reset:!0},groundProjectionLevel:{uniform:`groundProjectionLevel`,reset:!0},enableGroundCatcher:{uniform:`enableGroundCatcher`,reset:!0},groundCatcherHeight:{uniform:`groundCatcherHeight`,reset:!0},globalIlluminationIntensity:{uniform:`globalIlluminationIntensity`,reset:!0},enableDOF:{uniform:`enableDOF`,reset:!0},focusDistance:{uniform:`focusDistance`,reset:!1},focalLength:{uniform:`focalLength`,reset:!0},aperture:{uniform:`aperture`,reset:!0},apertureScale:{uniform:`apertureScale`,reset:!0},anamorphicRatio:{uniform:`anamorphicRatio`,reset:!0},samplingTechnique:{uniform:`samplingTechnique`,reset:!0},fireflyThreshold:{uniform:`fireflyThreshold`,reset:!0},enableAlphaShadows:{uniform:`enableAlphaShadows`,reset:!0},enableEmissiveTriangleSampling:{uniform:`enableEmissiveTriangleSampling`,reset:!0},emissiveBoost:{uniform:`emissiveBoost`,reset:!0},visMode:{uniform:`visMode`,reset:!0},debugVisScale:{uniform:`debugVisScale`,reset:!0},interactionModeEnabled:{handler:`handleInteractionModeEnabled`,reset:!1},maxSamples:{handler:`handleMaxSamples`,reset:!1},transparentBackground:{handler:`handleTransparentBackground`},backgroundColor:{handler:`handleBackgroundColor`,reset:!0},exposure:{handler:`handleExposure`},saturation:{handler:`handleSaturation`},renderLimitMode:{handler:`handleRenderLimitMode`},renderTimeLimit:{handler:`handleRenderTimeLimit`,reset:!1},renderMode:{handler:`handleRenderMode`},environmentRotation:{handler:`handleEnvironmentRotation`}},$c={bounces:`maxBounces`,debugMode:`visMode`},el=class extends r.EventDispatcher{constructor(e=B){super(),this._values=new Map,this._pathTracer=null,this._resetCallback=null,this._handlers={},this._delegates={},this._initDefaults(e)}bind({stages:e,renderer:t,resetCallback:n,reconcileCompletion:r}){this._pathTracer=e.pathTracer,this._resetCallback=n,this._delegates={},this._handlers=this._buildHandlers(e,t,r)}_buildHandlers(e,t,n){return{handleTransparentBackground:t=>{e.pathTracer?.setUniform(`transparentBackground`,t),e.compositor?.setTransparentBackground(t)},handleBackgroundColor:t=>{let n=t?.isColor?t:new r.Color(t);e.pathTracer?.setUniform(`backgroundColor`,n)},handleExposure:n=>{!e.autoExposure?.enabled&&t&&(t.toneMappingExposure=n)},handleSaturation:t=>{e.compositor?.setSaturation(t)},handleRenderLimitMode:t=>{e.pathTracer?.setRenderLimitMode?.(t)},handleMaxSamples:t=>{e.pathTracer?.setUniform(`maxSamples`,t),e.pathTracer?.updateCompletionThreshold(),n?.()},handleRenderTimeLimit:()=>{n?.()},handleRenderMode:t=>{e.pathTracer?.setUniform(`renderMode`,parseInt(t))},handleEnvironmentRotation:t=>{e.pathTracer?.environment.setEnvironmentRotation(t)},handleInteractionModeEnabled:t=>{e.pathTracer?.setInteractionModeEnabled(t)}}}set(e,t,{reset:n,silent:r}={}){let i=this._values.get(e);if(i===t)return;this._values.set(e,t);let a=Qc[e];a&&(this._applyRoute(a,t,i),(n===void 0?a.reset??!0:n)&&this._resetCallback?.(),r||this.dispatchEvent({type:F.SETTING_CHANGED,key:e,value:t,prev:i}))}setMany(e,{silent:t}={}){let n=!1;for(let[r,i]of Object.entries(e)){let e=this._values.get(r);if(e===i)continue;this._values.set(r,i);let a=Qc[r];a&&(this._applyRoute(a,i,e),(a.reset??!0)&&(n=!0),t||this.dispatchEvent({type:F.SETTING_CHANGED,key:r,value:i,prev:e}))}n&&this._resetCallback?.()}get(e){return this._values.get(e)}getAll(){return Object.fromEntries(this._values)}applyAll(){for(let[e,t]of this._values){let n=Qc[e];n&&this._applyRoute(n,t,void 0)}}_applyRoute(e,t,n){e.uniform?(this._pathTracer?.setUniform(e.uniform,t),e.after&&this._pathTracer?.[e.after]?.()):e.handler?this._handlers[e.handler]?.(t,n):e.delegate&&this._delegates[e.delegate]?.updateParam?.(e.param,t)}_initDefaults(e){for(let t of Object.keys(Qc))t in e&&this._values.set(t,e[t]);for(let[t,n]of Object.entries($c))t in e&&this._values.set(n,e[t])}},tl=class extends r.EventDispatcher{constructor(e){super();let t=e.clientWidth,n=e.clientHeight;this.camera=new r.PerspectiveCamera(60,t/n||1,.01,1e3),this.camera.position.set(0,0,5),this.controls=new m.OrbitControls(this.camera,e),this.controls.screenSpacePanning=!0,this.controls.zoomToCursor=!0,this.controls.saveState(),this.interactionManager=null,this.cameras=[this.camera],this.currentCameraIndex=0,this.autoFocusMode=Ne.SMOOTHING_FACTOR?`auto`:`manual`,this.afScreenPoint={x:.5,y:.5},this.afSmoothingFactor=Ne.SMOOTHING_FACTOR,this._lastValidFocusDistance=null,this._smoothedFocusDistance=null,this._afPointDirty=!1,this._afSuspended=!1,this._defaultCameraState=null,this._onResize=null,this._onReset=null,this._getSettings=null}setCameras(e){this.cameras=e}getCameraNames(){return!this.cameras||this.cameras.length===0?[`Default Camera`]:this.cameras.map((e,t)=>t===0?`Default Camera`:e.name||`Camera ${t}`)}initCallbacks({onResize:e,onReset:t,getSettings:n}){this._onResize=e,this._onReset=t,this._getSettings=n}switchCamera(e,t,n,i){if(t??=this._getSettings?.(`focusDistance`),n??=this._onResize,i??=this._onReset,!(!this.cameras||this.cameras.length===0)){if((e<0||e>=this.cameras.length)&&(console.warn(`CameraManager: Invalid camera index ${e}. Using default camera.`),e=0),this.currentCameraIndex===0&&e!==0&&(this._defaultCameraState={position:this.camera.position.clone(),quaternion:this.camera.quaternion.clone(),fov:this.camera.fov,near:this.camera.near,far:this.camera.far,target:this.controls?this.controls.target.clone():null}),this.currentCameraIndex=e,e===0&&this._defaultCameraState){let e=this._defaultCameraState;this.camera.position.copy(e.position),this.camera.quaternion.copy(e.quaternion),this.camera.fov=e.fov,this.camera.near=e.near,this.camera.far=e.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls&&e.target&&(this.controls.target.copy(e.target),this.controls.update())}else{let n=this.cameras[e];if(this.camera.position.copy(n.position),this.camera.quaternion.copy(n.quaternion),this.camera.fov=n.fov,this.camera.near=n.near,this.camera.far=n.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls){let e=new r.Vector3(0,0,-1).applyQuaternion(n.quaternion),i=t||5;this.controls.target.copy(this.camera.position).addScaledVector(e,i),this.controls.update()}}n?.(),i?.(),this.dispatchEvent({type:`CameraSwitched`,cameraIndex:e})}}focusOn(e){!e||!this.controls||(this.controls.target.copy(e),this.controls.update(),this._onReset?.())}get active(){return this.camera}getNames(){return this.getCameraNames()}setAutoFocusMode(e){this.autoFocusMode=e,e!==`manual`&&(this._smoothedFocusDistance=null,this._afPointDirty=!0)}setAFScreenPoint(e,t){this.afScreenPoint={x:e,y:t},this._afPointDirty=!0}enterAFPointPlacementMode(){this.interactionManager&&(this.interactionManager.enterAFPointPlacementMode(),this.controls&&(this.controls.enabled=!1))}exitAFPointPlacementMode(){this.interactionManager&&(this.interactionManager.exitAFPointPlacementMode(),this.controls&&(this.controls.enabled=!0))}updateAutoFocus(e){let{meshScene:t,assetLoader:n,floorPlane:r,currentFocusDistance:i,pathTracer:a,setFocusDistance:o,softReset:s,hardReset:c}=e||this._afContext||{};if(!t||this.autoFocusMode===`manual`)return;if(!a?.enableDOF?.value){this._afSuspended=!0;return}this._afSuspended&&(this._afSuspended=!1,this._smoothedFocusDistance=null);let l=a;if(l?.isReady&&l.renderMode?.value===1&&l.frameCount>0&&!l.isComplete)return;let u=this.afScreenPoint.x*2-1,d=-(this.afScreenPoint.y*2-1),f=this.interactionManager?.raycaster;if(!f)return;f.setFromCamera({x:u,y:d},this.camera);let p=f.intersectObjects(t.children,!0).find(e=>e.object!==this.interactionManager?.focusPointIndicator&&e.object!==r&&!e.object.name.includes(`Helper`)&&e.object.type===`Mesh`),m;if(p)m=p.distance,this._lastValidFocusDistance=m;else if(this._lastValidFocusDistance!==null)m=this._lastValidFocusDistance;else{let e=n?.getSceneScale()||1;m=Ne.FALLBACK_DISTANCE*e,this._lastValidFocusDistance=m}let h=this._afPointDirty;this._afPointDirty=!1,h||this._smoothedFocusDistance===null||this._smoothedFocusDistance===0||Math.abs(m-this._smoothedFocusDistance)/this._smoothedFocusDistance>Ne.SNAP_THRESHOLD?this._smoothedFocusDistance=m:this._smoothedFocusDistance+=this.afSmoothingFactor*(m-this._smoothedFocusDistance);let g=i,_=this._smoothedFocusDistance;if(h||g===0||Math.abs(_-g)/Math.max(g,.001)>.001){o(_);let e=n?.getSceneScale()||1;this.dispatchEvent({type:F.AUTO_FOCUS_UPDATED,distance:_/e});let t=Math.abs(_-g)/Math.max(g,.001);h?c?.():t>Ne.RESET_THRESHOLD&&s?.()}}setInteractionManager(e){this.interactionManager=e}initAutoFocus({meshScene:e,assetLoader:t,floorPlane:n,pathTracer:r,settings:i,softReset:a,hardReset:o}){this._afContext={meshScene:e,assetLoader:t,floorPlane:n,pathTracer:r,setFocusDistance:e=>i.set(`focusDistance`,e,{silent:!0}),softReset:a,hardReset:o},Object.defineProperty(this._afContext,`currentFocusDistance`,{get:()=>i.get(`focusDistance`)})}dispose(){this.controls?.dispose()}},nl=class extends r.EventDispatcher{constructor(e,t,n,r={}){super(),this.scene=e,this.sceneHelpers=t,this.pathTracer=n,this._onReset=r.onReset||null}addLight(e){let t={DirectionalLight:{position:[1,1,1],intensity:1,color:`#ffffff`},PointLight:{position:[0,2,0],intensity:1e3,color:`#ffffff`},SpotLight:{position:[0,1,0],intensity:1e3,color:`#ffffff`,angle:15},RectAreaLight:{position:[0,2,0],intensity:100,color:`#ffffff`,width:2,height:2}}[e];if(!t)return null;let n;if(e===`DirectionalLight`)n=new r.DirectionalLight(t.color,t.intensity),n.position.fromArray(t.position);else if(e===`PointLight`)n=new r.PointLight(t.color,t.intensity),n.position.fromArray(t.position);else if(e===`SpotLight`){n=new r.SpotLight(t.color,t.intensity),n.position.fromArray(t.position),n.angle=r.MathUtils.degToRad(t.angle);let e=new r.Object3D;this.scene.add(e),n.target=e}else e===`RectAreaLight`&&(n=new r.RectAreaLight(t.color,t.intensity,t.width,t.height),n.position.fromArray(t.position),n.lookAt(0,0,0),n.userData.normalize=!0,n.userData.spread=Math.PI,n.userData.shape=`rectangle`);n.userData.temperature=6500,n.userData.useTemperature=!1,n.userData.exposure=0;let i=this.scene.getObjectsByProperty(`isLight`,!0).length;return n.name=`${e.replace(`Light`,``)} ${i+1}`,this.scene.add(n),this.updateLights(),this._syncHelpers(),this._onReset?.(),this._buildDescriptor(n)}removeLight(e){let t=this.scene.getObjectByProperty(`uuid`,e);return!t||!t.isLight?!1:(this.sceneHelpers.remove(t),t.target&&t.target.removeFromParent(),t.removeFromParent(),this.updateLights(),this._onReset?.(),!0)}clearLights(){this.sceneHelpers.clear(),this._removeAllLights(),this.updateLights(),this._onReset?.()}getLights(){return this.scene.getObjectsByProperty(`isLight`,!0).map(e=>this._buildDescriptor(e))}updateLights(){this.pathTracer?.updateLights(),this.sceneHelpers?.visible&&this.sceneHelpers.update()}transferSceneLights(e){this._removeAllLights();let t=e.getObjectsByProperty(`isLight`,!0);if(!t||t.length===0){this.updateLights();return}for(let e of t){let t=e.clone();if(e.updateWorldMatrix(!0,!1),e.getWorldPosition(t.position),e.getWorldQuaternion(t.quaternion),e.getWorldScale(t.scale),t.isRectAreaLight&&(t.width*=t.scale.x,t.height*=t.scale.y,t.scale.set(1,1,1)),(e.isSpotLight||e.isDirectionalLight)&&e.target){let n=new r.Object3D;e.target.updateWorldMatrix(!0,!1),e.target.getWorldPosition(n.position),this.scene.add(n),t.target=n}this.scene.add(t)}this.updateLights(),this._syncHelpers()}setShowLightHelper(e){this.sceneHelpers.visible=e,e?this._syncHelpers():this.sceneHelpers.clear()}add(e){return this.addLight(e)}remove(e){return this.removeLight(e)}clear(){this.clearLights()}getAll(){return this.getLights()}sync(){this.updateLights()}showHelpers(e){this.setShowLightHelper(e)}dispose(){this._disposed||(this._disposed=!0,this.sceneHelpers?.clear(),this._removeAllLights(),this._onReset=null,this.pathTracer=null,this.sceneHelpers=null,this.scene=null)}_removeAllLights(){this.scene.getObjectsByProperty(`isLight`,!0).forEach(e=>{e.target&&this.scene.remove(e.target),this.scene.remove(e)})}_syncHelpers(){if(!this.sceneHelpers.visible)return;let e=this.scene.getObjectsByProperty(`isLight`,!0);this.sceneHelpers.sync(e)}_buildDescriptor(e){let t=0;e.type===`SpotLight`&&e.angle!==void 0&&(t=r.MathUtils.radToDeg(e.angle));let n={uuid:e.uuid,name:e.name,type:e.type,intensity:e.intensity,color:`#${e.color.getHexString()}`,position:[e.position.x,e.position.y,e.position.z],angle:t,temperature:e.userData?.temperature??6500,useTemperature:e.userData?.useTemperature??!1,exposure:e.userData?.exposure??0};if(e.type===`RectAreaLight`){n.width=e.width,n.height=e.height,n.normalize=e.userData?.normalize??!0,n.spread=r.MathUtils.radToDeg(e.userData?.spread??Math.PI);let t=e.userData?.shape;n.shape=t===`square`||t===`rectangle`||t===`disk`||t===`ellipse`?t:t===1?`ellipse`:`rectangle`;let i=e.getWorldDirection(e.position.clone());n.target=[e.position.x+i.x,e.position.y+i.y,e.position.z+i.z]}else e.type===`SpotLight`&&e.target?(n.target=[e.target.position.x,e.target.position.y,e.target.position.z],n.distance=e.distance??0,n.penumbra=e.penumbra??0,n.decay=e.decay??2):e.type===`PointLight`&&(n.distance=e.distance??0,n.decay=e.decay??2);return(e.type===`SpotLight`||e.type===`DirectionalLight`)&&e.userData?.gobo&&(n.gobo=e.userData.gobo.name,n.goboIntensity=e.userData.gobo.intensity,n.goboInverted=!!e.userData.gobo.inverted,e.type===`DirectionalLight`&&(n.goboScale=e.userData.gobo.scale??5)),e.type===`SpotLight`&&e.userData?.ies&&(n.ies=e.userData.ies.name,n.iesIntensity=e.userData.ies.intensity??1,n.fixtureLumens=e.userData.ies.fixtureLumens??null),n}},rl=class{constructor(e,t={}){this.pathTracer=e,this._onReset=t.onReset||null,this.texture=null,this.entries=[],this._size=256}async loadLibrary(e,{size:t=256}={}){if(!Array.isArray(e)||e.length===0)return[];this._size=t;let n=await Promise.all(e.map(e=>il(e.url))),i=t,a=t,o=n.length,s=new Uint8Array(i*a*o*4),c=document.createElement(`canvas`);c.width=i,c.height=a;let l=c.getContext(`2d`,{willReadFrequently:!0});for(let e=0;e<o;e++){l.clearRect(0,0,i,a),l.drawImage(n[e],0,0,i,a);let t=l.getImageData(0,0,i,a);s.set(t.data,e*i*a*4)}let u=new r.DataArrayTexture(s,i,a,o);u.minFilter=r.LinearFilter,u.magFilter=r.LinearFilter,u.format=r.RGBAFormat,u.type=r.UnsignedByteType,u.generateMipmaps=!1,u.needsUpdate=!0;let d=this.texture;return this.texture=u,this.entries=e.map((e,t)=>({name:e.name,index:t})),this.pathTracer.goboMaps=u,this.pathTracer.shaderBuilder?.updateGoboMaps?.(u),d?.dispose?.(),this.entries}getEntries(){return this.entries.slice()}setLightGobo(e,t,n={}){let{intensity:r=1,inverted:i=!1,scale:a=5}=n,o=this._findGoboLight(e);if(!o)return!1;if(o.userData=o.userData||{},t==null)delete o.userData.gobo;else{let e=this.entries.find(e=>e.name===t);if(!e)return console.warn(`GoboManager: unknown gobo "${t}"`),!1;o.userData.gobo={name:e.name,index:e.index,intensity:al(r),inverted:!!i,scale:Math.max(1e-4,a)}}return this.pathTracer.updateLights(),this._onReset?.(),!0}setLightGoboInverted(e,t){let n=this._findGoboLight(e);return n?.userData?.gobo?(n.userData.gobo.inverted=!!t,this.pathTracer.updateLights(),this._onReset?.(),!0):!1}setLightGoboScale(e,t){let n=this._findGoboLight(e);return n?.userData?.gobo?(n.userData.gobo.scale=Math.max(1e-4,t),this.pathTracer.updateLights(),this._onReset?.(),!0):!1}getLightGobo(e){return this._findGoboLight(e)?.userData?.gobo||null}setSpotLightGobo(e,t,n=1,r=!1){return this.setLightGobo(e,t,{intensity:n,inverted:r})}setSpotLightGoboInverted(e,t){return this.setLightGoboInverted(e,t)}getSpotLightGobo(e){return this.getLightGobo(e)}dispose(){this.texture?.dispose?.(),this.texture=null,this.entries=[],this.pathTracer=null,this._onReset=null}_findGoboLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&(t.isSpotLight||t.isDirectionalLight)?t:null}_findSpotLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&t.isSpotLight?t:null}};function il(e){return new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>t(r),r.onerror=()=>n(Error(`Failed to load gobo image: ${e}`)),r.src=e})}function al(e){return Math.max(0,Math.min(1,e))}function ol(e,t=`ies`){let n=e.search(/TILT\s*=/i);if(n<0)throw Error(`IES (${t}): missing TILT line`);let r=e.indexOf(`
734
+ `,n);if(r<0)throw Error(`IES (${t}): truncated TILT line`);let i=e.slice(n,r).match(/TILT\s*=\s*(\w+)/i),a=i?i[1].toUpperCase():`NONE`,o=e.slice(r);if(a===`INCLUDE`){let e=ul(o),t=2+2*Number(e[1]);o=dl(o,t)}let s=ul(o),c=0,l=()=>Number(s[c++]),u=l(),d=l(),f=l(),p=l(),m=l(),h=l();l(),l(),l(),l();let g=l();if(l(),l(),!Number.isFinite(p)||p<=0)throw Error(`IES (${t}): invalid vertical angle count ${p}`);if(!Number.isFinite(m)||m<=0)throw Error(`IES (${t}): invalid horizontal angle count ${m}`);let _=Array(p);for(let e=0;e<p;e++)_[e]=l();let v=Array(m);for(let e=0;e<m;e++)v[e]=l();let y=Array(p);for(let e=0;e<p;e++)y[e]=new Float32Array(m);let b=f*g,x=0;for(let e=0;e<m;e++)for(let t=0;t<p;t++){let n=l()*b;y[t][e]=n,n>x&&(x=n)}return{verticalAngles:_,horizontalAngles:v,candela:y,maxCandela:x,lumens:d*u,photometricType:h,name:t}}function sl(e,t,n){let r=new Uint8Array(t*n),{verticalAngles:i,horizontalAngles:a,candela:o,maxCandela:s}=e;if(s<=0)return r;let c=i[i.length-1],l=a[a.length-1],u=a[0],d=a.length===1||l===u;for(let e=0;e<n;e++){let f=(e+.5)/n*c,p=fl(i,f),m=Math.min(p+1,i.length-1),h=i[m]-i[p],g=h>0?(f-i[p])/h:0;for(let n=0;n<t;n++){let i;if(d)i=pl(o[p][0],o[m][0],g);else{let e=u+(n+.5)/t*(l-u),r=fl(a,e),s=Math.min(r+1,a.length-1),c=a[s]-a[r],d=c>0?(e-a[r])/c:0,f=o[p][r],h=o[p][s],_=o[m][r],v=o[m][s];i=pl(pl(f,h,d),pl(_,v,d),g)}let c=Math.min(1,Math.max(0,i/s));r[e*t+n]=Math.round(c*255)}}return r}function cl(e,t=.1){let{verticalAngles:n,horizontalAngles:r,candela:i,maxCandela:a}=e,o=Math.PI/4;if(a<=0||!n?.length)return o;let s=a*t,c=r.length,l=n[n.length-1],u=!1;for(let e=0;e<n.length;e++){let t=0;for(let n=0;n<c;n++)t+=i[e][n];if(t/=c,t>=s&&(u=!0),u&&t<s){l=n[e];break}}let d=l*Math.PI/180;return Math.min(Math.max(d,5*Math.PI/180),89*Math.PI/180)}function ll(e,t,n=.7){let{verticalAngles:r,horizontalAngles:i,candela:a,maxCandela:o}=e;if(o<=0||!r?.length||t<=0)return 0;let s=o*n,c=i.length,l=0;for(let e=0;e<r.length;e++){let t=0;for(let n=0;n<c;n++)t+=a[e][n];if(t/=c,t>=s)l=r[e];else break}let u=t*180/Math.PI,d=u>0?1-l/u:0;return Math.min(Math.max(d,0),1)}function ul(e){return e.split(/\s+/).filter(e=>e.length>0)}function dl(e,t){let n=/\S+/g,r=0;for(;n.exec(e)!==null;)if(r++,r===t)return e.slice(n.lastIndex);return``}function fl(e,t){if(t<=e[0])return 0;if(t>=e[e.length-1])return e.length-1;let n=0,r=e.length-1;for(;r-n>1;){let i=n+r>>1;e[i]<=t?n=i:r=i}return n}function pl(e,t,n){return e+(t-e)*n}var ml=class{constructor(e,t={}){this.pathTracer=e,this._onReset=t.onReset||null,this.texture=null,this.entries=[],this._gridWidth=128,this._gridHeight=128}async loadLibrary(e,{gridWidth:t=128,gridHeight:n=128}={}){if(!Array.isArray(e)||e.length===0)return[];this._gridWidth=t,this._gridHeight=n;let i=(await Promise.all(e.map(async e=>{try{let r=await fetch(e.url);if(!r.ok)throw Error(`HTTP ${r.status}`);let i=ol(await r.text(),e.name);return{it:e,profile:i,grid:sl(i,t,n)}}catch(t){return console.warn(`IESManager: failed to load "${e.name}": ${t.message}`),null}}))).filter(e=>e!==null);if(i.length===0)return[];let a=i.length,o=t*n,s=new Uint8Array(o*4*a),c=[];for(let e=0;e<a;e++){let t=i[e].grid,n=e*o*4;for(let e=0;e<o;e++){let r=t[e];s[n+e*4+0]=r,s[n+e*4+1]=r,s[n+e*4+2]=r,s[n+e*4+3]=255}let r=i[e].profile,a=cl(r);c.push({name:i[e].it.name,index:e,maxCandela:r.maxCandela,photometricType:r.photometricType,suggestedAngle:a,suggestedPenumbra:ll(r,a),lumens:r.lumens})}let l=new r.DataArrayTexture(s,t,n,a);l.format=r.RGBAFormat,l.type=r.UnsignedByteType,l.minFilter=r.LinearFilter,l.magFilter=r.LinearFilter,l.generateMipmaps=!1,l.needsUpdate=!0;let u=this.texture;return this.texture=l,this.entries=c,this.pathTracer.iesProfiles=l,this.pathTracer.shaderBuilder?.updateIESProfiles?.(l),u?.dispose?.(),this.entries.map(({name:e,index:t})=>({name:e,index:t}))}getEntries(){return this.entries.slice()}setSpotLightProfile(e,t,n=1,{applyAutoCone:r=!0}={}){let i=this._findSpotLight(e),a={applied:!1,suggestedAngle:null,suggestedPenumbra:null,suggestedDecay:null,fixtureLumens:null};if(!i)return a;i.userData=i.userData||{};let o=null,s=null,c=null,l=null;if(t==null)delete i.userData.ies;else{let e=this.entries.find(e=>e.name===t);if(!e)return console.warn(`IESManager: unknown profile "${t}"`),a;l=Number.isFinite(e.lumens)?e.lumens:null,i.userData.ies={name:e.name,index:e.index,intensity:hl(n),fixtureLumens:l},r&&(Number.isFinite(e.suggestedAngle)&&(i.angle=e.suggestedAngle,o=e.suggestedAngle),Number.isFinite(e.suggestedPenumbra)&&(i.penumbra=e.suggestedPenumbra,s=e.suggestedPenumbra),i.decay=2,c=2)}return this.pathTracer.updateLights(),this._onReset?.(),{applied:!0,suggestedAngle:o,suggestedPenumbra:s,suggestedDecay:c,fixtureLumens:l}}getSpotLightProfile(e){return this._findSpotLight(e)?.userData?.ies||null}dispose(){this.texture?.dispose?.(),this.texture=null,this.entries=[],this.pathTracer=null,this._onReset=null}_findSpotLight(e){let t=this.pathTracer?.scene?.getObjectByProperty?.(`uuid`,e);return t&&t.isSpotLight?t:null}};function hl(e){return Math.max(0,Math.min(1,e))}var gl=e=>Math.min(Math.max(e,0),1);function _l(e,t,n,r,i){i[0]=gl(e),i[1]=gl(t),i[2]=gl(n)}function vl(e,t,n,r,i){i[0]=gl(e*r),i[1]=gl(t*r),i[2]=gl(n*r)}function yl(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=gl(e/(e+1)),i[1]=gl(t/(t+1)),i[2]=gl(n/(n+1))}function bl(e,t,n,r,i){e=Math.max(e*r-.004,0),t=Math.max(t*r-.004,0),n=Math.max(n*r-.004,0);let a=e=>(e*(6.2*e+.5)/(e*(6.2*e+1.7)+.06))**2.2;i[0]=a(e),i[1]=a(t),i[2]=a(n)}function xl(e,t,n,r,i){e=e*r/.6,t=t*r/.6,n=n*r/.6;let a=.59719*e+.35458*t+.04823*n,o=.076*e+.90834*t+.01566*n,s=.0284*e+.13383*t+.83777*n,c=e=>(e*(e+.0245786)-90537e-9)/(e*(.983729*e+.432951)+.238081);a=c(a),o=c(o),s=c(s),i[0]=gl(1.60475*a-.53108*o-.07367*s),i[1]=gl(-.10208*a+1.10813*o-.00605*s),i[2]=gl(-.00327*a-.07276*o+1.07602*s)}function Sl(e,t,n,r,i){e*=r,t*=r,n*=r;let a=.6274*e+.3293*t+.0433*n,o=.0691*e+.9195*t+.0113*n,s=.0164*e+.088*t+.8956*n,c=.856627153315983*a+.0951212405381588*o+.0482516061458583*s,l=.137318972929847*a+.761241990602591*o+.101439036467562*s,u=.11189821299995*a+.0767994186031903*o+.811302368396859*s,d=-12.47393,f=4.026069-d;c=gl((Math.log2(Math.max(c,1e-10))-d)/f),l=gl((Math.log2(Math.max(l,1e-10))-d)/f),u=gl((Math.log2(Math.max(u,1e-10))-d)/f);let p=e=>{let t=e*e,n=t*t;return 15.5*n*t-40.14*n*e+31.96*n-6.868*t*e+.4298*t+.1191*e-.00232};c=p(c),l=p(l),u=p(u);let m=1.1271005818144368*c-.11060664309660323*l-.016493938717834573*u,h=-.1413297634984383*c+1.157823702216272*l-.016493938717834257*u,g=-.14132976349843826*c-.11060664309660294*l+1.2519364065950405*u;m=Math.max(0,m)**2.2,h=Math.max(0,h)**2.2,g=Math.max(0,g)**2.2,i[0]=gl(1.6605*m-.5876*h-.0728*g),i[1]=gl(-.1246*m+1.1329*h-.0083*g),i[2]=gl(-.0182*m-.1006*h+1.1187*g)}function Cl(e,t,n,r,i){let a=.76;e*=r,t*=r,n*=r;let o=Math.min(e,Math.min(t,n)),s=o<.08?o-6.25*o*o:.04;e-=s,t-=s,n-=s;let c=Math.max(e,Math.max(t,n));if(c<a){i[0]=e,i[1]=t,i[2]=n;return}let l=1-a,u=1-l*l/(c+l-a),d=u/c;e*=d,t*=d,n*=d;let f=1-1/(.15*(c-u)+1);i[0]=e+(u-e)*f,i[1]=t+(u-t)*f,i[2]=n+(u-n)*f}var wl=new Map([[r.NoToneMapping,_l],[r.LinearToneMapping,vl],[r.ReinhardToneMapping,yl],[r.CineonToneMapping,bl],[r.ACESFilmicToneMapping,xl],[r.AgXToneMapping,Sl],[r.NeutralToneMapping,Cl]]),Tl=1/2.2;function El(e){return e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055}var Dl=.2126,Ol=.7152,kl=.0722;function Al(e,t){if(t===1)return;let n=e[0]*Dl+e[1]*Ol+e[2]*kl;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}var jl=null,Ml=null;async function Nl(){if(!jl){let[e,t]=await Promise.all([import(`oidn-web`),import(`@tensorflow/tfjs-core`)]);jl=e.initUNetFromURL,Ml=t.engine}return jl}function Pl(){if(Ml)try{let e=Ml();e?.registryFactory&&`webgpu-oidn`in e.registryFactory&&e.removeBackend(`webgpu-oidn`)}catch(e){console.warn(`OIDNDenoiser: failed to clear cached TFJS backend`,e)}}var Fl=new Float32Array(3),Il={QUALITY_MODELS:{fast:`rt_hdr_alb_nrm_small`,balance:`rt_hdr_alb_nrm`,high:`rt_hdr_calb_cnrm_large`},DEFAULT_OPTIONS:{enableOIDN:!0,oidnQuality:`fast`,debugGbufferMaps:!0,tileSize:256}},Ll=class extends r.EventDispatcher{constructor(e,t,n,i,a={}){if(super(),!e||!t||!n||!i)throw Error(`OIDNDenoiser requires output canvas, renderer, scene, and camera`);this.renderer=t,this.scene=n,this.camera=i,this.input=t.domElement,this.output=e,this.extractGBufferData=a.extractGBufferData||null,this.getMRTRenderTarget=a.getMRTRenderTarget||null,this.backendParamsGetter=a.backendParams||null,this.getGPUTextures=a.getGPUTextures||null,this.getExposure=a.getExposure||(()=>1),this.getToneMapping=a.getToneMapping||(()=>r.ACESFilmicToneMapping),this.getSaturation=a.getSaturation||(()=>1),this.getTransparentBackground=a.getTransparentBackground||(()=>!1),this.isGPUMode=!!this.backendParamsGetter,this.gpuDevice=null,this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputBufferSize={width:0,height:0},this._gpuInputPadBuffer=null,this._gpuInputPaddedRowBytes=0,this._alphaReadbackBuffer=null,this._alphaReadbackMapped=!1,this._cachedAlpha=null,this._cachedAlphaWidth=0,this.config={...Il.DEFAULT_OPTIONS,...a},this.enabled=this.config.enableOIDN,this.quality=this.config.oidnQuality,this.debugGbufferMaps=this.config.debugGbufferMaps,this.tileSize=this.config.tileSize,this.state={isDenoising:!1,isLoading:!1,abortController:null},this._pendingStagingBuffers=new Set,this._pendingTileBlits=[],this.currentTZAUrl=null,this.unet=null,this._pendingStart=!1,this._initialize().catch(e=>{console.error(`Failed to initialize OIDNDenoiser:`,e),this.dispatchEvent({type:`error`,error:e})})}async _initialize(){try{this._setupCanvas(),await this._setupUNetDenoiser()}catch(e){throw Error(`Initialization failed: ${e.message}`)}}_setupCanvas(){if(!this.output.getContext)throw Error(`Output must be a valid Canvas element`);this.output.willReadFrequently=!0,this.output.width=this.input.width,this.output.height=this.input.height,Object.assign(this.output.style,{position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,borderRadius:`5px`,background:`repeating-conic-gradient(#808080 0% 25%, transparent 0% 50%) 50% / 20px 20px`}),this.ctx=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0})}async _setupUNetDenoiser(){if(this.state.isLoading)return;this.state.isLoading=!0;let e=this._generateTzaUrl();if(this.currentTZAUrl===e&&this.unet){this.state.isLoading=!1;return}try{this.dispatchEvent({type:`loading`,message:`Loading UNet denoiser...`}),this.unet&&=(this.unet.dispose(),null);let t;if(this.isGPUMode&&this.backendParamsGetter){let e=this.backendParamsGetter();this.gpuDevice=e?.device??null,t=e?.device?e:void 0}this.unet=await(await Nl())(e,t,{aux:!0,hdr:!0,maxTileSize:this.tileSize}),this.currentTZAUrl=e,this.dispatchEvent({type:`loaded`}),console.log(`UNet denoiser loaded successfully:`,e)}catch(e){console.error(`Failed to load UNet denoiser:`,e),this.dispatchEvent({type:`error`,error:Error(`Denoiser loading failed: ${e.message}`)})}finally{this.state.isLoading=!1,this._pendingStart&&this.unet&&this.enabled&&(this._pendingStart=!1,this.start())}}_generateTzaUrl(){let{oidnWeightsBaseUrl:e}=na(),{QUALITY_MODELS:t}=Il;return`${e}${t[this.quality]||t.balance}.tza`}async updateConfiguration(e){Object.keys(e).some(t=>this.config[t]!==e[t])&&(Object.assign(this.config,e),this.quality=this.config.oidnQuality,this.debugGbufferMaps=this.config.debugGbufferMaps,this.tileSize=this.config.tileSize,await this._setupUNetDenoiser())}async updateQuality(e){if(!Object.prototype.hasOwnProperty.call(Il.QUALITY_MODELS,e))throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(Il.QUALITY_MODELS).join(`, `)}`);await this.updateConfiguration({oidnQuality:e})}async start(){if(!this.enabled||this.state.isDenoising)return!1;if(this.state.isLoading)return this._pendingStart=!0,!1;this.dispatchEvent({type:`start`});let e=performance.now(),t=await this.execute();if(t){this.renderer?.resetState?.(),this.input.style.opacity=`0`;let t=performance.now()-e;console.log(`Denoising completed in ${t.toFixed(1)}ms (quality: ${this.quality})`)}return t}async execute(){if(!this.enabled||!this.unet)return!1;this.state.abortController=new AbortController,this.state.isDenoising=!0,this.input.style.opacity=`0`,this.output.style.display=`block`;try{return await this._executeUNet(),!0}catch(e){return e.name===`AbortError`?console.log(`Denoising was aborted`):console.error(`Denoising error:`,e),this.input.style.opacity=`1`,!1}finally{this.state.isDenoising=!1,this.state.abortController=null,this.dispatchEvent({type:`end`})}}async _executeUNet(){return this._executeUNetGPU()}async _executeUNetGPU(){let{width:e,height:t}=this.output;if(!this.getGPUTextures)return console.warn(`OIDNDenoiser: GPU mode enabled but getGPUTextures not provided`),!1;let n=this.getGPUTextures();if(!n?.color)return console.warn(`OIDNDenoiser: GPU textures not ready yet`),!1;let r=this.gpuDevice;if(!r)return console.warn(`OIDNDenoiser: gpuDevice not available`),!1;this._ensureGPUInputBuffers(e,t);let i=r.createCommandEncoder({label:`oidn-tex-to-buf`}),a=e*16,o=this._gpuInputPaddedRowBytes,s=o>a,c=this._gpuInputPadBuffer,l=(n,r)=>{if(!s)i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:r,offset:0,bytesPerRow:a,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});else{i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:c,offset:0,bytesPerRow:o,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});for(let e=0;e<t;e++)i.copyBufferToBuffer(c,e*o,r,e*a,a)}};l(n.color,this._gpuInputBuffers.color),l(n.albedo,this._gpuInputBuffers.albedo),l(n.normal,this._gpuInputBuffers.normal),r.queue.submit([i.finish()]),this.getTransparentBackground()?await this._cacheInputAlpha(r,e,t):this._cachedAlpha=null,this.ctx.drawImage(this.input,0,0,e,t);let u={color:{data:this._gpuInputBuffers.color,width:e,height:t},albedo:{data:this._gpuInputBuffers.albedo,width:e,height:t},normal:{data:this._gpuInputBuffers.normal,width:e,height:t}};return this._executeWithAbortGPU(u)}_ensureGPUInputBuffers(e,t){let{width:n,height:r}=this._gpuInputBufferSize;if(n===e&&r===t&&this._gpuInputBuffers.color)return;this._destroyGPUInputBuffers();let i=this.gpuDevice,a=e*t*16,o=GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC;this._gpuInputBuffers.color=i.createBuffer({label:`oidn-in-color`,size:a,usage:o}),this._gpuInputBuffers.albedo=i.createBuffer({label:`oidn-in-albedo`,size:a,usage:o}),this._gpuInputBuffers.normal=i.createBuffer({label:`oidn-in-normal`,size:a,usage:o}),this._gpuInputBufferSize={width:e,height:t};let s=e*16,c=Math.ceil(s/256)*256;c===s?this._gpuInputPaddedRowBytes=s:(this._gpuInputPadBuffer=i.createBuffer({label:`oidn-in-pad`,size:c*t,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC}),this._gpuInputPaddedRowBytes=c)}_destroyGPUInputBuffers(){if(this._gpuInputBuffers.color?.destroy(),this._gpuInputBuffers.albedo?.destroy(),this._gpuInputBuffers.normal?.destroy(),this._gpuInputPadBuffer?.destroy(),this._alphaReadbackMapped&&this._alphaReadbackBuffer)try{this._alphaReadbackBuffer.unmap()}catch{}this._alphaReadbackBuffer?.destroy(),this._alphaReadbackMapped=!1,this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputPadBuffer=null,this._gpuInputPaddedRowBytes=0,this._alphaReadbackBuffer=null,this._gpuInputBufferSize={width:0,height:0}}async _cacheInputAlpha(e,t,n){let r=t*n*16;this._alphaReadbackBuffer===null&&(this._alphaReadbackBuffer=e.createBuffer({label:`oidn-alpha-readback`,size:r,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}));let i=this._alphaReadbackBuffer,a=e.createCommandEncoder();a.copyBufferToBuffer(this._gpuInputBuffers.color,0,i,0,r),e.queue.submit([a.finish()]),this._alphaReadbackMapped=!0;try{await i.mapAsync(GPUMapMode.READ)}catch{this._alphaReadbackMapped=!1;return}let o=new Float32Array(i.getMappedRange()),s=t*n,c=new Uint8Array(s);for(let e=0;e<s;e++)c[e]=Math.min(Math.max(o[e*4+3]*255,0),255)|0;i.unmap(),this._alphaReadbackMapped=!1,this._cachedAlpha=c,this._cachedAlphaWidth=t}_executeWithAbortGPU(e){return new Promise((t,n)=>{if(this.state.abortController?.signal.aborted){n(new DOMException(`Aborted`,`AbortError`));return}let i=null;this._pendingTileBlits=[];let a=()=>{i&&=(i(),null),n(new DOMException(`Aborted`,`AbortError`))};this.state.abortController.signal.addEventListener(`abort`,a,{once:!0}),i=this.unet.tileExecute({...e,done:async e=>{this.state.abortController.signal.removeEventListener(`abort`,a),i=null;try{this._pendingTileBlits.length>0?await Promise.allSettled(this._pendingTileBlits):await this._displayGPUOutput(e),t()}catch(e){n(e)}},progress:(e,t,n)=>{if(!e?.data||!n)return;let i=this.gpuDevice,a=e.width,o=e.height,s=Math.min(n.width,a-n.x),c=Math.min(n.height,o-n.y);if(s<=0||c<=0)return;let l=s*16,u=s*c*16,d=i.createBuffer({size:u,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});this._pendingStagingBuffers.add(d);let f=i.createCommandEncoder();for(let t=0;t<c;t++){let r=((n.y+t)*a+n.x)*16,i=t*l;f.copyBufferToBuffer(e.data,r,d,i,l)}i.queue.submit([f.finish()]);let p=d.mapAsync(GPUMapMode.READ).then(()=>{let e=new Float32Array(d.getMappedRange()),t=new ImageData(s,c),i=this.getExposure(),l=this.getSaturation(),u=wl.get(this.getToneMapping())||wl.get(r.ACESFilmicToneMapping),f=this._cachedAlpha,p=this._cachedAlphaWidth;for(let r=0,a=e.length;r<a;r+=4){let a=e[r]*i,o=e[r+1]*i,c=e[r+2]*i;if(l!==1&&(Fl[0]=a,Fl[1]=o,Fl[2]=c,Al(Fl,l),a=Fl[0],o=Fl[1],c=Fl[2]),u(a,o,c,1,Fl),t.data[r]=El(Fl[0])*255+.5|0,t.data[r+1]=El(Fl[1])*255+.5|0,t.data[r+2]=El(Fl[2])*255+.5|0,f){let e=(r>>2)%s,i=(r>>2)/s|0;t.data[r+3]=f[(n.y+i)*p+n.x+e]}else t.data[r+3]=255}d.unmap(),d.destroy(),this._pendingStagingBuffers.delete(d),this.ctx.putImageData(t,n.x,n.y),this.dispatchEvent({type:`tileProgress`,tile:{x:n.x,y:n.y,width:s,height:c},imageWidth:a,imageHeight:o})}).catch(()=>{d.destroy(),this._pendingStagingBuffers.delete(d)});this._pendingTileBlits.push(p)}})})}async _displayGPUOutput({data:e,width:t,height:n}){let i=this.gpuDevice;if(!i){console.error(`OIDNDenoiser: gpuDevice not available for output readback`);return}let a=t*n*4*4,o=i.createBuffer({label:`oidn-output-staging`,size:a,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});try{let s=i.createCommandEncoder({label:`oidn-readback`});s.copyBufferToBuffer(e,0,o,0,a),i.queue.submit([s.finish()]),await o.mapAsync(GPUMapMode.READ);let c=new Float32Array(o.getMappedRange()),l=new ImageData(t,n),u=this.getExposure(),d=this.getSaturation(),f=wl.get(this.getToneMapping())||wl.get(r.ACESFilmicToneMapping),p=this._cachedAlpha;for(let e=0,t=c.length;e<t;e+=4){let t=c[e]*u,n=c[e+1]*u,r=c[e+2]*u;d!==1&&(Fl[0]=t,Fl[1]=n,Fl[2]=r,Al(Fl,d),t=Fl[0],n=Fl[1],r=Fl[2]),f(t,n,r,1,Fl),l.data[e]=El(Fl[0])*255+.5|0,l.data[e+1]=El(Fl[1])*255+.5|0,l.data[e+2]=El(Fl[2])*255+.5|0,l.data[e+3]=p?p[e>>2]:255}o.unmap(),this.ctx.putImageData(l,0,0)}finally{o.destroy()}}abort(){this._pendingStart=!1,!(!this.enabled||!this.state.isDenoising)&&(this.state.abortController?.abort(),this._destroyPendingStagingBuffers(),this.input.style.opacity=`1`,this.state.isDenoising=!1,this.dispatchEvent({type:`end`}),console.log(`Denoising aborted`))}setSize(e,t){if(e<=0||t<=0)throw Error(`Invalid dimensions: ${e}x${t}`);this.output.width=e,this.output.height=t,this._setupUNetDenoiser().catch(e=>{console.error(`Failed to reinitialize denoiser after size change:`,e)})}_destroyPendingStagingBuffers(){for(let e of this._pendingStagingBuffers)e.destroy();this._pendingStagingBuffers.clear()}dispose(){this.abort(),this._destroyPendingStagingBuffers(),this.unet?.dispose(),Pl(),this._destroyGPUInputBuffers(),this.output?.parentNode&&this.output.remove(),this.unet=null,this.ctx=null,this.state.abortController=null,this.removeAllListeners?.(),console.log(`OIDNDenoiser disposed`)}},Rl=``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/AIUpscalerWorker-AXN-lKWN.js`).href:new URL(`assets/AIUpscalerWorker-AXN-lKWN.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href),zl={fast:{2:`2x-spanx2-ch48.onnx`,4:`4xNomos8k_span_otf_strong_fp32_opset17.onnx`},balanced:{2:`2xNomosUni_compact_otf_medium.onnx`,4:`RealESRGAN_x4plus.onnx`},quality:{2:`2x-realesrgan-x2plus.onnx`,4:`4xNomos2_hq_mosr_fp32.onnx`}};function Bl(){let{upscalerModelBaseUrl:e}=na(),t={};for(let n in zl){t[n]={};for(let r in zl[n])t[n][r]=e+zl[n][r]}return t}var Vl={get QUALITY_PRESETS(){return Bl()},TILE_SIZE:512,TILE_OVERLAP:16,SESSION_OPTIONS:{executionProviders:[{name:`webgpu`,preferredLayout:`NCHW`}],graphOptimizationLevel:`all`}},Hl=class extends r.EventDispatcher{constructor(e,t,n={}){if(super(),!e||!t)throw Error(`AIUpscaler requires output canvas and renderer`);this.renderer=t,this.input=t.domElement,this.output=e,this.getSourceCanvas=n.getSourceCanvas||null,this.getGPUTextures=n.getGPUTextures||null,this.getExposure=n.getExposure||(()=>1),this.getToneMapping=n.getToneMapping||(()=>r.ACESFilmicToneMapping),this.getSaturation=n.getSaturation||(()=>1),this.enabled=!1,this.hdr=!1,this.scaleFactor=n.scaleFactor||2,this.quality=n.quality||`fast`,this.tileSize=n.tileSize||Vl.TILE_SIZE,this._tileSizeOverride=!!n.tileSize,this.state={isUpscaling:!1,isLoading:!1,abortController:null},this._worker=null,this._currentModelUrl=null,this._tileId=0,this._pendingWorkerHandlers=new Set,this._upscaledAlpha=null,this._upscaledAlphaWidth=0,this._backupCanvas=null,this._baseWidth=e.width,this._baseHeight=e.height,this._hdrStagingBuffer=null,this._hdrStagingWidth=0,this._hdrStagingHeight=0}async _ensureSession(){let e=Vl.QUALITY_PRESETS[this.quality];if(!e)throw Error(`Unknown quality preset: ${this.quality}`);let t=e[this.scaleFactor];if(!t)throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);if(!(this._worker&&this._currentModelUrl===t)){this.state.isLoading=!0,this.dispatchEvent({type:`loading`,message:`Loading ${this.scaleFactor}x upscale model...`});try{if(!this._worker)try{this._worker=new Worker(Rl,{type:`module`})}catch(e){if(e.name!==`SecurityError`)throw e;this._worker=await Xe(Rl)}await new Promise((e,n)=>{let r=t=>{t.data.type===`loaded`?(this._worker.removeEventListener(`message`,r),t.data.tileSize&&!this._tileSizeOverride&&(this.tileSize=t.data.tileSize),console.log(`AI Upscaler: ${this.scaleFactor}x model loaded, backend: ${t.data.backend}, tileSize: ${this.tileSize}`),e()):t.data.type===`error`&&(this._worker.removeEventListener(`message`,r),n(Error(t.data.message)))},{ortRuntimeUrl:i,ortWasmPaths:a,cacheNamespace:o}=na();this._worker.addEventListener(`message`,r),this._worker.postMessage({type:`load`,url:t,sessionOptions:Vl.SESSION_OPTIONS,ortRuntimeUrl:i,ortWasmPaths:a,cacheNamespace:o})}),this._currentModelUrl=t,this.dispatchEvent({type:`loaded`})}catch(e){throw console.error(`AI Upscaler: Failed to load model:`,e),this.dispatchEvent({type:`error`,error:e}),e}finally{this.state.isLoading=!1}}}async start(){if(!this.enabled||this.state.isUpscaling||this.state.isLoading)return!1;this.dispatchEvent({type:`start`});let e=performance.now(),t=await this.execute();if(t){this.renderer?.resetState?.();let t=performance.now()-e;console.log(`AI Upscaler: ${this.scaleFactor}x upscale completed in ${t.toFixed(1)}ms`)}return t}async execute(){if(!this.enabled)return!1;this.state.abortController=new AbortController,this.state.isUpscaling=!0,this.input.style.opacity=`0`,this.output.style.display=`block`,this.hdr&&this.getGPUTextures?this._capturedSource=await this._captureSourceHDR():this._capturedSource=this._captureSource(),this._createBackup(this._capturedSource);let e=this._capturedSource.width*this.scaleFactor,t=this._capturedSource.height*this.scaleFactor;this.output.width=e,this.output.height=t;let n=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});n.imageSmoothingEnabled=!0,n.imageSmoothingQuality=`high`,n.drawImage(this._backupCanvas,0,0,e,t);try{return await this._ensureSession(),await this._runUpscale(),this.dispatchEvent({type:`resolution_changed`,width:this.output.width,height:this.output.height}),!0}catch(e){return e.name===`AbortError`?console.log(`AI Upscaler: Upscaling was aborted`):(console.error(`AI Upscaler: Upscaling error:`,e),this.dispatchEvent({type:`error`,error:e}),this._restoreBackup(),this.input.style.opacity=`1`,this.dispatchEvent({type:`resolution_changed`,width:this._baseWidth,height:this._baseHeight})),!1}finally{this._capturedSource=null,this._upscaledAlpha=null,this._backupCanvas=null,this.state.isUpscaling&&(this.state.isUpscaling=!1,this.state.abortController=null,this.dispatchEvent({type:`end`}))}}abort(){this.state.isUpscaling&&(this.state.abortController?.abort(),this._cleanupPendingWorkerHandlers(),this.input.style.opacity=`1`,this._restoreBackup(),this.dispatchEvent({type:`resolution_changed`,width:this._baseWidth,height:this._baseHeight}),this.state.isUpscaling=!1,this.dispatchEvent({type:`end`}),console.log(`AI Upscaler: Aborted`))}async _runUpscale(){let e=this.state.abortController.signal,t=this._capturedSource;this._capturedSource=null;let{width:n,height:i}=t,a=this.scaleFactor,o=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});this._cacheUpscaledAlpha(t,n*a,i*a),t.isHDR&&(this._hdrToneMapFn=wl.get(this.getToneMapping())||wl.get(r.ACESFilmicToneMapping),this._hdrExposure=this.getExposure(),this._hdrSaturation=this.getSaturation(),this._tmOut=new Float32Array(3));let s=Vl.TILE_OVERLAP,c=this.tileSize,l=c-s*2,u=Math.ceil(n/l),d=Math.ceil(i/l),f=u*d,p=0;for(let r=0;r<d;r++)for(let s=0;s<u;s++){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`);let u=Math.min(s*l,Math.max(0,n-c)),d=Math.min(r*l,Math.max(0,i-c)),m=Math.min(c,n-u),h=Math.min(c,i-d),g=this._extractTile(t,u,d,m,h),_=await this._inferTile(g,m,h),v=u*a,y=d*a,b=m*a,x=h*a,S=this._tensorToImageData(_,b,x,v,y);o.putImageData(S,v,y),p++,this.dispatchEvent({type:`progress`,progress:p/f,tile:{x:s,y:r,total:f,completed:p}}),this.dispatchEvent({type:`tileProgress`,tile:{x:v,y,width:b,height:x},imageWidth:n*a,imageHeight:i*a})}}_captureSource(){let e=this.getSourceCanvas?this.getSourceCanvas():null;if(e&&e!==this.output){let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);return n.drawImage(e,0,0),n.getImageData(0,0,t.width,t.height)}return this.output.getContext(`2d`,{willReadFrequently:!0}).getImageData(0,0,this.output.width,this.output.height)}async _captureSourceHDR(){let e=this.getGPUTextures();if(!e?.color)throw Error(`No GPU color texture available for HDR capture`);let t=this.renderer.backend.device,n=e.color,r=n.width,i=n.height,a=Math.ceil(r*16/256)*256,o=a*i;(this._hdrStagingWidth!==r||this._hdrStagingHeight!==i)&&(this._hdrStagingBuffer?.destroy(),this._hdrStagingBuffer=t.createBuffer({label:`aiupscaler-hdr-readback`,size:o,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this._hdrStagingWidth=r,this._hdrStagingHeight=i);let s=this._hdrStagingBuffer,c=t.createCommandEncoder();c.copyTextureToBuffer({texture:n},{buffer:s,bytesPerRow:a,rowsPerImage:i},{width:r,height:i,depthOrArrayLayers:1}),t.queue.submit([c.finish()]),await s.mapAsync(GPUMapMode.READ);let l=new Float32Array(s.getMappedRange()),u=r*4,d=a/4,f=new Float32Array(r*i*4);for(let e=0;e<i;e++){let t=e*d,n=e*u;f.set(l.subarray(t,t+u),n)}return s.unmap(),{data:f,width:r,height:i,isHDR:!0}}_extractTile(e,t,n,r,i){let{data:a,width:o}=e,s=e.isHDR,c=r*i,l=new Float32Array(3*c);for(let e=0;e<i;e++)for(let i=0;i<r;i++){let u=((n+e)*o+(t+i))*4,d=e*r+i;if(s){let e=this._hdrToneMapFn,t=this._hdrExposure,n=this._hdrSaturation,r=a[u]*t,i=a[u+1]*t,o=a[u+2]*t;n!==1&&(this._tmOut[0]=r,this._tmOut[1]=i,this._tmOut[2]=o,Al(this._tmOut,n),r=this._tmOut[0],i=this._tmOut[1],o=this._tmOut[2]),e(r,i,o,1,this._tmOut),l[d]=this._tmOut[0]**+Tl,l[c+d]=this._tmOut[1]**+Tl,l[2*c+d]=this._tmOut[2]**+Tl}else l[d]=a[u]/255,l[c+d]=a[u+1]/255,l[2*c+d]=a[u+2]/255}return l}async _inferTile(e,t,n){let r=++this._tileId;return new Promise((i,a)=>{let o=e=>{e.data.id===r&&(this._worker.removeEventListener(`message`,o),this._pendingWorkerHandlers.delete(o),e.data.type===`inferred`?i(e.data.outputData):e.data.type===`error`&&a(Error(e.data.message)))};this._pendingWorkerHandlers.add(o),this._worker.addEventListener(`message`,o),this._worker.postMessage({type:`infer`,tileData:e,width:t,height:n,id:r},[e.buffer])})}_tensorToImageData(e,t,n,r,i){let a=new ImageData(t,n),o=a.data,s=t*n,c=this._upscaledAlpha,l=this._upscaledAlphaWidth;for(let n=0;n<s;n++)if(o[n*4]=Math.min(255,Math.max(0,e[n]*255+.5))|0,o[n*4+1]=Math.min(255,Math.max(0,e[s+n]*255+.5))|0,o[n*4+2]=Math.min(255,Math.max(0,e[2*s+n]*255+.5))|0,c){let e=n/t|0,a=n%t;o[n*4+3]=c[(i+e)*l+(r+a)]}else o[n*4+3]=255;return a}_cacheUpscaledAlpha(e,t,n){let{data:r,width:i,height:a}=e,o=e.isHDR,s=o?1:255,c=!1;for(let e=3;e<r.length;e+=4)if(r[e]<s){c=!0;break}if(!c){this._upscaledAlpha=null,this._upscaledAlphaWidth=0;return}let l=document.createElement(`canvas`);l.width=i,l.height=a;let u=l.getContext(`2d`),d=u.createImageData(i,a);for(let e=0,t=i*a;e<t;e++){let t=o?Math.min(Math.max(r[e*4+3]*255,0),255)|0:r[e*4+3];d.data[e*4]=t,d.data[e*4+1]=t,d.data[e*4+2]=t,d.data[e*4+3]=255}u.putImageData(d,0,0);let f=document.createElement(`canvas`);f.width=t,f.height=n;let p=f.getContext(`2d`);p.imageSmoothingEnabled=!0,p.imageSmoothingQuality=`high`,p.drawImage(l,0,0,t,n);let m=p.getImageData(0,0,t,n).data,h=new Uint8Array(t*n);for(let e=0,r=t*n;e<r;e++)h[e]=m[e*4];this._upscaledAlpha=h,this._upscaledAlphaWidth=t}_createBackup(e){this._backupCanvas=document.createElement(`canvas`),this._backupCanvas.width=e.width,this._backupCanvas.height=e.height;let t=this._backupCanvas.getContext(`2d`);if(e.isHDR){let{data:n,width:i,height:a}=e,o=t.createImageData(i,a),s=o.data,c=wl.get(this.getToneMapping())||wl.get(r.ACESFilmicToneMapping),l=this.getExposure(),u=this.getSaturation(),d=new Float32Array(3);for(let e=0,t=i*a;e<t;e++){let t=e*4,r=n[t]*l,i=n[t+1]*l,a=n[t+2]*l;u!==1&&(d[0]=r,d[1]=i,d[2]=a,Al(d,u),r=d[0],i=d[1],a=d[2]),c(r,i,a,1,d),s[t]=d[0]**+Tl*255+.5|0,s[t+1]=d[1]**+Tl*255+.5|0,s[t+2]=d[2]**+Tl*255+.5|0,s[t+3]=255}t.putImageData(o,0,0)}else t.putImageData(e,0,0)}_restoreBackup(){this._backupCanvas&&=(this.output.width=this._backupCanvas.width,this.output.height=this._backupCanvas.height,this.output.getContext(`2d`).drawImage(this._backupCanvas,0,0),null)}toggleHDR(e){this.hdr=!!e}setQuality(e){if(!Vl.QUALITY_PRESETS[e]){console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);return}this.quality=e}setScaleFactor(e){if(e=Number(e),e!==2&&e!==4){console.warn(`AIUpscaler: Invalid scale factor ${e}, must be 2 or 4`);return}this.scaleFactor=e}setBaseSize(e,t){this._baseWidth=e,this._baseHeight=t}_cleanupPendingWorkerHandlers(){if(this._worker)for(let e of this._pendingWorkerHandlers)this._worker.removeEventListener(`message`,e);this._pendingWorkerHandlers.clear()}async dispose(){this.abort(),this._cleanupPendingWorkerHandlers(),this._worker&&=(this._worker.postMessage({type:`dispose`}),this._worker.terminate(),null),this._currentModelUrl=null,this._backupCanvas=null,this._upscaledAlpha=null,this.state.abortController=null,this._hdrStagingBuffer?.destroy(),this._hdrStagingBuffer=null,this._hdrStagingWidth=0,this._hdrStagingHeight=0,console.log(`AIUpscaler disposed`)}},Ul=class extends r.EventDispatcher{constructor({renderer:e,mainCanvas:t,scene:n,camera:r,stages:i,pipeline:a,getExposure:o,getSaturation:s,getTransparentBg:c}){super(),this.renderer=e,this.mainCanvas=t,this.denoiserCanvas=this._createDenoiserCanvas(t),this.scene=n,this.camera=r,this.pipeline=a,this._stages=i,this._getExposure=o,this._getSaturation=s,this._getTransparentBg=c,this.denoiser=null,this.upscaler=null,this._lastRenderWidth=0,this._lastRenderHeight=0,this._pendingStartUpscaler=null,this._denoiserStartHandler=null,this._denoiserEndHandler=null,this._upscalerResChangedHandler=null,this._upscalerStartHandler=null,this._upscalerProgressHandler=null,this._upscalerEndHandler=null}_createDenoiserCanvas(e){let t=e.parentNode;if(!t)return null;let n=document.createElement(`canvas`);return n.width=e.width,n.height=e.height,n.style.position=`absolute`,n.style.inset=`0`,n.style.width=`100%`,n.style.height=`100%`,t.insertBefore(n,e),n}setRenderSize(e,t){this._lastRenderWidth=e,this._lastRenderHeight=t,this.denoiser?.setSize(e,t),this.upscaler?.setBaseSize(e,t)}restoreBaseResolution(){if(!this.denoiserCanvas||!this._lastRenderWidth||!this._lastRenderHeight)return!1;let e=this.denoiserCanvas.width!==this._lastRenderWidth||this.denoiserCanvas.height!==this._lastRenderHeight;return this.denoiserCanvas.width=this._lastRenderWidth,this.denoiserCanvas.height=this._lastRenderHeight,e}setupDenoiser(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.denoiser=new Ll(this.denoiserCanvas,this.renderer,this.scene,this.camera,{...B,backendParams:()=>({device:this.renderer.backend.device,adapterInfo:null}),getGPUTextures:()=>{if(!e?.storageTextures?.readTarget)return null;let t=e.storageTextures.getReadTextures(),{backend:n}=this.renderer;return{color:n.get(t.color).texture,normal:n.get(t.normalDepth).texture,albedo:n.get(t.albedo).texture}},getExposure:()=>this._getEffectiveExposure(),getToneMapping:()=>this._getToneMapping(),getSaturation:()=>this._getSaturation(),getTransparentBackground:()=>this._getTransparentBg(),getMRTRenderTarget:()=>e?.storageTextures?.readTarget??null}),this.denoiser.enabled=B.enableOIDN,this._denoiserStartHandler=()=>this.dispatchEvent({type:F.DENOISING_START}),this._denoiserEndHandler=()=>this.dispatchEvent({type:F.DENOISING_END}),this.denoiser.addEventListener(`start`,this._denoiserStartHandler),this.denoiser.addEventListener(`end`,this._denoiserEndHandler)}setupUpscaler(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.upscaler=new Hl(this.denoiserCanvas,this.renderer,{scaleFactor:B.upscalerScale||2,quality:B.upscalerQuality||`fast`,getSourceCanvas:()=>this.denoiser?.enabled?null:this.renderer.domElement,getGPUTextures:()=>{if(!e?.storageTextures?.readTarget)return null;let t=e.storageTextures.getReadTextures();return{color:this.renderer.backend.get(t.color).texture}},getExposure:()=>this._getEffectiveExposure(),getToneMapping:()=>this._getToneMapping(),getSaturation:()=>this._getSaturation()}),this.upscaler.enabled=B.enableUpscaler||!1,this._upscalerResChangedHandler=e=>this.dispatchEvent({type:`resolution_changed`,width:e.width,height:e.height}),this._upscalerStartHandler=()=>this.dispatchEvent({type:F.UPSCALING_START}),this._upscalerProgressHandler=e=>this.dispatchEvent({type:F.UPSCALING_PROGRESS,progress:e.progress}),this._upscalerEndHandler=()=>this.dispatchEvent({type:F.UPSCALING_END}),this.upscaler.addEventListener(`resolution_changed`,this._upscalerResChangedHandler),this.upscaler.addEventListener(`start`,this._upscalerStartHandler),this.upscaler.addEventListener(`progress`,this._upscalerProgressHandler),this.upscaler.addEventListener(`end`,this._upscalerEndHandler)}setDenoiserStrategy(e,t){let n=this._stages;switch(n.asvgf&&(n.asvgf.enabled=!1),n.variance&&(n.variance.enabled=!1),n.bilateralFilter&&(n.bilateralFilter.enabled=!1),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!1),this._clearDenoiserTextures(),e){case`asvgf`:n.asvgf.enabled=!0,n.variance&&(n.variance.enabled=!0),n.bilateralFilter&&(n.bilateralFilter.enabled=!0),n.asvgf.setTemporalEnabled?.(!0),this._applyASVGFPreset(t||`medium`);break;case`edgeaware`:n.variance&&(n.variance.enabled=!0),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!0);break}this._syncGBufferStages()}setASVGFEnabled(e,t){let n=this._stages;n.asvgf&&(n.asvgf.enabled=e),n.variance&&(n.variance.enabled=e),n.bilateralFilter&&(n.bilateralFilter.enabled=e),e&&(n.asvgf?.setTemporalEnabled?.(!0),this._applyASVGFPreset(t||`medium`)),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!e),this._syncGBufferStages()}applyASVGFPreset(e){this._applyASVGFPreset(e)}setAutoExposureEnabled(e,t){let n=this._stages;n.autoExposure&&(n.autoExposure.enabled=e,!e&&this.renderer&&(this.renderer.toneMappingExposure=t))}_syncGBufferStages(){let e=this._stages,t=e.normalDepth,n=e.motionVector,r=!!e.asvgf?.enabled,i=r||!!(e.edgeFilter?.enabled||e.bilateralFilter?.enabled);t&&(i&&!t.enabled&&t.reset(),t.enabled=i),n&&(r&&!n.enabled&&(n.matricesInitialized=!1,n.isFirstFrame=!0,n.frameCount=0),n.enabled=r),e.pathTracer?.setAuxGBufferEnabled?.(i||!!this.denoiser?.enabled);for(let r of[e.asvgf,e.variance,e.bilateralFilter,e.edgeFilter,t,n])r&&!r.enabled&&r.releaseGPUMemory?.()}_cleanupCompletionListener(){this._pendingStartUpscaler&&this.denoiser&&this.denoiser.removeEventListener(`end`,this._pendingStartUpscaler),this._pendingStartUpscaler=null}onRenderComplete({isStillComplete:e,context:t}){this._cleanupCompletionListener(),(this.denoiser?.enabled||this.upscaler?.enabled)&&this.denoiserCanvas&&(this.denoiserCanvas.style.display=`block`);let n=()=>{this._pendingStartUpscaler=null,e()&&this.upscaler?.enabled&&this.upscaler.start()};this.denoiser?.enabled?(this._pendingStartUpscaler=n,this.denoiser.addEventListener(`end`,n,{once:!0}),this.denoiser.start()):(this.upscaler?.enabled&&this._stages.compositor&&t&&this._stages.compositor.render(t),n())}abort(e){this._cleanupCompletionListener(),e&&(e.style.opacity=`1`),this.upscaler&&this.upscaler.abort(),this.denoiser&&(this.denoiser.enabled&&this.denoiser.abort(),this.denoiser.output&&(this.denoiser.output.style.display=`none`))}dispose(){this._cleanupCompletionListener(),this.denoiser&&=(this._denoiserStartHandler&&this.denoiser.removeEventListener(`start`,this._denoiserStartHandler),this._denoiserEndHandler&&this.denoiser.removeEventListener(`end`,this._denoiserEndHandler),this.denoiser.dispose(),null),this.upscaler&&=(this._upscalerResChangedHandler&&this.upscaler.removeEventListener(`resolution_changed`,this._upscalerResChangedHandler),this._upscalerStartHandler&&this.upscaler.removeEventListener(`start`,this._upscalerStartHandler),this._upscalerProgressHandler&&this.upscaler.removeEventListener(`progress`,this._upscalerProgressHandler),this._upscalerEndHandler&&this.upscaler.removeEventListener(`end`,this._upscalerEndHandler),this.upscaler.dispose(),null),this._denoiserStartHandler=null,this._denoiserEndHandler=null,this._upscalerResChangedHandler=null,this._upscalerStartHandler=null,this._upscalerProgressHandler=null,this._upscalerEndHandler=null,this.denoiserCanvas?.parentNode&&(this.denoiserCanvas.parentNode.removeChild(this.denoiserCanvas),this.denoiserCanvas=null)}setOverlayManager(e){this._overlayManager=e}setResetCallback(e){this._onReset=e}setSettings(e){this._settings=e}setASVGFParams(e){this._stages.asvgf?.updateParameters(e)}toggleASVGFHeatmap(e){this._stages.asvgf?.setHeatmapEnabled?.(e)}configureASVGFForMode(e){this._stages.asvgf&&(this._stages.asvgf.enabled=e.enabled,this._stages.variance&&(this._stages.variance.enabled=e.enabled),this._stages.bilateralFilter&&(this._stages.bilateralFilter.enabled=e.enabled),e.enabled&&this._stages.asvgf.updateParameters(e),this._syncGBufferStages())}setEdgeAwareParams(e){this._stages.edgeFilter?.updateUniforms(e)}setAutoExposureParams(e){this._stages.autoExposure?.updateParameters(e)}setOIDNEnabled(e){this.denoiser&&(this.denoiser.enabled=e),this._syncGBufferStages()}setOIDNQuality(e){this.denoiser?.updateQuality(e)}setTileHelperEnabled(e){this._setTileHelper(e)}setUpscalerEnabled(e){this.upscaler&&(this.upscaler.enabled=e)}setUpscalerScaleFactor(e){this.upscaler?.setScaleFactor(e)}setUpscalerQuality(e){this.upscaler?.setQuality(e)}setAutoExposure(e){this.setAutoExposureEnabled(e,this._getExposure()),this._onReset?.()}setStrategy(e,t){this.setDenoiserStrategy(e,t),this._onReset?.()}_setTileHelper(e){let t=this._overlayManager?.getHelper(`tiles`);t&&(t.enabled=e,e||t.hide())}_getEffectiveExposure(){return this._stages.autoExposure?.enabled?this.renderer.toneMappingExposure:this._getExposure()}_getToneMapping(){return this.renderer.toneMapping}_clearDenoiserTextures(){let e=this.pipeline?.context;e&&[`asvgf:output`,`asvgf:demodulated`,`asvgf:gradient`,`variance:output`,`bilateralFiltering:output`,`edgeFiltering:output`].forEach(t=>e.removeTexture(t))}_applyASVGFPreset(e){let t=U[e];t&&(this._stages.asvgf?.updateParameters(t),this._stages.bilateralFilter?.updateParameters(t),this._stages.variance&&t.varianceBoost!==void 0&&(this._stages.variance.varianceBoost.value=t.varianceBoost))}},Wl=class{constructor(){this.layer=`hud`,this.visible=!1,this._tileBounds=null,this._imageWidth=1,this._imageHeight=1,this.enabled=!0,this._borderColor=`rgba(255, 0, 0, 0.6)`,this._borderWidthRatio=1/540,this._borderWidthMin=1.5,this._borderWidthMax=4}setActiveTile(e){this._tileBounds=e}setRenderSize(e,t){this._imageWidth=e,this._imageHeight=t}render(e,t,n){if(!this._tileBounds)return;let r=this._tileBounds,i=t/this._imageWidth,a=n/this._imageHeight,o=r.x*i,s=r.y*a,c=r.width*i,l=r.height*a,u=Math.min(this._borderWidthMax,Math.max(this._borderWidthMin,Math.min(t,n)*this._borderWidthRatio));e.strokeStyle=this._borderColor,e.lineWidth=u,e.strokeRect(o,s,c,l)}show(){this.enabled&&(this.visible=!0)}hide(){this.visible=!1,this._tileBounds=null}dispose(){this.visible=!1}},Gl=class{constructor(e,i,a){this.layer=`scene`,this.visible=!0,this._outlineNode=(0,h.outline)(i,a,{selectedObjects:[],edgeThickness:(0,n.uniform)(1),edgeGlow:(0,n.uniform)(0)}),this._displayWidth=1,this._displayHeight=1;let o=this._outlineNode.setSize.bind(this._outlineNode);this._outlineNode.setSize=()=>{o(this._displayWidth,this._displayHeight)};let s=(0,n.uniform)(3),c=(0,n.uniform)(new r.Color(16777215)),l=(0,n.uniform)(new r.Color(1640965)),{visibleEdge:u,hiddenEdge:d}=this._outlineNode,f=u.mul(c).add(d.mul(l)).mul(s);this._material=new t.MeshBasicNodeMaterial,this._material.colorNode=(0,n.vec4)(f,1),this._material.blending=r.AdditiveBlending,this._material.toneMapped=!1,this._material.depthTest=!1,this._material.depthWrite=!1,this._quad=new t.QuadMesh(this._material)}setSelectedObjects(e){this._outlineNode.selectedObjects=e}render(e){if(this._outlineNode.selectedObjects.length===0)return;let t=e.autoClear;e.autoClear=!1,e.setRenderTarget(null),this._quad.render(e),e.autoClear=t}setSize(e,t){this._displayWidth=e,this._displayHeight=t,this._outlineNode.setSize(e,t)}show(){this.visible=!0}hide(){this.visible=!1}dispose(){this.visible=!1,this._outlineNode?.dispose(),this._material?.dispose(),this._quad=null}},Kl=class{constructor(e,t){this.renderer=e,this.camera=t,this._helpers=new Map,this._hudCanvas=document.createElement(`canvas`),this._hudCanvas.style.cssText=`position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;`,this._hudCtx=this._hudCanvas.getContext(`2d`),this._helperScene=null}setHelperScene(e){this._helperScene=e}getHUDCanvas(){return this._hudCanvas}mount(e){!e||this._hudCanvas.parentElement===e||e.appendChild(this._hudCanvas)}setupDefaultHelpers({helperScene:e,meshScene:t,pipeline:n,denoisingManager:r,app:i,renderWidth:a,renderHeight:o}){this.setHelperScene(e);let s=new Wl;this.register(`tiles`,s),s.setRenderSize(a||1,o||1),i.addEventListener(`resolution_changed`,e=>{s.setRenderSize(e.width,e.height)}),n.eventBus.on(`pipeline:reset`,()=>s.hide()),this._wireDenoiserTileEvents(s,r);let c=new Gl(this.renderer,t,this.camera);this.register(`outline`,c)}_wireDenoiserTileEvents(e,t){let n=[t?.denoiser,t?.upscaler];for(let t of n)t&&(t.addEventListener(`tileProgress`,t=>{t.tile&&(e.setRenderSize(t.imageWidth,t.imageHeight),e.setActiveTile(t.tile),e.show(),this.refreshHUD())}),t.addEventListener(`end`,()=>{e.hide(),this.refreshHUD()}))}register(e,t){this._helpers.has(e)&&(console.warn(`OverlayManager: helper "${e}" already registered — replacing.`),this._helpers.get(e).dispose?.()),this._helpers.set(e,t)}unregister(e){let t=this._helpers.get(e);t&&(t.dispose?.(),this._helpers.delete(e))}show(e){this._helpers.get(e)?.show()}hide(e){this._helpers.get(e)?.hide()}toggle(e){let t=this._helpers.get(e);t&&(t.visible?t.hide():t.show())}getHelper(e){return this._helpers.get(e)??null}isVisible(e){return this._helpers.get(e)?.visible??!1}showAll(){for(let e of this._helpers.values())e.show()}hideAll(){for(let e of this._helpers.values())e.hide()}render(){this._helperScene&&this._helperScene.render(this.renderer,this.camera);for(let e of this._helpers.values())e.visible&&e.layer===`scene`&&e.render&&e.render(this.renderer,this.camera);this.refreshHUD()}setSize(e,t){for(let n of this._helpers.values())n.setSize?.(e,t)}refreshHUD(){let e=this._hudCanvas,t=this._hudCtx,n=!1;for(let e of this._helpers.values())if(e.visible&&e.layer===`hud`&&e.render){n=!0;break}if(!n){e.style.display!==`none`&&(e.style.display=`none`);return}let r=window.devicePixelRatio||1,i=e.clientWidth,a=e.clientHeight,o=Math.round(i*r),s=Math.round(a*r);(e.width!==o||e.height!==s)&&(e.width=o,e.height=s),t.clearRect(0,0,o,s),t.save(),t.scale(r,r);for(let e of this._helpers.values())e.visible&&e.layer===`hud`&&e.render&&e.render(t,i,a);t.restore(),e.style.display!==``&&(e.style.display=``)}dispose(){for(let e of this._helpers.values())e.dispose?.();this._helpers.clear(),this._hudCanvas.parentElement&&this._hudCanvas.parentElement.removeChild(this._hudCanvas)}},ql=class extends r.EventDispatcher{constructor(){super(),this.mixer=null,this.timer=new r.Timer,this.actions=[],this.isPlaying=!1,this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._tempVec=new r.Vector3,this._skinnedCache=null,this._clipsCache=null,this._savedTimeScale=1,this.onFinished=null,this.wakeCallback=null}init(e,t,n,i){if(this.dispose(),!i||i.length===0)return;this._scene=e,this._mixerRoot=t,this._meshes=n,this.mixer=new r.AnimationMixer(t);let a=i.map(e=>this.mixer.clipAction(e)),o=(e,t)=>e.name===t||e.getObjectByName(t)!==void 0;!a.some(e=>e.getClip().tracks.some(e=>{let n=e.name.split(`.`)[0];return o(t,n)}))&&t!==e&&(console.log(`[AnimationManager] Tracks did not resolve from model root, retrying with scene root`),this.mixer=new r.AnimationMixer(e),this._mixerRoot=e,a=i.map(e=>this.mixer.clipAction(e))),this.actions=a,this.mixer.addEventListener(`finished`,()=>{this.isPlaying=!1,this.timer.reset(),this.onFinished&&this.onFinished()}),this._meshTriRanges=[],this._skinnedCache=[];let s=0;for(let e of n){let t=e.geometry,n=t.attributes.position,r=t.index?t.index.array:null,i=r?r.length/3:n.count/3,a=n.count;this._meshTriRanges.push({start:s,count:i,uniqueVerts:a,indices:r}),this._skinnedCache.push(new Float32Array(a*3)),s+=i}this._posBuffer=new Float32Array(s*9);let c=n.filter(e=>e.isSkinnedMesh).length;console.debug(`[AnimationManager] Init: ${i.length} clips, ${n.length} meshes (${c} skinned), ${s} triangles`)}play(e=0){if(!(!this.mixer||this.actions.length===0)){if(this.mixer.stopAllAction(),e===-1)for(let e of this.actions)e.play();else e>=0&&e<this.actions.length&&this.actions[e].play();this.timer.reset(),this.isPlaying=!0,this.wakeCallback?.(),this.dispatchEvent({type:F.ANIMATION_STARTED})}}pause(){this.mixer&&(this.mixer.timeScale=0,this.timer.reset(),this.isPlaying=!1,this.dispatchEvent({type:F.ANIMATION_PAUSED}))}resume(){this.mixer&&(this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!0,this.wakeCallback?.(),this.dispatchEvent({type:F.ANIMATION_STARTED}))}stop(){this.mixer&&(this.mixer.stopAllAction(),this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!1,this.dispatchEvent({type:F.ANIMATION_STOPPED}))}setSpeed(e){this._savedTimeScale=e,this.mixer&&this.isPlaying&&(this.mixer.timeScale=e)}setLoop(e){let t=e?r.LoopRepeat:r.LoopOnce;for(let n of this.actions)n.setLoop(t),n.clampWhenFinished=!e}seekTo(e,t=0){if(!this.mixer||this.actions.length===0)return null;if(this.mixer.stopAllAction(),t===-1)for(let e of this.actions)e.play();else t>=0&&t<this.actions.length&&this.actions[t].play();this.mixer.setTime(e);for(let e of this.actions)e.isRunning()&&(e.paused=!0);return this._computePositions(),this._posBuffer}get currentTime(){return this.mixer?.time||0}update(){if(!this.isPlaying||!this.mixer)return null;this.timer.update();let e=this.timer.getDelta();return this.mixer.update(e),this._computePositions(),this._posBuffer}_computePositions(){let e=this._tempVec,t=this._posBuffer;this._mixerRoot.updateMatrixWorld(!0);for(let n=0;n<this._meshes.length;n++){let r=this._meshes[n],{start:i,count:a,uniqueVerts:o,indices:s}=this._meshTriRanges[n],c=this._skinnedCache[n],l=r.matrixWorld;for(let t=0;t<o;t++)r.getVertexPosition(t,e),e.applyMatrix4(l),c[t*3]=e.x,c[t*3+1]=e.y,c[t*3+2]=e.z;if(s)for(let e=0;e<a;e++){let n=e*3,r=s[n]*3,a=s[n+1]*3,o=s[n+2]*3,l=(i+e)*9;t[l]=c[r],t[l+1]=c[r+1],t[l+2]=c[r+2],t[l+3]=c[a],t[l+4]=c[a+1],t[l+5]=c[a+2],t[l+6]=c[o],t[l+7]=c[o+1],t[l+8]=c[o+2]}else for(let e=0;e<a;e++){let n=e*3*3,r=(e*3+1)*3,a=(e*3+2)*3,o=(i+e)*9;t[o]=c[n],t[o+1]=c[n+1],t[o+2]=c[n+2],t[o+3]=c[r],t[o+4]=c[r+1],t[o+5]=c[r+2],t[o+6]=c[a],t[o+7]=c[a+1],t[o+8]=c[a+2]}}}get hasAnimations(){return this.actions.length>0}get clips(){return this._clipsCache||=this.actions.map((e,t)=>{let n=e.getClip();return{index:t,name:n.name||`Clip ${t}`,duration:n.duration}}),this._clipsCache}dispose(){this.mixer&&=(this.mixer.stopAllAction(),this.mixer.uncacheRoot(this._mixerRoot),null),this.actions=[],this.isPlaying=!1,this.timer.reset(),this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._skinnedCache=null,this._clipsCache=null}},Jl=class{constructor({camera:e,canvas:t,orbitControls:n,app:i}){this._app=i,this._orbitControls=n,this._camera=e,this._controls=new g.TransformControls(e,t),this._gizmoScene=new r.Scene,this._gizmoScene.add(this._controls.getHelper()),this._attached=null,this._isDragging=!1,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._normalBuffer=null,this._skinnedCache=null,this._normalCache=null,this._tempVec=new r.Vector3,this._normalMatrix=new r.Matrix3,this._refitInFlight=!1,this._baselineComputed=!1,this._onDraggingChanged=this._onDraggingChanged.bind(this),this._onObjectChange=this._onObjectChange.bind(this),this._controls.addEventListener(`dragging-changed`,this._onDraggingChanged),this._controls.addEventListener(`objectChange`,this._onObjectChange)}setMeshData(e){this._meshes=e,this._meshTriRanges=[],this._skinnedCache=[],this._normalCache=[];let t=0;for(let n of e){let e=n.geometry,r=e.attributes.position,i=e.index?e.index.array:null,a=i?i.length/3:r.count/3,o=r.count;this._meshTriRanges.push({start:t,count:a,uniqueVerts:o,indices:i}),this._skinnedCache.push(new Float32Array(o*3)),this._normalCache.push(new Float32Array(o*3)),t+=a}this._posBuffer=new Float32Array(t*9),this._normalBuffer=new Float32Array(t*9),this._baselineComputed=!1}attach(e){this._attached!==e&&(this._controls.attach(e),this._attached=e)}detach(){this._attached&&=(this._controls.detach(),null)}setMode(e){this._controls.setMode(e),this._app?.dispatchEvent({type:F.TRANSFORM_MODE_CHANGED,mode:e})}setSpace(e){this._controls.setSpace(e)}get isDragging(){return this._isDragging}get attachedObject(){return this._attached}get controls(){return this._controls}render(e){if(!this._attached)return;let t=e.autoClear;e.autoClear=!1,e.clearDepth(),e.setRenderTarget(null),e.render(this._gizmoScene,this._camera),e.autoClear=t}_onDraggingChanged(e){this._isDragging=e.value,this._orbitControls&&(this._orbitControls.enabled=!e.value),e.value?this._app.dispatchEvent({type:F.OBJECT_TRANSFORM_START}):(this._recomputeAndRefit(),this._app.dispatchEvent({type:F.OBJECT_TRANSFORM_END}))}_onObjectChange(){this._app.needsReset=!0,this._app.wake()}_recomputeAndRefit(){if(!this._meshes||!this._posBuffer||this._refitInFlight||!this._attached)return;this._attached.updateMatrixWorld(!0);let e=this._findAffectedMeshIndices(this._attached);if(e.length!==0){if(!this._baselineComputed)this._computeAllPositions(),this._baselineComputed=!0;else for(let t of e)this._computeMeshPositions(t);this._refitInFlight=!0;try{this._app.refitBLASes(e,this._posBuffer,this._normalBuffer)}catch(e){console.error(`Transform refit error:`,e)}finally{this._refitInFlight=!1}}}_findAffectedMeshIndices(e){let t=[];for(let n=0;n<this._meshes.length;n++){let r=this._meshes[n];(r===e||this._isDescendantOf(r,e))&&t.push(n)}return t}_isDescendantOf(e,t){let n=e.parent;for(;n;){if(n===t)return!0;n=n.parent}return!1}_computeAllPositions(){for(let e=0;e<this._meshes.length;e++)this._computeMeshPositions(e)}_computeMeshPositions(e){let t=this._meshes[e],{start:n,count:r,uniqueVerts:i,indices:a}=this._meshTriRanges[e],o=this._skinnedCache[e],s=this._normalCache[e],c=this._tempVec,l=this._posBuffer,u=this._normalBuffer;t.updateMatrixWorld(!0);let d=t.matrixWorld;this._normalMatrix.getNormalMatrix(d);let f=this._normalMatrix.elements,p=t.geometry.attributes.normal;for(let e=0;e<i;e++)if(t.getVertexPosition(e,c),c.applyMatrix4(d),o[e*3]=c.x,o[e*3+1]=c.y,o[e*3+2]=c.z,p){let t=p.getX(e),n=p.getY(e),r=p.getZ(e);s[e*3]=f[0]*t+f[3]*n+f[6]*r,s[e*3+1]=f[1]*t+f[4]*n+f[7]*r,s[e*3+2]=f[2]*t+f[5]*n+f[8]*r}if(a)for(let e=0;e<r;e++){let t=e*3,r=a[t]*3,i=a[t+1]*3,c=a[t+2]*3,d=(n+e)*9;l[d]=o[r],l[d+1]=o[r+1],l[d+2]=o[r+2],l[d+3]=o[i],l[d+4]=o[i+1],l[d+5]=o[i+2],l[d+6]=o[c],l[d+7]=o[c+1],l[d+8]=o[c+2],u[d]=s[r],u[d+1]=s[r+1],u[d+2]=s[r+2],u[d+3]=s[i],u[d+4]=s[i+1],u[d+5]=s[i+2],u[d+6]=s[c],u[d+7]=s[c+1],u[d+8]=s[c+2]}else for(let e=0;e<r;e++){let t=e*3*3,r=(e*3+1)*3,i=(e*3+2)*3,a=(n+e)*9;l[a]=o[t],l[a+1]=o[t+1],l[a+2]=o[t+2],l[a+3]=o[r],l[a+4]=o[r+1],l[a+5]=o[r+2],l[a+6]=o[i],l[a+7]=o[i+1],l[a+8]=o[i+2],u[a]=s[t],u[a+1]=s[t+1],u[a+2]=s[t+2],u[a+3]=s[r],u[a+4]=s[r+1],u[a+5]=s[r+2],u[a+6]=s[i],u[a+7]=s[i+1],u[a+8]=s[i+2]}}dispose(){this._controls.removeEventListener(`dragging-changed`,this._onDraggingChanged),this._controls.removeEventListener(`objectChange`,this._onObjectChange),this.detach(),this._gizmoScene.remove(this._controls.getHelper()),this._controls.dispose(),this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._normalBuffer=null,this._skinnedCache=null,this._normalCache=null,this._baselineComputed=!1,this._app=null,this._orbitControls=null,this._camera=null,this._controls=null,this._gizmoScene=null}},Yl=new WeakMap,Xl=class extends r.EventDispatcher{constructor(e,t={}){super();try{Yl.get(e)?.dispose()}catch(e){console.warn(`PathTracerApp: prior canvas owner dispose failed`,e)}Yl.set(e,this),this.canvas=e,this._autoResize=t.autoResize!==!1,this._container=t.container||null,this.settings=new el(B),this.renderer=null,this.scene=null,this.meshScene=null,this._sceneHelpers=null,this.assetLoader=null,this._sdf=null,this._animRefitInFlight=!1,this._maxTextureSize=B.maxTextureSize,this.pipeline=null,this.stages={},this.cameraManager=null,this.lightManager=null,this.goboManager=null,this.iesManager=null,this.denoisingManager=null,this.overlayManager=null,this.interactionManager=null,this.transformManager=null,this.animationManager=new ql,this.environmentManager=null,this.isInitialized=!1,this.pauseRendering=!1,this.pathTracerEnabled=!0,this.animationManagerId=null,this.needsReset=!1,this._loadingInProgress=!1,this._needsDisplayRefresh=!1,this._paused=!1,this.completion=new hc,this._resizeDebounceTimer=null,this._trackedListeners=[],this._disposed=!1,this._deviceLost=!1}_addTrackedListener(e,t,n){e&&(e.addEventListener(t,n),this._trackedListeners.push({target:e,type:t,handler:n}))}_removeTrackedListeners(){for(let{target:e,type:t,handler:n}of this._trackedListeners)try{e.removeEventListener(t,n)}catch(e){console.warn(`PathTracerApp: failed to remove listener`,t,e)}this._trackedListeners.length=0}async init(){return await this._initRenderer(),this._initCameraManager(),this._initScenes(),this._initAssetPipeline(),this._initPipeline(),this._initManagers(),this._wireEvents(),this.stages.pathTracer.setTriangleData(new Float32Array(32),0),this.stages.pathTracer.setBVHData(new Float32Array(16)),this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)),this.stages.pathTracer.setupMaterial(),this.isInitialized=!0,console.log(`WebGPU Path Tracer App initialized`),this}animate(){if(!this._deviceLost){if(this.animationManagerId=requestAnimationFrame(()=>this.animate()),this._loadingInProgress||this._sdf?.isProcessing){this.dispatchEvent({type:F.FRAME});return}if(this.cameraManager.controls&&this.cameraManager.controls.update(),this.animationManager?.isPlaying&&!this._animRefitInFlight){let e=this.animationManager.update();e&&(this._animRefitInFlight=!0,this.refitBVH(e).catch(e=>console.error(`Animation refit error:`,e)).finally(()=>{this._animRefitInFlight=!1}))}if(this.needsReset&&=(this.reset(!0),!1),this.cameraManager.camera.updateMatrixWorld(),!this.pathTracerEnabled){this.renderer.render(this.meshScene,this.cameraManager.camera),this._renderHelperOverlay();return}if(!this.pauseRendering){if(this.cameraManager.updateAutoFocus(),this.stages.pathTracer?.isReady){if(this.stages.pathTracer.isComplete&&this.completion.renderCompleteDispatched){this._needsDisplayRefresh&&(this._needsDisplayRefresh=!1,this.stages.compositor.render(this.pipeline.context),this._renderHelperOverlay()),this.stopAnimation();return}this.pipeline.render(),this.stages.pathTracer.isComplete||this.completion.updateTime(),this._ensureVRAMWiring();let e=this.stages.pathTracer?.vramTracker,t=this.stages.pathTracer?.frameCount??0;e&&(t<=1||t%30==0)&&e.measure(),Ce({timeElapsed:this.completion.timeElapsed,samples:L(this.stages.pathTracer),memoryUsed:e?.current??0,memoryPeak:e?.peak??0}),this.completion.isTimeLimitReached(this.settings.get(`renderLimitMode`),this.settings.get(`renderTimeLimit`))&&(this.stages.pathTracer.isComplete=!0),this.stages.pathTracer.isComplete&&this.completion.markComplete()&&(this.denoisingManager.onRenderComplete({isStillComplete:()=>this.completion.renderCompleteDispatched,context:this.pipeline?.context}),this.dispatchEvent({type:`RenderComplete`}),this.dispatchEvent({type:F.RENDER_COMPLETE}))}this._renderHelperOverlay(),this.dispatchEvent({type:F.FRAME})}}}stopAnimation(){this.animationManagerId&&=(cancelAnimationFrame(this.animationManagerId),null)}_handleDeviceLost(e){this._deviceLost||(this._deviceLost=!0,console.error(`WebGPU device lost (${e?.reason||`unknown`}): ${e?.message||``}`),this.stopAnimation(),this.dispatchEvent({type:F.DEVICE_LOST,reason:e?.reason,message:e?.message}))}wake(){this._deviceLost||!this.animationManagerId&&this.isInitialized&&!this._paused&&this.animate()}pause(){this._paused=!0,this.stopAnimation()}resume(){this._paused=!1,this.animationManagerId||this.animate()}reset(e=!1){if(this.pipeline&&(this.pipeline.reset(),e||this.pipeline.eventBus.emit(`asvgf:reset`)),this.denoisingManager?.abort(this.canvas),this.denoisingManager?.restoreBaseResolution()){let e=this.denoisingManager._lastRenderWidth,t=this.denoisingManager._lastRenderHeight;this.dispatchEvent({type:`resolution_changed`,width:e,height:t})}this.completion.reset(),this.wake(),this.dispatchEvent({type:`RenderReset`}),this.dispatchEvent({type:F.RENDER_RESET})}dispose(){if(!this._disposed){if(this._disposed=!0,this.dispatchEvent({type:F.DISPOSE}),this.stopAnimation(),clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=null,this._removeTrackedListeners(),xe(null),this.interactionManager?.deselect?.(),this.transformManager?.detach?.(),this.animationManager?.dispose(),this.transformManager?.dispose(),this.overlayManager?.dispose(),this.lightManager?.dispose(),this.goboManager?.dispose(),this.iesManager?.dispose(),this.denoisingManager?.dispose(),this.interactionManager?.dispose(),this.cameraManager?.dispose(),this.pipeline?.dispose(),this._sdf?.dispose(),this._sdf=null,this.assetLoader?.dispose(),this.assetLoader=null,this.meshScene){this.meshScene.environment?.dispose(),this.meshScene.environment=null;for(let e of[...this.meshScene.children])R(e);this.meshScene.clear(),this.meshScene=null}this._sceneHelpers?.clear(),this._sceneHelpers=null,this.scene?.clear(),this.scene=null,this.renderer?._canvasTarget&&this.renderer._onCanvasTargetResize&&this.renderer._canvasTarget.removeEventListener(`resize`,this.renderer._onCanvasTargetResize);try{let e=(0,n.texture)().value,t=(0,n.cubeTexture)().value;e?._listeners?.dispose&&(e._listeners.dispose.length=0),t?._listeners?.dispose&&(t._listeners.dispose.length=0)}catch(e){console.warn(`PathTracerApp: failed to clear TSL texture singleton listeners`,e)}this.renderer?.dispose(),this.renderer&&(this.renderer._canvasTarget=null),this.renderer=null,this.stages={},this.isInitialized=!1}}unloadScene(){if(this.isInitialized){if(this._loadingInProgress)throw Error(`PathTracerApp.unloadScene: cannot unload while a load is in progress`);this._disposed||(this.animationManager?.dispose(),this._animRefitInFlight=!1,this.interactionManager?.deselect(),this.transformManager?.detach?.(),this.assetLoader?.releaseTargetModel(),this.lightManager?.clearLights?.(),this.stages.pathTracer&&(this.stages.pathTracer.setTriangleData(new Float32Array(32),0),this.stages.pathTracer.setBVHData(new Float32Array(16)),this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)),this.stages.pathTracer.setEmissiveTriangleData?.(new Float32Array,0,0),this.stages.pathTracer.setupMaterial()),this.reset(),this.dispatchEvent({type:`SceneUnloaded`}))}}async loadModel(e){await this._loadWithSceneRebuild(()=>this.assetLoader.loadModel(e),{type:`ModelLoaded`,url:e})}async loadObject3D(e,t=`object3d`){await this._loadWithSceneRebuild(()=>this.assetLoader.loadObject3D(e,t),{type:`Object3DLoaded`,name:t})}async loadEnvironment(e){if(this._loadingInProgress)throw Error(`PathTracerApp.loadEnvironment: another load is already in progress`);this._loadingInProgress=!0;try{await this.assetLoader.loadEnvironment(e);let t=this.meshScene.environment;t&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(t),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),this.dispatchEvent({type:`EnvironmentLoaded`,url:e})}finally{this._loadingInProgress=!1}}async loadExampleModels(e,t){await this._loadWithSceneRebuild(()=>this.assetLoader.loadExampleModels(e,t),{type:`ModelLoaded`,index:e})}cancelLoad(){this._loadingInProgress&&this.assetLoader?.cancelActiveLoad()}async setMaxTextureSize(e,{reprocess:t=!0}={}){let n=this._maxTextureSize;if(this._maxTextureSize=this._sdf?.setMaxTextureSize(e)??e,typeof this.stages?.pathTracer?.sdfs?.setMaxTextureSize==`function`&&this.stages.pathTracer.sdfs.setMaxTextureSize(this._maxTextureSize),t&&this._maxTextureSize!==n&&this._sdf?.triangleData&&!this._loadingInProgress){this._loadingInProgress=!0;try{await this.loadSceneData(),this.reset(),this.dispatchEvent({type:`TexturesReprocessed`,maxTextureSize:this._maxTextureSize})}finally{this._loadingInProgress=!1}}}async _loadWithSceneRebuild(e,t){if(this._loadingInProgress)throw Error(`PathTracerApp: another load is already in progress`);this._loadingInProgress=!0;try{await e(),this._clearAppendedModels(),this._syncControlsAfterLoad(),await this.loadSceneData(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),this.cameraManager.currentCameraIndex=0,this.dispatchEvent(t),this.dispatchEvent({type:`CamerasUpdated`,cameras:this.cameraManager.cameras,cameraNames:this.cameraManager.getCameraNames()})}finally{this._loadingInProgress=!1}}async loadSceneData(){this._preserveSelectionOnRebuild||this.interactionManager?.deselect(),this.animationManager.dispose(),this._animRefitInFlight=!1,this._tagPrimarySceneObject();let e=new Wi(`loadSceneData`),t=this.meshScene.environment,n=null;if(t?.image?.data&&(e.start(`Environment CDF build (worker)`),this.stages.pathTracer.scene.environment=t,n=this.stages.pathTracer.environment.buildEnvironmentCDF().then(()=>e.end(`Environment CDF build (worker)`))),e.start(`BVH build (SceneProcessor)`),this._sdf.setMaxTextureSize(this._maxTextureSize),await this._sdf.buildBVH(this.meshScene),e.end(`BVH build (SceneProcessor)`),I({status:`Transferring data to GPU...`,progress:86}),await new Promise(e=>setTimeout(e,0)),e.start(`GPU data transfer`),!this._sdf.uploadToPathTracer(this.stages.pathTracer,this.lightManager,this.meshScene,t))return!1;this.stages.pathTracer._meshRefs=this.stages.pathTracer._collectMeshRefs(this.meshScene),this.stages.pathTracer.setMeshVisibilityData(this.stages.pathTracer._meshRefs),e.end(`GPU data transfer`),I({status:`Compiling shaders...`,progress:90}),await new Promise(e=>setTimeout(e,0)),e.start(`Material setup (TSL compile)`),this.stages.pathTracer.setupMaterial(),e.end(`Material setup (TSL compile)`),e.start(`Pipeline precompile`);try{await this.renderer.compileAsync(this.meshScene,this.cameraManager.camera)}catch(e){console.warn(`PathTracerApp: raster fallback precompile failed`,e)}e.end(`Pipeline precompile`),n&&(I({status:`Finalizing environment map...`,progress:95}),await n,this.stages.pathTracer.environment.applyCDFResults());let r=this.getSceneMinY();return this.settings.set(`groundProjectionLevel`,r,{reset:!1}),this.settings.set(`groundCatcherHeight`,r,{reset:!1}),e.start(`Apply settings`),this.settings.applyAll(),this.stages.compositor.setTransparentBackground(this.settings.get(`transparentBackground`)),e.end(`Apply settings`),e.print(),Se(),this._initAnimationAndTransforms(),this.dispatchEvent({type:`SceneRebuild`}),!0}_tagPrimarySceneObject(){let e=this.assetLoader?.targetModel;e&&(e.userData.__rayzeeSceneObject=!0,e.userData.__rayzeeExternal=e===this.assetLoader._externalModel)}_clearAppendedModels(){let e=this.meshScene;if(!e)return;let t=this.assetLoader?.floorPlane,n=this.assetLoader?.targetModel;for(let r of[...e.children])r===t||r===n||r.userData?.__rayzeeSceneObject&&this.assetLoader.removeModelRoot(r,{external:!!r.userData.__rayzeeExternal})}async _finishRebuildNoReframe(e){await this.loadSceneData(),this._recalibrateControlLimits(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset(),e&&this.dispatchEvent(e)}async addModel(e,{name:t}={}){if(this._loadingInProgress)throw Error(`PathTracerApp.addModel: another load is already in progress`);this._loadingInProgress=!0,this._preserveSelectionOnRebuild=!0;try{let{root:n}=await this.assetLoader.appendModel(e);return n.userData.__rayzeeSceneObject=!0,n.userData.__rayzeeExternal=!1,t&&(n.userData.__rayzeeName=t),await this._finishRebuildNoReframe({type:`ModelAdded`,url:e,id:n.uuid}),n.uuid}finally{this._preserveSelectionOnRebuild=!1,this._loadingInProgress=!1}}async addModelFromObject3D(e,{name:t}={}){if(this._loadingInProgress)throw Error(`PathTracerApp.addModelFromObject3D: another load is already in progress`);this._loadingInProgress=!0,this._preserveSelectionOnRebuild=!0;try{let{root:n}=this.assetLoader.appendObject3D(e,t||`object3d`);return n.userData.__rayzeeSceneObject=!0,n.userData.__rayzeeExternal=!0,t&&(n.userData.__rayzeeName=t),await this._finishRebuildNoReframe({type:`ModelAdded`,id:n.uuid}),n.uuid}finally{this._preserveSelectionOnRebuild=!1,this._loadingInProgress=!1}}async removeSceneObject(e){let t=this.meshScene;if(!t)return!1;let n=this.assetLoader?.floorPlane;if(n&&n.uuid===e)return!1;let r=t.children.find(t=>t.uuid===e&&t.userData?.__rayzeeSceneObject);if(!r)return!1;if(this._loadingInProgress)throw Error(`PathTracerApp.removeSceneObject: another load is already in progress`);this._loadingInProgress=!0;try{return this.interactionManager?.deselect(),this.transformManager?.detach?.(),r===this.assetLoader.targetModel?this.assetLoader.releaseTargetModel():this.assetLoader.removeModelRoot(r,{external:!!r.userData.__rayzeeExternal}),await this._finishRebuildNoReframe({type:`SceneObjectRemoved`,id:e}),!0}finally{this._loadingInProgress=!1}}setSceneObjectVisibility(e,t){return this.setMeshVisibilityByUuid(e,t)}async refitBVH(e,t){let n=await this._sdf.refitBVH(e,t);return this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset(),n}refitBLASes(e,t,n){let r=this._sdf.refitBLASes(e,t,n),{triRanges:i,bvhRanges:a}=this._sdf.computeBLASDirtyRanges(e);return this.stages.pathTracer.updateBufferRanges(i,a),this.reset(),this._sdf.scheduleBackgroundRebuild(e,()=>{this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset()}),r}_isRenderSizeSupported(e,t){return e>2048||t>2048?(console.warn(`[Rayzee] Render resolution ${e}×${t} exceeds the ${H}px limit (compute storage textures are pre-allocated at ${H}px). Ignoring resize — use a resolution ≤ ${H}.`),!1):!0}onResize(){let e=this.canvas.clientWidth,t=this.canvas.clientHeight;if(e===0||t===0||!this._isRenderSizeSupported(e,t))return;this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this.cameraManager.camera.aspect=e/t,this.cameraManager.camera.updateProjectionMatrix();let n=window.devicePixelRatio||1;this.overlayManager?.setSize(Math.round(e*n),Math.round(t*n));let r=this.denoisingManager?._lastRenderWidth??0,i=this.denoisingManager?._lastRenderHeight??0;e===r&&t===i||(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{this._applyRenderResize(e,t)},300))}_applyRenderResize(e,t){this._isRenderSizeSupported(e,t)&&(this.pipeline?.setSize(e,t),this.denoisingManager?.setRenderSize(e,t),this.needsReset=!0,this.dispatchEvent({type:`resolution_changed`,width:e,height:t}))}setCanvasSize(e,t){e===0||t===0||this._isRenderSizeSupported(e,t)&&(this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this.cameraManager.camera.aspect=e/t,this.cameraManager.camera.updateProjectionMatrix(),clearTimeout(this._resizeDebounceTimer),this._applyRenderResize(e,t))}configureForMode(e,t={}){let n=e===`production`,r=n?Re:ze;this.cameraManager.controls.enabled=!n,this.settings.setMany({maxSamples:r.maxSamples,maxBounces:r.bounces,transmissiveBounces:r.transmissiveBounces,maxSubsurfaceSteps:r.maxSubsurfaceSteps},{silent:!0}),this.stages.pathTracer?.setUniform(`renderMode`,parseInt(r.renderMode)),this.stages.pathTracer?.setUniform(`enableAlphaShadows`,r.enableAlphaShadows??!1),this.stages.pathTracer?.updateCompletionThreshold?.();let i=this.denoisingManager?.denoiser;if(i&&(i.abort(),i.enabled=r.enableOIDN,i.updateQuality(r.oidnQuality)),this.denoisingManager?._syncGBufferStages?.(),this.denoisingManager?.upscaler?.abort(),t.canvasWidth&&t.canvasHeight&&this.setCanvasSize(t.canvasWidth,t.canvasHeight),this.needsReset=!1,this.pauseRendering=!1,n){let e=this.stages.pathTracer?.vramTracker;e&&(e.measure(),e.resetPeak())}this.reset()}refreshFrame(){this._needsDisplayRefresh=!0,this.wake()}getCanvas(){if(!this.renderer?.domElement)return null;let e=this.denoisingManager;return(e?.denoiser?.enabled||e?.upscaler?.enabled)&&e?.denoiserCanvas&&this.stages.pathTracer?.isComplete?e.denoiserCanvas:(this.stages.compositor&&this.pipeline?.context&&this.stages.compositor.render(this.pipeline.context),this.renderer.domElement)}screenshot({type:e=`image/png`,quality:t}={}){let n=this.getCanvas();return n?new Promise(r=>n.toBlob(r,e,t)):Promise.resolve(null)}getStatistics(){try{return this._sdf?.getStatistics?.()??null}catch{return null}}get isLoading(){return this._loadingInProgress}isComplete(){return this.stages.pathTracer?.isComplete??!1}getFrameCount(){return this.stages.pathTracer?.frameCount||0}get vram(){return this.stages.pathTracer?.vramTracker??null}getMemoryInfo(){return this.stages.pathTracer?.vramTracker?.measure()??{current:0,peak:0,byCategory:{}}}_ensureVRAMWiring(){if(this._vramWired)return;let e=this.stages.pathTracer?.vramTracker;if(!e)return;e.register(`stages`,()=>this._collectStageTextures());let t=()=>e.measure();this._addTrackedListener(this,`SceneRebuild`,t),this._addTrackedListener(this,`EnvironmentLoaded`,t),this._addTrackedListener(this,`resolution_changed`,t),this._vramWired=!0}_collectStageTextures(){let e=[],t=this.stages||{},n=t.pathTracer;for(let r in t){let i=t[r];if(!(!i||i===n||typeof i!=`object`))for(let t in i){let n=i[t];n&&(n.isTexture||n.isRenderTarget)&&e.push(n)}}return e}getSceneMinY(){if(!this.meshScene)return 0;let e=new r.Box3().setFromObject(this.meshScene);return Number.isFinite(e.min.y)?e.min.y:0}setMaterialProperty(e,t,n){if(this.stages.pathTracer?.materialData.updateMaterialProperty(e,t,n),[`emissive`,`emissiveIntensity`].includes(t)&&this.stages.pathTracer?.enableEmissiveTriangleSampling?.value){let r=this._sdf.updateMaterialEmissive(e,t,n);r&&(this.stages.pathTracer.setEmissiveTriangleData(r.rawData,r.emissiveCount,r.totalPower,r.bitTrailMap),r.lightBVHNodeData&&this.stages.pathTracer.setLightBVHData(r.lightBVHNodeData,r.lightBVHNodeCount))}this.reset()}setMeshVisibility(e,t){this.stages.pathTracer?.updateMeshVisibility(e,t),this.reset()}updateAllMeshVisibility(){this.stages.pathTracer?.updateAllMeshVisibility(),this.reset()}getScene(){return this.meshScene||this.scene}setMeshVisibilityByUuid(e,t){let n=this.getScene()?.getObjectByProperty(`uuid`,e);if(!n)return null;let r=typeof t==`function`?!!t(n.visible):!!t;return n.visible=r,this.updateAllMeshVisibility(),r}setTextureTransform(e,t,n){this.stages.pathTracer?.materialData.updateTextureTransform(e,t,n),this.reset()}async rebuildMaterials(e){await this.stages.pathTracer?.rebuildMaterials(e||this.meshScene),this.reset()}async _initRenderer(){if(xe(e=>this.dispatchEvent(e)),!navigator.gpu)throw Error(`WebGPU is not supported in this browser`);let e=await navigator.gpu.requestAdapter({powerPreference:`high-performance`});if(!e)throw Error(`Failed to get WebGPU adapter`);let n=e.limits;this.renderer=new t.WebGPURenderer({canvas:this.canvas,alpha:!0,powerPreference:`high-performance`,requiredLimits:{maxBufferSize:n.maxBufferSize,maxStorageBufferBindingSize:n.maxStorageBufferBindingSize,maxColorAttachmentBytesPerSample:128,maxStorageBuffersPerShaderStage:Math.min(n.maxStorageBuffersPerShaderStage,10)}}),await this.renderer.init();let a=this.renderer.backend?.device;a?.lost&&(a.lost.then(e=>{this._disposed||this._handleDeviceLost(e)}),a.onuncapturederror=e=>console.error(`WebGPU uncaptured error:`,e.error)),t.RectAreaLightNode.setLTC(i.RectAreaLightTexturesLib.init()),this.renderer.outputColorSpace=t.SRGBColorSpace,this.renderer.toneMapping=r.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1,this.renderer.setPixelRatio(1)}_initCameraManager(){this.cameraManager=new tl(this.canvas)}_initScenes(){this.scene=new r.Scene,this.meshScene=new r.Scene,this._sceneHelpers=new O}_initAssetPipeline(){this._sdf=new Ki,this.assetLoader=new Zc(this.meshScene,this.cameraManager.camera,this.cameraManager.controls),this.assetLoader.setRenderer(this.renderer),this.assetLoader.createFloorPlane(),this._addTrackedListener(this.cameraManager.controls,`change`,()=>{this.needsReset=!0,this.wake()})}_initPipeline(){this._createStages();let{clientWidth:e,clientHeight:t}=this.canvas;this.pipeline=new mc(this.renderer,e||1,t||1),this.pipeline.addStage(this.stages.pathTracer),this.pipeline.addStage(this.stages.normalDepth),this.pipeline.addStage(this.stages.motionVector),this.pipeline.addStage(this.stages.asvgf),this.pipeline.addStage(this.stages.variance),this.pipeline.addStage(this.stages.bilateralFilter),this.pipeline.addStage(this.stages.edgeFilter),this.pipeline.addStage(this.stages.autoExposure),this.pipeline.addStage(this.stages.compositor);let n=this.canvas.clientWidth||1,r=this.canvas.clientHeight||1;this.pipeline.setSize(n,r)}_initManagers(){this.interactionManager=new gc({scene:this.meshScene,camera:this.cameraManager.camera,canvas:this.canvas,assetLoader:this.assetLoader,pathTracer:null,floorPlane:this.assetLoader.floorPlane}),this.interactionManager.wireAppEvents(this),this.cameraManager.setInteractionManager(this.interactionManager),this.lightManager=new nl(this.scene,this._sceneHelpers,this.stages.pathTracer,{onReset:()=>this.reset()}),this.goboManager=new rl(this.stages.pathTracer,{onReset:()=>this.reset()}),this.iesManager=new ml(this.stages.pathTracer,{onReset:()=>this.reset()}),this._setupDenoisingManager(),this._setupOverlayManager(),this.transformManager=new Jl({camera:this.cameraManager.camera,canvas:this.canvas,orbitControls:this.cameraManager.controls,app:this}),this.interactionManager.setDependencies({overlayManager:this.overlayManager,transformManager:this.transformManager,appDispatch:e=>this.dispatchEvent(e),orbitControls:this.cameraManager.controls}),this.denoisingManager.setOverlayManager(this.overlayManager),this.denoisingManager.setResetCallback(()=>this.reset()),this.denoisingManager.setSettings(this.settings),this.environmentManager=this.stages.pathTracer.environment,this.environmentManager.callbacks.onAutoExposureReset=()=>this.pipeline.eventBus.emit(`autoexposure:resetHistory`)}_wireEvents(){this._addTrackedListener(this.cameraManager,`CameraSwitched`,e=>this.dispatchEvent(e)),this._addTrackedListener(this.cameraManager,F.AUTO_FOCUS_UPDATED,e=>this.dispatchEvent(e)),this._forwardEvents(this.denoisingManager,[F.DENOISING_START,F.DENOISING_END,F.UPSCALING_START,F.UPSCALING_PROGRESS,F.UPSCALING_END,`resolution_changed`]),this._setupAutoExposureListener(),this.animationManager.wakeCallback=()=>this.wake(),this._forwardEvents(this.animationManager,[F.ANIMATION_STARTED,F.ANIMATION_PAUSED,F.ANIMATION_STOPPED]),this._addTrackedListener(this.animationManager,F.ANIMATION_PAUSED,()=>{this._animRefitInFlight=!1}),this._addTrackedListener(this.animationManager,F.ANIMATION_STOPPED,()=>{this._animRefitInFlight=!1}),this.cameraManager.initCallbacks({onResize:()=>this.onResize(),onReset:()=>this.reset(),getSettings:e=>this.settings.get(e)}),this.cameraManager.initAutoFocus({meshScene:this.meshScene,assetLoader:this.assetLoader,floorPlane:this.assetLoader.floorPlane,pathTracer:this.stages.pathTracer,settings:this.settings,softReset:()=>this.reset(!0),hardReset:()=>this.reset()}),this.settings.bind({stages:this.stages,renderer:this.renderer,resetCallback:()=>this.reset(),reconcileCompletion:()=>this._reconcileCompletion()}),this.renderer.toneMappingExposure=this.settings.get(`exposure`)??1,this.onResize(),this.resizeHandler=()=>this.onResize(),this._autoResize&&this._addTrackedListener(window,`resize`,this.resizeHandler),this._onAssetLoaded=async e=>{if(!this._loadingInProgress){if(e.model)this._clearAppendedModels(),await this.loadSceneData();else if(e.texture){let e=this.meshScene.environment;e&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(e),Se()}this.pauseRendering=!1,this.reset()}},this._addTrackedListener(this.assetLoader,`load`,this._onAssetLoaded),this._addTrackedListener(this.assetLoader,`modelProcessed`,e=>{let t=[this.cameraManager.camera,...e.cameras||[]];this.cameraManager.setCameras(t),this.interactionManager&&(this.interactionManager.floorPlane=this.assetLoader.floorPlane)})}_initAnimationAndTransforms(){let e=this.assetLoader?.animations||[];if(e.length>0){let t=this.assetLoader?.targetModel||this.meshScene;this.animationManager.init(this.meshScene,t,this._sdf.meshes,e),this.animationManager.onFinished=()=>{this._animRefitInFlight=!1,this.dispatchEvent({type:F.ANIMATION_FINISHED})}}this.transformManager?.setMeshData(this._sdf.meshes)}_createStages(){this.stages.pathTracer=new Hs(this.renderer,this.scene,this.cameraManager.camera),this.stages.normalDepth=new Us(this.renderer,{pathTracer:this.stages.pathTracer}),this.stages.motionVector=new Ws(this.renderer,this.cameraManager.camera,{pathTracer:this.stages.pathTracer}),this.stages.asvgf=new qs(this.renderer,{enabled:!1}),this.stages.variance=new Xs(this.renderer,{enabled:!1}),this.stages.bilateralFilter=new Qs(this.renderer,{enabled:!1}),this.stages.edgeFilter=new rc(this.renderer,{enabled:!1}),this.stages.autoExposure=new uc(this.renderer,{enabled:B.autoExposure??!1}),this.stages.compositor=new dc(this.renderer,{saturation:this.settings.get(`saturation`)??B.saturation})}_setupDenoisingManager(){this.denoisingManager=new Ul({renderer:this.renderer,mainCanvas:this.canvas,scene:this.scene,camera:this.cameraManager.camera,stages:{pathTracer:this.stages.pathTracer,normalDepth:this.stages.normalDepth,motionVector:this.stages.motionVector,asvgf:this.stages.asvgf,variance:this.stages.variance,bilateralFilter:this.stages.bilateralFilter,edgeFilter:this.stages.edgeFilter,autoExposure:this.stages.autoExposure,compositor:this.stages.compositor},pipeline:this.pipeline,getExposure:()=>this.settings.get(`exposure`)??1,getSaturation:()=>this.settings.get(`saturation`)??1,getTransparentBg:()=>this.settings.get(`transparentBackground`)??!1}),this.denoisingManager.setupDenoiser(),this.denoisingManager.setupUpscaler(),this.denoisingManager._syncGBufferStages();let e=this.canvas.clientWidth||1,t=this.canvas.clientHeight||1;this.denoisingManager.setRenderSize(e,t)}_reconcileCompletion(){let e=this.stages.pathTracer;if(!e)return;let t=this.completion.isLimitReached(e,this.settings.get(`renderLimitMode`),this.settings.get(`renderTimeLimit`));t&&!e.isComplete?e.isComplete=!0:!t&&e.isComplete&&(e.isComplete=!1,this.completion.resumeFromPause(),this.denoisingManager?.abort(this.canvas),this.dispatchEvent({type:F.RENDER_RESET}),this.wake())}_setupAutoExposureListener(){this.stages.autoExposure&&this.stages.autoExposure.on(`autoexposure:updated`,e=>{this.dispatchEvent({type:F.AUTO_EXPOSURE_UPDATED,exposure:e.exposure,luminance:e.luminance})})}_renderHelperOverlay(){this.scene.updateMatrixWorld(),this.overlayManager?.render(),this.transformManager?.render(this.renderer)}_setupOverlayManager(){this.overlayManager=new Kl(this.renderer,this.cameraManager.camera),this.overlayManager.setupDefaultHelpers({helperScene:this._sceneHelpers,meshScene:this.meshScene,pipeline:this.pipeline,denoisingManager:this.denoisingManager,app:this,renderWidth:this.denoisingManager?._lastRenderWidth||this.canvas.clientWidth||1,renderHeight:this.denoisingManager?._lastRenderHeight||this.canvas.clientHeight||1}),this._container=this._container||this.canvas.parentNode||null,this.overlayManager.mount(this._container)}_syncControlsAfterLoad(){this.cameraManager.controls.saveState(),this.cameraManager.controls.update()}_recalibrateControlLimits(){if(!this.meshScene||!this.cameraManager)return;let e=new r.Box3,t=new r.Box3;for(let n of this.meshScene.children)n.userData?.__rayzeeSceneObject&&(t.setFromObject(n),t.isEmpty()||e.union(t));if(e.isEmpty())return;let n=Math.max(e.max.x-e.min.x,e.max.y-e.min.y,e.max.z-e.min.z);if(!Number.isFinite(n)||n<=0)return;let{camera:i,controls:a}=this.cameraManager,o=i.fov*(Math.PI/180),s=Math.abs(n/Math.sin(o/2)/2);this.cameraManager.currentCameraIndex===0&&(i.near=n/100,i.far=n*100,i.updateProjectionMatrix());let c=i.position.distanceTo(a.target);a.minDistance=Math.min(n/1e3,c),a.maxDistance=Math.max(s*10,c*1.1),a.update()}_forwardEvents(e,t){if(e)for(let n of t)this._addTrackedListener(e,n,e=>this.dispatchEvent(e))}},Zl=class{constructor(e){this._app=e,this._cancelled=!1,this._rendering=!1}async renderAnimation(e={}){let{clipIndex:t=0,fps:n=30,speed:r=1,samplesPerFrame:i=Re.maxSamples,enableOIDN:a=!0,onFrame:o,onProgress:s,onComplete:c}=e,l=this._app;if(!l.animationManager?.hasAnimations){console.warn(`VideoRenderManager: No animation clips available`),c?.(!1);return}let u=l.animationManager.clips[t];if(!u){console.warn(`VideoRenderManager: Invalid clip index ${t}`),c?.(!1);return}let d=u.duration/(r||1),f=e.totalFrames||Math.ceil(d*n),p=1/n;this._cancelled=!1,this._rendering=!0;let m=this._saveState();l.stopAnimation(),l.configureForMode(`production`),l.settings.setMany({maxSamples:i},{silent:!0}),l.stages.pathTracer?.updateCompletionThreshold?.(),l.cameraManager.controls&&(l.cameraManager.controls.enabled=!1);try{for(let e=0;e<f&&!this._cancelled;e++){let n=e*p*r,i=l.animationManager.seekTo(n,t);if(i?await l.refitBVH(i):l.reset(),l.stopAnimation(),await this._accumulateFrame(l),this._cancelled||(a&&l.denoisingManager?.denoiser?.enabled&&await this._waitForDenoise(l),this._cancelled))break;let c=l.getCanvas();if(c&&o){let t=await createImageBitmap(c);await o(t,e,f),t.close()}let u={frame:e+1,totalFrames:f,percent:(e+1)/f*100};s?.(u),l.dispatchEvent({type:F.VIDEO_RENDER_PROGRESS,...u})}}catch(e){console.error(`VideoRenderManager: Render error:`,e),this._cancelled=!0}finally{this._restoreState(m),this._rendering=!1;let e=!this._cancelled;c?.(e),l.dispatchEvent({type:F.VIDEO_RENDER_COMPLETE,success:e})}}cancel(){this._cancelled=!0}get isRendering(){return this._rendering}async _accumulateFrame(e){let t=e.stages.pathTracer;if(t?.isReady)for(;!t.isComplete&&!this._cancelled;)e.cameraManager.camera.updateMatrixWorld(),e.pipeline.render(),t.frameCount%4==0&&(Ce({samples:L(t)}),await new Promise(e=>setTimeout(e,0)))}_waitForDenoise(e){return new Promise(t=>{let n,r=()=>{e.removeEventListener(F.DENOISING_END,i),clearTimeout(n)},i=()=>{r(),t()};n=setTimeout(()=>{console.warn(`VideoRenderManager: Denoise timed out, skipping`),r(),t()},3e4),e.addEventListener(F.DENOISING_END,i),e.denoisingManager.onRenderComplete({isStillComplete:()=>!this._cancelled,context:e.pipeline?.context})})}_saveState(){let e=this._app;return{maxSamples:e.settings.get(`maxSamples`),maxBounces:e.settings.get(`maxBounces`),transmissiveBounces:e.settings.get(`transmissiveBounces`),renderMode:e.stages.pathTracer?.renderMode?.value,controlsEnabled:e.cameraManager.controls?.enabled,oidnEnabled:e.denoisingManager?.denoiser?.enabled,oidnQuality:e.denoisingManager?.denoiser?.quality,wasPlaying:e.animationManager?.isPlaying,pauseRendering:e.pauseRendering}}_restoreState(e){let t=this._app;t.settings.setMany({maxSamples:e.maxSamples,maxBounces:e.maxBounces,transmissiveBounces:e.transmissiveBounces},{silent:!0}),t.stages.pathTracer&&e.renderMode!==void 0&&t.stages.pathTracer?.setUniform(`renderMode`,parseInt(e.renderMode)),t.stages.pathTracer?.updateCompletionThreshold?.(),t.cameraManager.controls&&(t.cameraManager.controls.enabled=e.controlsEnabled??!0),t.denoisingManager?.denoiser&&(t.denoisingManager.denoiser.enabled=e.oidnEnabled??!1,e.oidnQuality&&t.denoisingManager.denoiser.updateQuality(e.oidnQuality)),t.pauseRendering=e.pauseRendering??!1,t.animationManager?.stop(),t.reset(),t.wake()}};e.AF_DEFAULTS=Ne,e.ASVGF_QUALITY_PRESETS=U,e.AUTO_FOCUS_MODES=Me,e.AnimationManager=ql,e.BVH_LEAF_MARKERS=Pe,e.CAMERA_PRESETS=je,e.CAMERA_RANGES=ke,e.CameraManager=tl,e.DEFAULT_TEXTURE_MATRIX=Le,e.DenoisingManager=Ul,e.ENGINE_DEFAULTS=B,e.EngineEvents=F,e.GoboManager=rl,e.IESManager=ml,e.INTERACTIVE_RENDER_CONFIG=ze,e.InteractionManager=gc,e.LightManager=nl,e.MEMORY_CONSTANTS=Be,e.OverlayManager=Kl,e.PRODUCTION_RENDER_CONFIG=Re,e.PathTracerApp=Xl,e.PipelineContext=fc,e.RenderPipeline=mc,e.RenderSettings=el,e.RenderStage=ve,e.SKY_PRESETS=Ae,e.StageExecutionMode=_e,e.TEXTURE_CONSTANTS=K,e.TRIANGLE_DATA_LAYOUT=W,e.TransformManager=Jl,e.VRAMTracker=qa,e.VideoRenderManager=Zl,e.bufferBytes=Ga,e.configureAssets=ta,e.getAssetConfig=na,e.textureBytes=Ka});
735
735
  //# sourceMappingURL=rayzee.umd.js.map