rayzee 4.7.3 → 4.8.0

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.
@@ -693,5 +693,5 @@
693
693
  return vec4f( newExposure, geoMean, targetExp, 1.0 );
694
694
 
695
695
  }
696
- `),Ja=class extends L{constructor(e,n={}){super(`AutoExposure`,{...n,executionMode:I.ALWAYS}),this.renderer=e,this.REDUCTION_SIZE=64,this.keyValueU=(0,s.uniform)(n.keyValue??.18),this.minExposureU=(0,s.uniform)(n.minExposure??.1),this.maxExposureU=(0,s.uniform)(n.maxExposure??20),this.adaptSpeedBrightU=(0,s.uniform)(n.adaptSpeedBright??3),this.adaptSpeedDarkU=(0,s.uniform)(n.adaptSpeedDark??.5),this.epsilonU=(0,s.uniform)(n.epsilon??1e-4),this.deltaTimeU=(0,s.uniform)(1/60),this.isFirstFrameU=(0,s.uniform)(1),this.previousExposureU=(0,s.uniform)(n.initialExposure??1),this.inputResW=(0,s.uniform)(1),this.inputResH=(0,s.uniform)(1),this._inputTexNode=new t.TextureNode,this._reductionReadTexNode=new t.TextureNode,this.currentExposure=n.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:n.FloatType,format:n.RGBAFormat,minFilter:n.NearestFilter,magFilter:n.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=n.FloatType,this._downsampleStorageTex.format=n.RGBAFormat,this._downsampleStorageTex.minFilter=n.NearestFilter,this._downsampleStorageTex.magFilter=n.NearestFilter,this._reductionStorageTex=new t.StorageTexture(1,1),this._reductionStorageTex.type=n.FloatType,this._reductionStorageTex.format=n.RGBAFormat,this._reductionStorageTex.minFilter=n.NearestFilter,this._reductionStorageTex.magFilter=n.NearestFilter,this._reductionReadTarget=new t.RenderTarget(1,1,e),this._adaptationStorageTex=new t.StorageTexture(1,1),this._adaptationStorageTex.type=n.FloatType,this._adaptationStorageTex.format=n.RGBAFormat,this._adaptationStorageTex.minFilter=n.NearestFilter,this._adaptationStorageTex.magFilter=n.NearestFilter,this._adaptationTarget=new t.RenderTarget(1,1,e)}_buildCompute(){this._buildDownsampleCompute(),this._buildReductionCompute(),this._buildAdaptationCompute()}_buildDownsampleCompute(){let e=this._inputTexNode,t=this._downsampleStorageTex,n=this.epsilonU,r=this.inputResW,i=this.inputResH;this._downsampleComputeNode=(0,s.Fn)(()=>{let a=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),o=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y)),c=r.div((0,s.float)(64)),l=i.div((0,s.float)(64)),u=(0,s.float)(a).mul(c),d=(0,s.float)(o).mul(l),f=(0,s.float)(0).toVar(),p=(0,s.float)(0).toVar();for(let t=0;t<4;t++)for(let r=0;r<4;r++){let i=zt((0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(u.add((0,s.float)((r+.5)/4).mul(c))),(0,s.int)(d.add((0,s.float)((t+.5)/4).mul(l))))).xyz);(0,s.If)(i.greaterThan(n),()=>{f.addAssign(i.add(n).log()),p.addAssign(1)})}(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(a),(0,s.uint)(o)),(0,s.vec4)(f,p,0,1)).toWriteOnly()})().compute([64/8,64/8,1],[8,8,1])}_buildReductionCompute(){let e=this._downsampleTarget.texture,t=this._reductionStorageTex,n=(0,s.workgroupArray)(`float`,256),r=(0,s.workgroupArray)(`float`,256);this._reductionComputeNode=(0,s.Fn)(()=>{let i=s.localId.x,a=(0,s.float)(0).toVar(),o=(0,s.float)(0).toVar();for(let t=0;t<16;t++){let n=i.mul(16).add(t),r=n.mod(64),c=n.div(64),l=(0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(r),(0,s.int)(c)));a.addAssign(l.x),o.addAssign(l.y)}n.element(i).assign(a),r.element(i).assign(o);for(let e=256/2;e>=1;e=Math.floor(e/2))(0,s.workgroupBarrier)(),(0,s.If)(i.lessThan((0,s.uint)(e)),()=>{n.element(i).addAssign(n.element(i.add((0,s.uint)(e)))),r.element(i).addAssign(r.element(i.add((0,s.uint)(e))))});(0,s.workgroupBarrier)(),(0,s.If)(i.equal((0,s.uint)(0)),()=>{let e=n.element((0,s.uint)(0)),i=r.element((0,s.uint)(0)),a=(0,s.max)(i,(0,s.float)(1)),o=e.div(a),c=o.exp();(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(0),(0,s.uint)(0)),(0,s.vec4)(c,i,o,1)).toWriteOnly()})})().compute(1,[256,1,1])}_buildAdaptationCompute(){let e=this._reductionReadTexNode,t=this._adaptationStorageTex,n=this.keyValueU,r=this.minExposureU,i=this.maxExposureU,a=this.adaptSpeedBrightU,o=this.adaptSpeedDarkU,c=this.deltaTimeU,l=this.isFirstFrameU,u=this.previousExposureU;this._adaptationComputeNode=(0,s.Fn)(()=>{let d=(0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(0),(0,s.int)(0))).x,f=qa(d,u,n,r,i,a,o,c,l);(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(0),(0,s.uint)(0)),f).toWriteOnly()})().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&&(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))})}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?1:0,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._reductionComputeNode),this.renderer.copyTextureToTexture(this._reductionStorageTex,this._reductionReadTarget.texture),this._reductionReadTexNode.value=this._reductionReadTarget.texture,this.renderer.compute(this._adaptationComputeNode),this.renderer.copyTextureToTexture(this._adaptationStorageTex,this._adaptationTarget.texture),!this._pendingReadback){this._pendingReadback=!0;let e=this._readbackGeneration;this.renderer.readRenderTargetPixelsAsync(this._adaptationTarget,0,0,1,1).then(t=>{this._pendingReadback=!1,e===this._readbackGeneration&&this._applyReadback(t)}).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)}dispose(){this._downsampleComputeNode?.dispose(),this._reductionComputeNode?.dispose(),this._adaptationComputeNode?.dispose(),this._downsampleTarget?.dispose(),this._downsampleStorageTex?.dispose(),this._reductionStorageTex?.dispose(),this._reductionReadTarget?.dispose(),this._adaptationStorageTex?.dispose(),this._adaptationTarget?.dispose()}};function Ya({colorTexNode:e,ndTexNode:t,motionTexNode:n,readCacheTexNode:r,readPrevNDTexNode:i,writeCacheTex:a,writePrevNDTex:o,resW:c,resH:l,temporalAlpha:u,phiNormal:d,phiDepth:f,maxHistory:p,framesSinceReset:m}){return(0,s.Fn)(()=>{let h=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),g=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y));(0,s.If)(h.lessThan((0,s.int)(c)).and(g.lessThan((0,s.int)(l))),()=>{let _=(0,s.ivec2)(h,g),v=(0,s.textureLoad)(e,_).xyz,y=(0,s.textureLoad)(t,_),b=(0,s.vec4)(v,1).toVar();(0,s.If)(m.greaterThan((0,s.int)(0)),()=>{let e=(0,s.textureLoad)(n,_),t=e.w.greaterThan(.5),a=(0,s.float)(h).sub(e.x.mul(c)),o=(0,s.float)(g).sub(e.y.mul(l)),m=a.greaterThanEqual(0).and(a.lessThan((0,s.float)(c))).and(o.greaterThanEqual(0)).and(o.lessThan((0,s.float)(l)));(0,s.If)(t.and(m),()=>{let e=(0,s.ivec2)((0,s.int)(a).clamp((0,s.int)(0),(0,s.int)(c).sub(1)),(0,s.int)(o).clamp((0,s.int)(0),(0,s.int)(l).sub(1))),t=y.xyz.mul(2).sub(1),n=(0,s.textureLoad)(i,e),m=Xt(t,n.xyz.mul(2).sub(1),y.w,n.w,d,f);(0,s.If)(m.greaterThan(.01),()=>{let t=(0,s.textureLoad)(r,e),n=t.xyz,i=t.w,a=(0,s.mix)(n,v,(0,s.min)((0,s.max)(u,(0,s.float)(1).div(i.add(1))).div((0,s.max)(m,(0,s.float)(.1))),1)),o=(0,s.min)(i.add(1),p);b.assign((0,s.vec4)(a,o))}).Else(()=>{b.assign((0,s.vec4)(v,1))})}).Else(()=>{b.assign((0,s.vec4)(v,1))})}),(0,s.textureStore)(a,(0,s.uvec2)(h,g),b).toWriteOnly(),(0,s.textureStore)(o,(0,s.uvec2)(h,g),y).toWriteOnly()})})}function Xa({colorTexNode:e,ndTexNode:t,readCacheTexNode:n,outputTex:r,resW:i,resH:a,spatialRadius:o,spatialWeight:c,phiNormal:l,phiDepth:u}){let d=[[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];return(0,s.Fn)(()=>{let f=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),p=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y));(0,s.If)(f.lessThan((0,s.int)(i)).and(p.lessThan((0,s.int)(a))),()=>{let m=(0,s.ivec2)(f,p),h=(0,s.textureLoad)(n,m),g=h.xyz,_=h.w,v=(0,s.textureLoad)(t,m),y=v.xyz.mul(2).sub(1),b=(0,s.float)(1).sub(_.div(16).clamp(0,1)),x=c.mul(b),S=(0,s.vec3)(g).toVar(),C=(0,s.float)(1).toVar();for(let e=0;e<d.length;e++){let[r,c]=d[e],m=(0,s.ivec2)(f.add((0,s.int)(o).mul(r)).clamp((0,s.int)(0),(0,s.int)(i).sub(1)),p.add((0,s.int)(o).mul(c)).clamp((0,s.int)(0),(0,s.int)(a).sub(1))),h=(0,s.textureLoad)(n,m).xyz,g=(0,s.textureLoad)(t,m),_=Xt(y,g.xyz.mul(2).sub(1),v.w,g.w,l,u);S.addAssign(h.mul(_)),C.addAssign(_)}let w=(0,s.mix)(g,S.div((0,s.max)(C,1e-4)),x),T=(0,s.textureLoad)(e,m).w;(0,s.textureStore)(r,(0,s.uvec2)(f,p),(0,s.vec4)(w,T)).toWriteOnly()})})}var Za=class extends L{constructor(e,r={}){super(`SSRC`,{...r,executionMode:I.PER_CYCLE}),this.renderer=e,this.resW=(0,s.uniform)(1),this.resH=(0,s.uniform)(1),this.temporalAlpha=(0,s.uniform)(r.temporalAlpha??.1),this.phiNormal=(0,s.uniform)(r.phiNormal??128),this.phiDepth=(0,s.uniform)(r.phiDepth??.5),this.maxHistory=(0,s.uniform)(r.maxHistory??128),this.spatialRadius=(0,s.uniform)(r.spatialRadius??4,`int`),this.spatialWeight=(0,s.uniform)(r.spatialWeight??.4),this._framesSinceReset=(0,s.uniform)(0,`int`),this._colorTexNode=new t.TextureNode,this._ndTexNode=new t.TextureNode,this._motionTexNode=new t.TextureNode,this._readCacheTexNode=new t.TextureNode,this._readPrevNDTexNode=new t.TextureNode,this._readPass1CacheTexNode=new t.TextureNode,this._cacheTexA=this._createStorageTex(1,1,n.NearestFilter),this._cacheTexB=this._createStorageTex(1,1,n.NearestFilter),this._prevNDTexA=this._createStorageTex(1,1,n.NearestFilter),this._prevNDTexB=this._createStorageTex(1,1,n.NearestFilter),this._outputTex=this._createStorageTex(1,1,n.LinearFilter),this._currentPingPong=0,this._dispatchX=1,this._dispatchY=1,this._buildComputeNodes()}setupEventListeners(){this.on(`pipeline:reset`,()=>this._resetCache()),this.on(`camera:moved`,()=>this._resetCache())}render(e){if(!this.enabled){e.removeTexture(`ssrc:output`);return}let t=e.getTexture(`pathtracer:color`);if(t?.image){let{width:e,height:n}=t.image;(e!==this._cacheTexA.image.width||n!==this._cacheTexA.image.height)&&this.setSize(e,n)}let n=e.getTexture(`pathtracer:normalDepth`);if(!n||!t)return;this._colorTexNode.value=t,this._ndTexNode.value=n;let r=e.getTexture(`motionVector:screenSpace`);r&&(this._motionTexNode.value=r);let[i,a,o]=this._currentPingPong===0?[this._cacheTexB,this._cacheTexA,this._prevNDTexB]:[this._cacheTexA,this._cacheTexB,this._prevNDTexA];this._readCacheTexNode.value=i,this._readPrevNDTexNode.value=o,this.renderer.compute(this._currentPingPong===0?this._pass1NodeA:this._pass1NodeB),this._readPass1CacheTexNode.value=a,this.renderer.compute(this._pass2Node),this._framesSinceReset.value=Math.min(this._framesSinceReset.value+1,9999),e.setTexture(`ssrc:output`,this._outputTex),this._currentPingPong=1-this._currentPingPong}reset(){this._resetCache()}setSize(e,t){if(e<1||t<1)return;this._cacheTexA.setSize(e,t),this._cacheTexB.setSize(e,t),this._prevNDTexA.setSize(e,t),this._prevNDTexB.setSize(e,t),this._outputTex.setSize(e,t),this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/8),this._dispatchY=Math.ceil(t/8);let n=[this._dispatchX,this._dispatchY,1];this._pass1NodeA&&this._pass1NodeA.setCount(n),this._pass1NodeB&&this._pass1NodeB.setCount(n),this._pass2Node&&this._pass2Node.setCount(n),this._resetCache()}dispose(){this._pass1NodeA?.dispose(),this._pass1NodeB?.dispose(),this._pass2Node?.dispose(),this._cacheTexA.dispose(),this._cacheTexB.dispose(),this._prevNDTexA.dispose(),this._prevNDTexB.dispose(),this._outputTex.dispose()}updateParameters(e){e.temporalAlpha!==void 0&&(this.temporalAlpha.value=e.temporalAlpha),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth),e.maxHistory!==void 0&&(this.maxHistory.value=e.maxHistory),e.spatialRadius!==void 0&&(this.spatialRadius.value=e.spatialRadius),e.spatialWeight!==void 0&&(this.spatialWeight.value=e.spatialWeight)}_createStorageTex(e,r,i){let a=new t.StorageTexture(e,r);return a.type=n.HalfFloatType,a.format=n.RGBAFormat,a.minFilter=i,a.magFilter=i,a}_resetCache(){this._currentPingPong=0,this._framesSinceReset.value=0}_buildComputeNodes(){let e={colorTexNode:this._colorTexNode,ndTexNode:this._ndTexNode,motionTexNode:this._motionTexNode,readCacheTexNode:this._readCacheTexNode,readPrevNDTexNode:this._readPrevNDTexNode,resW:this.resW,resH:this.resH,temporalAlpha:this.temporalAlpha,phiNormal:this.phiNormal,phiDepth:this.phiDepth,maxHistory:this.maxHistory},t=Ya({...e,writeCacheTex:this._cacheTexA,writePrevNDTex:this._prevNDTexA,framesSinceReset:this._framesSinceReset}),n=Ya({...e,writeCacheTex:this._cacheTexB,writePrevNDTex:this._prevNDTexB,framesSinceReset:this._framesSinceReset}),r=[this._dispatchX,this._dispatchY,1],i=[8,8,1];this._pass1NodeA=t().compute(r,i),this._pass1NodeB=n().compute(r,i),this._pass2Node=Xa({colorTexNode:this._colorTexNode,ndTexNode:this._ndTexNode,readCacheTexNode:this._readPass1CacheTexNode,outputTex:this._outputTex,resW:this.resW,resH:this.resH,spatialRadius:this.spatialRadius,spatialWeight:this.spatialWeight,phiNormal:this.phiNormal,phiDepth:this.phiDepth})().compute(r,i)}},Qa=class extends L{constructor(e,r={}){super(`Display`,{...r,executionMode:I.ALWAYS}),this.renderer=e,this.exposure=(0,s.uniform)(r.exposure??1),this.saturation=(0,s.uniform)(r.saturation??1),this._transparentBackground=(0,s.uniform)(0,`int`),this._displayTexNode=new t.TextureNode;let i=this._displayTexNode.sample((0,s.uv)()),a=i.xyz.mul(this.exposure),o=(0,s.mix)((0,s.vec3)((0,s.dot)(a,Ft)),a,this.saturation),c=(0,s.select)(this._transparentBackground,i.w,1);this.displayMaterial=new t.MeshBasicNodeMaterial,this.displayMaterial.colorNode=(0,s.vec4)(o,c),this.displayMaterial.blending=n.NoBlending,this.displayMaterial.toneMapped=!0,this.displayQuad=new t.QuadMesh(this.displayMaterial)}_resolveDisplayTexture(e){return e.getTexture(`bloom:output`)||e.getTexture(`edgeFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`ssrc:output`)||e.getTexture(`pathtracer:color`)}render(e){if(!this.enabled)return;let t=this._resolveDisplayTexture(e);t&&(this._displayTexNode.value=t,this.renderer.setRenderTarget(null),this.displayQuad.render(this.renderer))}setExposure(e){this.exposure.value=e}setSaturation(e){this.saturation.value=e}setTransparentBackground(e){this._transparentBackground.value=e?1:0}dispose(){this.displayMaterial?.dispose()}},$a=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,enableAdaptiveSampling:!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={}}},eo=class extends n.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):[]}},to=class{constructor(e,t,n){this.renderer=e,this.width=t,this.height=n,this.stages=[],this.context=new $a,this.eventBus=new eo,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(),!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}`),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()}},no=class extends n.EventDispatcher{constructor({scene:e,camera:t,canvas:r,assetLoader:i,pathTracer:a,floorPlane:o}){super(),this.scene=e,this.camera=t,this.canvas=r,this.assetLoader=i,this.pathTracer=a,this.floorPlane=o,this.raycaster=new n.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)}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.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 n.Mesh(new n.SphereGeometry(this.assetLoader.getSceneScale()*.02,16,16),new n.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)}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}},ro={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`}},io=class extends n.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.camera=t,this.controls=n,this.targetModel=null,this.floorPlane=null,this.sceneScale=1,this.loaderCache={},this.uploadedFileInfo=null,this.animations=[]}getFileFormat(e){return ro[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}`);z({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){try{this.dispatchEvent({type:`beforeEnvironmentLoad`,url:e});let t;if(e.startsWith(`blob:`))t=await this.loadEnvironmentFromBlob(e);else{let n=e.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 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(e,t){let r;return t===`hdr`||t===`exr`?r=await(t===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new l.HDRLoader().setDataType(n.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new d.EXRLoader().setDataType(n.FloatType))).loadAsync(e):(this.loaderCache.texture||(this.loaderCache.texture=new n.TextureLoader),r=await this.loaderCache.texture.loadAsync(e)),r.mapping=n.EquirectangularReflectionMapping,r.minFilter=n.LinearFilter,r.magFilter=n.LinearFilter,r}applyEnvironmentToScene(e){this.scene.background=e,this.scene.environment=e}async loadArchiveFromFile(e,t){try{let n=await this.readFileAsArrayBuffer(e),r=(0,m.unzipSync)(new Uint8Array(n));return await this.processObjMtlPairsInZip(r,t)||await this.findAndLoadModelFromZip(r,t)}catch(e){throw console.error(`Error loading ZIP archive:`,e),e}}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,t){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(ro[n]&&ro[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{z({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,m.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,r,i){if(e===`gltf`){let e=(0,m.strFromU8)(t);JSON.parse(e);let a=new n.LoadingManager,o=r.split(`/`).slice(0,-1).join(`/`);a.setURLModifier(e=>this.resolveZipResource(e,o,i));let s=await this.createGLTFLoader();return s.manager=a,await new Promise((t,n)=>{s.parse(e,``,e=>{this.targetModel&&B(this.targetModel),this.targetModel=e.scene,this.onModelLoad(this.targetModel).then(()=>t(e))},e=>n(e))})}else return await this.loadGLBFromArrayBuffer(t.buffer,r)}async handleObjFromZip(e,t,n){let r=(0,m.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.targetModel&&B(this.targetModel),this.targetModel=c,await this.onModelLoad(this.targetModel),c}async loadMtlFromZip(e,t,r){let i=t.split(`/`).slice(0,-1).join(`/`),a=[e,`${i}/${e}`,e.split(`/`).pop()];for(let e of a)if(r[e]){let{MTLLoader:t}=await import(`three/examples/jsm/loaders/MTLLoader.js`),a=(0,m.strFromU8)(r[e]),o=new n.LoadingManager;o.setURLModifier(e=>this.resolveZipResource(e,i,r));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,r,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 n.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,r,s));let d=this.prepareFixedMtlContent(t),f=new a(c).parse(d,u);f.preload();let p=new o(c);p.setMaterials(f);let h=(0,m.strFromU8)(e.content),g=p.parse(h);return this.targetModel&&B(this.targetModel),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,m.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(){if(this.loaderCache.gltf)return this.loaderCache.gltf;let e=new u.DRACOLoader;e.setDecoderConfig({type:`js`}),e.setDecoderPath(`https://www.gstatic.com/draco/v1/decoders/`);let t=new c.GLTFLoader;return t.setDRACOLoader(e),t.setMeshoptDecoder(p.MeshoptDecoder),this.loaderCache.gltf=t,t}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(e){try{let t=await this.createGLTFLoader();z({status:`Loading Model...`,progress:2});let n=await t.loadAsync(e);return z({status:`Processing Data...`,progress:10}),this.targetModel&&B(this.targetModel),this.targetModel=n.scene,this.animations=n.animations||[],await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n.scene,filename:e.split(`/`).pop()}),n}catch(t){throw console.error(`Error loading model:`,t),this.dispatchEvent({type:`error`,message:t.message,filename:e}),t}}async loadGLBFromArrayBuffer(e,t=`model.glb`){try{let n=await this.createGLTFLoader();z({isLoading:!0,status:`Processing GLB Data...`,progress:5}),await new Promise(e=>setTimeout(e,0));let r=await n.parseAsync(e,``);return this.targetModel&&B(this.targetModel),this.targetModel=r.scene,this.animations=r.animations||[],z({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}}async loadFBXFromArrayBuffer(e,t=`model.fbx`){try{if(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=r,z({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(z({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 r=new n.Mesh(this.loaderCache.stl.parse(e),new n.MeshStandardMaterial);return r.name=t,this.targetModel&&B(this.targetModel),this.targetModel=r,z({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 STL:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadPLYFromArrayBuffer(e,t=`model.ply`){try{if(z({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 r=this.loaderCache.ply.parse(e),i;if(r.index!==null)i=new n.Mesh(r,new n.MeshStandardMaterial);else{let e=new n.PointsMaterial({size:.01});e.vertexColors=r.hasAttribute(`color`),i=new n.Points(r,e)}return i.name=t,this.targetModel&&B(this.targetModel),this.targetModel=i,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=r.scene,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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.targetModel&&B(this.targetModel),this.targetModel=e,z({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 Xi(`onModelLoad`);t.start(`Camera extraction`);let r=this.extractCamerasFromModel(e);t.end(`Camera extraction`),t.start(`Camera setup`);let i=new n.Box3().setFromObject(e),a=i.getCenter(new n.Vector3),o=i.getSize(new n.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 n.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:r,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 r=e.userData;if(e.isRectAreaLight&&!t.includes(e.uuid)&&(e.intensity*=100/4),e.name.startsWith(`RectAreaLightPlaceholder`)&&r.name&&r.type===`RectAreaLight`){let i=new n.RectAreaLight(new n.Color(...r.color),r.intensity*.1/4,r.width,r.height);i.position.z=-2,i.name=r.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,f.createMeshesFromMultiMaterialMesh)(e);e.parent&&(e.parent.add(t),e.parent.remove(e))}})}async setupPathTracing(e,t){this.sceneScale=t}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(ro))r.type===e&&(t[n]=r);return t}return ro}dispose(){for(let e in this.loaderCache){let t=this.loaderCache[e];t&&typeof t.dispose==`function`&&t.dispose()}this.loaderCache={},super.dispose(),this.targetModel&&=(B(this.targetModel),null),console.log(`AssetLoader resources disposed`)}removeAllEventListeners(){super.dispose()}},ao={maxBounces:{uniform:`maxBounces`,reset:!0},samplesPerPixel:{uniform:`samplesPerPixel`,reset:!0},transmissiveBounces:{uniform:`transmissiveBounces`,reset:!0},environmentIntensity:{uniform:`environmentIntensity`,reset:!0},backgroundIntensity:{uniform:`backgroundIntensity`,reset:!0},showBackground:{uniform:`showBackground`,reset:!0},enableEnvironment:{uniform:`enableEnvironment`,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},enableEmissiveTriangleSampling:{uniform:`enableEmissiveTriangleSampling`,reset:!0},emissiveBoost:{uniform:`emissiveBoost`,reset:!0},visMode:{uniform:`visMode`,reset:!0},debugVisScale:{uniform:`debugVisScale`,reset:!0},useAdaptiveSampling:{uniform:`useAdaptiveSampling`,reset:!0},adaptiveSamplingMax:{uniform:`adaptiveSamplingMax`,reset:!0},maxSamples:{handler:`handleMaxSamples`,reset:!1},transparentBackground:{handler:`handleTransparentBackground`},exposure:{handler:`handleExposure`},saturation:{handler:`handleSaturation`},renderLimitMode:{handler:`handleRenderLimitMode`},renderTimeLimit:{handler:`handleRenderTimeLimit`,reset:!1},renderMode:{handler:`handleRenderMode`},environmentRotation:{handler:`handleEnvironmentRotation`}},oo={bounces:`maxBounces`,adaptiveSampling:`useAdaptiveSampling`,debugMode:`visMode`},so=class extends n.EventDispatcher{constructor(e=V){super(),this._values=new Map,this._pathTracer=null,this._resetCallback=null,this._handlers={},this._delegates={},this._initDefaults(e)}bind({pathTracer:e,resetCallback:t,handlers:n={},delegates:r={}}){this._pathTracer=e,this._resetCallback=t,this._handlers=n,this._delegates=r}set(e,t,{reset:n,silent:r}={}){let i=this._values.get(e);if(i===t)return;this._values.set(e,t);let a=ao[e];a&&(this._applyRoute(a,t,i),(n===void 0?a.reset??!0:n)&&this._resetCallback?.(),r||this.dispatchEvent({type:R.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=ao[r];a&&(this._applyRoute(a,i,e),(a.reset??!0)&&(n=!0),t||this.dispatchEvent({type:R.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=ao[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(ao))t in e&&this._values.set(t,e[t]);for(let[t,n]of Object.entries(oo))t in e&&this._values.set(n,e[t])}},co=class extends n.EventDispatcher{constructor(e,t,n){super(),this.camera=e,this.controls=t,this.interactionManager=n,this.cameras=[e],this.currentCameraIndex=0,this.autoFocusMode=Pe.SMOOTHING_FACTOR?`auto`:`manual`,this.afScreenPoint={x:.5,y:.5},this.afSmoothingFactor=Pe.SMOOTHING_FACTOR,this._lastValidFocusDistance=null,this._smoothedFocusDistance=null,this._afPointDirty=!1,this._defaultCameraState=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}`)}switchCamera(e,t,r,i){if(!(!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 r=this.cameras[e];if(this.camera.position.copy(r.position),this.camera.quaternion.copy(r.quaternion),this.camera.fov=r.fov,this.camera.near=r.near,this.camera.far=r.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls){let e=new n.Vector3(0,0,-1).applyQuaternion(r.quaternion),i=t||5;this.controls.target.copy(this.camera.position).addScaledVector(e,i),this.controls.update()}}r?.(),i?.(),this.dispatchEvent({type:`CameraSwitched`,cameraIndex:e})}}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({meshScene:e,assetLoader:t,floorPlane:n,currentFocusDistance:r,pathTracer:i,setFocusDistance:a,softReset:o,hardReset:s}){if(this.autoFocusMode===`manual`)return;let c=i;if(c?.isReady&&c.renderMode?.value===1&&c.frameCount>0&&!c.isComplete)return;let l=this.afScreenPoint.x*2-1,u=-(this.afScreenPoint.y*2-1),d=this.interactionManager?.raycaster;if(!d)return;d.setFromCamera({x:l,y:u},this.camera);let f=d.intersectObjects(e.children,!0).find(e=>e.object!==this.interactionManager?.focusPointIndicator&&e.object!==n&&!e.object.name.includes(`Helper`)&&e.object.type===`Mesh`),p;if(f)p=f.distance,this._lastValidFocusDistance=p;else if(this._lastValidFocusDistance!==null)p=this._lastValidFocusDistance;else{let e=t?.getSceneScale()||1;p=Pe.FALLBACK_DISTANCE*e,this._lastValidFocusDistance=p}let m=this._afPointDirty;this._afPointDirty=!1,m||this._smoothedFocusDistance===null||this._smoothedFocusDistance===0||Math.abs(p-this._smoothedFocusDistance)/this._smoothedFocusDistance>Pe.SNAP_THRESHOLD?this._smoothedFocusDistance=p:this._smoothedFocusDistance+=this.afSmoothingFactor*(p-this._smoothedFocusDistance);let h=r,g=this._smoothedFocusDistance;if(m||h===0||Math.abs(g-h)/Math.max(h,.001)>.001){a(g);let e=t?.getSceneScale()||1;this.dispatchEvent({type:R.AUTO_FOCUS_UPDATED,distance:g/e});let n=Math.abs(g-h)/Math.max(h,.001);m?s?.():n>Pe.RESET_THRESHOLD&&o?.()}}},lo=class extends n.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.sceneHelpers=t,this.pathTracer=n}addLight(e){let t={DirectionalLight:{position:[1,1,1],intensity:1,color:`#ffffff`},PointLight:{position:[0,2,0],intensity:100,color:`#ffffff`},SpotLight:{position:[0,1,0],intensity:300,color:`#ffffff`,angle:15},RectAreaLight:{position:[0,2,0],intensity:500,color:`#ffffff`,width:2,height:2}}[e];if(!t)return null;let r;if(e===`DirectionalLight`)r=new n.DirectionalLight(t.color,t.intensity),r.position.fromArray(t.position);else if(e===`PointLight`)r=new n.PointLight(t.color,t.intensity),r.position.fromArray(t.position);else if(e===`SpotLight`){r=new n.SpotLight(t.color,t.intensity),r.position.fromArray(t.position),r.angle=n.MathUtils.degToRad(t.angle);let e=new n.Object3D;this.scene.add(e),r.target=e}else e===`RectAreaLight`&&(r=new n.RectAreaLight(t.color,t.intensity,t.width,t.height),r.position.fromArray(t.position),r.lookAt(0,0,0));let i=this.scene.getObjectsByProperty(`isLight`,!0).length;return r.name=`${e.replace(`Light`,``)} ${i+1}`,this.scene.add(r),this.updateLights(),this._syncHelpers(),this._buildDescriptor(r)}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(),!0)}clearLights(){this.sceneHelpers.clear(),this._removeAllLights(),this.updateLights()}getLights(){return this.scene.getObjectsByProperty(`isLight`,!0).map(e=>this._buildDescriptor(e))}updateLights(){this.pathTracer?.updateLights()}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.target){let r=new n.Object3D;e.target.updateWorldMatrix(!0,!1),e.target.getWorldPosition(r.position),this.scene.add(r),t.target=r}this.scene.add(t)}this.updateLights(),this._syncHelpers()}setShowLightHelper(e){this.sceneHelpers.visible=e,e?this._syncHelpers():this.sceneHelpers.clear()}_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=n.MathUtils.radToDeg(e.angle));let r={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};if(e.type===`RectAreaLight`){r.width=e.width,r.height=e.height;let t=e.getWorldDirection(e.position.clone());r.target=[e.position.x+t.x,e.position.y+t.y,e.position.z+t.z]}else e.type===`SpotLight`&&e.target&&(r.target=[e.target.position.x,e.target.position.y,e.target.position.z]);return r}},Q=e=>Math.min(Math.max(e,0),1);function uo(e,t,n,r,i){i[0]=Q(e),i[1]=Q(t),i[2]=Q(n)}function fo(e,t,n,r,i){i[0]=Q(e*r),i[1]=Q(t*r),i[2]=Q(n*r)}function po(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=Q(e/(e+1)),i[1]=Q(t/(t+1)),i[2]=Q(n/(n+1))}function mo(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 ho(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]=Q(1.60475*a-.53108*o-.07367*s),i[1]=Q(-.10208*a+1.10813*o-.00605*s),i[2]=Q(-.00327*a-.07276*o+1.07602*s)}function go(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=Q((Math.log2(Math.max(c,1e-10))-d)/f),l=Q((Math.log2(Math.max(l,1e-10))-d)/f),u=Q((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]=Q(1.6605*m-.5876*h-.0728*g),i[1]=Q(-.1246*m+1.1329*h-.0083*g),i[2]=Q(-.0182*m-.1006*h+1.1187*g)}function _o(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 vo=new Map([[n.NoToneMapping,uo],[n.LinearToneMapping,fo],[n.ReinhardToneMapping,po],[n.CineonToneMapping,mo],[n.ACESFilmicToneMapping,ho],[n.AgXToneMapping,go],[n.NeutralToneMapping,_o]]),yo=1/2.2,bo=.2126,xo=.7152,So=.0722;function Co(e,t){if(t===1)return;let n=e[0]*bo+e[1]*xo+e[2]*So;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}var wo=null;async function To(){return wo||=(await import(`oidn-web`)).initUNetFromURL,wo}var $=new Float32Array(3),Eo={BASE_URL:`https://cdn.jsdelivr.net/npm/denoiser/tzas/`,QUALITY_SUFFIXES:{fast:`_small`,balance:``,high:`_large`},DEFAULT_OPTIONS:{enableOIDN:!0,oidnQuality:`fast`,debugGbufferMaps:!0,tileSize:256}},Do=class extends n.EventDispatcher{constructor(e,t,r,i,a={}){if(super(),!e||!t||!r||!i)throw Error(`OIDNDenoiser requires output canvas, renderer, scene, and camera`);this.renderer=t,this.scene=r,this.camera=i,this.input=t.domElement,this.output=e,this.debugContainer=a.debugContainer||null,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||(()=>n.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._cachedAlpha=null,this._cachedAlphaWidth=0,this.config={...Eo.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.currentTZAUrl=null,this.unet=null,this.debugHelpers=null,this._lastAlbedoTexture=null,this._lastNormalTexture=null,this._initialize().catch(e=>{console.error(`Failed to initialize OIDNDenoiser:`,e),this.dispatchEvent({type:`error`,error:e})})}async _initialize(){try{this._setupCanvas(),this._initDebugVisualization(),await this._setupUNetDenoiser()}catch(e){throw Error(`Initialization failed: ${e.message}`)}}_initDebugVisualization(){this.debugHelpers=null}_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 To())(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}}_generateTzaUrl(){let{BASE_URL:e,QUALITY_SUFFIXES:t}=Eo;return`${e}rt_hdr_alb_nrm${t[this.quality]||``}.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(Eo.QUALITY_SUFFIXES,e))throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(Eo.QUALITY_SUFFIXES).join(`, `)}`);await this.updateConfiguration({oidnQuality:e})}async start(){if(!this.enabled||this.state.isDenoising||this.state.isLoading)return!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=(n,r)=>i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:r,offset:0,bytesPerRow:a,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});o(n.color,this._gpuInputBuffers.color),o(n.albedo,this._gpuInputBuffers.albedo),o(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 s={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(s)}_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*4*4,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}}_destroyGPUInputBuffers(){this._gpuInputBuffers.color?.destroy(),this._gpuInputBuffers.albedo?.destroy(),this._gpuInputBuffers.normal?.destroy(),this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputBufferSize={width:0,height:0}}async _cacheInputAlpha(e,t,n){let r=t*n*4*4,i=e.createBuffer({label:`oidn-alpha-staging`,size:r,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),a=e.createCommandEncoder();a.copyBufferToBuffer(this._gpuInputBuffers.color,0,i,0,r),e.queue.submit([a.finish()]),await i.mapAsync(GPUMapMode.READ);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(),i.destroy(),this._cachedAlpha=c,this._cachedAlphaWidth=t}_executeWithAbortGPU(e){return new Promise((t,r)=>{if(this.state.abortController?.signal.aborted){r(new DOMException(`Aborted`,`AbortError`));return}let i=null,a=()=>{i&&=(i(),null),r(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{await this._displayGPUOutput(e),t()}catch(e){r(e)}},progress:(e,t,r)=>{if(!e?.data||!r)return;this.dispatchEvent({type:`tileProgress`,tile:r,imageWidth:e.width,imageHeight:e.height});let i=this.gpuDevice,a=e.width,o=r.width*16,s=r.width*r.height*16,c=i.createBuffer({size:s,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),l=i.createCommandEncoder();for(let t=0;t<r.height;t++){let n=((r.y+t)*a+r.x)*16,i=t*o;l.copyBufferToBuffer(e.data,n,c,i,o)}i.queue.submit([l.finish()]),c.mapAsync(GPUMapMode.READ).then(()=>{let e=new Float32Array(c.getMappedRange()),t=new ImageData(r.width,r.height),i=this.getExposure(),a=this.getSaturation(),o=vo.get(this.getToneMapping())||vo.get(n.ACESFilmicToneMapping),s=this._cachedAlpha,l=this._cachedAlphaWidth;for(let n=0,c=e.length;n<c;n+=4){let c=e[n]*i,u=e[n+1]*i,d=e[n+2]*i;if(a!==1&&($[0]=c,$[1]=u,$[2]=d,Co($,a),c=$[0],u=$[1],d=$[2]),o(c,u,d,1,$),t.data[n]=$[0]**yo*255|0,t.data[n+1]=$[1]**yo*255|0,t.data[n+2]=$[2]**yo*255|0,s){let e=(n>>2)%r.width,i=(n>>2)/r.width|0;t.data[n+3]=s[(r.y+i)*l+r.x+e]}else t.data[n+3]=255}c.unmap(),c.destroy(),this.ctx.putImageData(t,r.x,r.y)})}})})}async _displayGPUOutput({data:e,width:t,height:r}){let i=this.gpuDevice;if(!i){console.error(`OIDNDenoiser: gpuDevice not available for output readback`);return}let a=t*r*4*4,o=i.createBuffer({label:`oidn-output-staging`,size:a,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),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,r),u=this.getExposure(),d=this.getSaturation(),f=vo.get(this.getToneMapping())||vo.get(n.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&&($[0]=t,$[1]=n,$[2]=r,Co($,d),t=$[0],n=$[1],r=$[2]),f(t,n,r,1,$),l.data[e]=$[0]**yo*255|0,l.data[e+1]=$[1]**yo*255|0,l.data[e+2]=$[2]**yo*255|0,l.data[e+3]=p?p[e>>2]:255}o.unmap(),o.destroy(),this.ctx.putImageData(l,0,0)}abort(){!this.enabled||!this.state.isDenoising||(this.state.abortController?.abort(),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)})}_updateDebugVisualization(e){if(!e?.textures||e.textures.length<3)return;let t=this.debugHelpers&&(this._lastAlbedoTexture!==e.textures[2]||this._lastNormalTexture!==e.textures[1]);if(!this.debugHelpers||t){this.debugHelpers&&(this.debugHelpers.albedo?.dispose(),this.debugHelpers.normal?.dispose(),console.log(`OIDNDenoiser: Recreating debug helpers due to texture change`)),this.debugHelpers={albedo:La(this.renderer,e,{width:250,height:250,position:`bottom-right`,theme:`dark`,title:`OIDN Albedo`,autoUpdate:!1,textureIndex:2}),normal:La(this.renderer,e,{width:250,height:250,position:`bottom-left`,theme:`dark`,title:`OIDN Normal`,autoUpdate:!1,textureIndex:1})},this._lastAlbedoTexture=e.textures[2],this._lastNormalTexture=e.textures[1];let t=this.debugContainer||document.body;t.appendChild(this.debugHelpers.albedo),t.appendChild(this.debugHelpers.normal),this.debugHelpers.albedo.hide(),this.debugHelpers.normal.hide()}this.debugHelpers.albedo.update(),this.debugHelpers.normal.update()}dispose(){this.abort(),this.unet?.dispose(),this._destroyGPUInputBuffers(),this.debugHelpers&&=(this.debugHelpers.albedo?.dispose(),this.debugHelpers.normal?.dispose(),null),this._lastAlbedoTexture=null,this._lastNormalTexture=null,this.output?.parentNode&&this.output.remove(),this.unet=null,this.ctx=null,this.state.abortController=null,this.removeAllListeners?.(),console.log(`OIDNDenoiser disposed`)}},Oo=`https://huggingface.co/notaneimu/onnx-image-models/resolve/main/`,ko={QUALITY_PRESETS:{fast:{2:Oo+`2x-spanx2-ch48.onnx`,4:Oo+`4xNomos8k_span_otf_strong_fp32_opset17.onnx`},balanced:{2:Oo+`2xNomosUni_compact_otf_medium.onnx`,4:Oo+`RealESRGAN_x4plus.onnx`},quality:{2:Oo+`2x-realesrgan-x2plus.onnx`,4:Oo+`4xNomos2_hq_mosr_fp32.onnx`}},TILE_SIZE:512,TILE_OVERLAP:16,SESSION_OPTIONS:{executionProviders:[{name:`webgpu`,preferredLayout:`NCHW`}],graphOptimizationLevel:`all`}},Ao=class extends n.EventDispatcher{constructor(e,t,r={}){if(super(),!e||!t)throw Error(`AIUpscaler requires output canvas and renderer`);this.renderer=t,this.input=t.domElement,this.output=e,this.getSourceCanvas=r.getSourceCanvas||null,this.getGPUTextures=r.getGPUTextures||null,this.getExposure=r.getExposure||(()=>1),this.getToneMapping=r.getToneMapping||(()=>n.ACESFilmicToneMapping),this.getSaturation=r.getSaturation||(()=>1),this.enabled=!1,this.hdr=!1,this.scaleFactor=r.scaleFactor||2,this.quality=r.quality||`fast`,this.tileSize=r.tileSize||ko.TILE_SIZE,this._tileSizeOverride=!!r.tileSize,this.state={isUpscaling:!1,isLoading:!1,abortController:null},this._worker=null,this._currentModelUrl=null,this._tileId=0,this._upscaledAlpha=null,this._upscaledAlphaWidth=0,this._backupCanvas=null,this._baseWidth=e.width,this._baseHeight=e.height}async _ensureSession(){let e=ko.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{this._worker||=new Worker(new URL(``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/AIUpscalerWorker-BRtNMgzZ.js`).href:new URL(`assets/AIUpscalerWorker-BRtNMgzZ.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href),``+{}.url),{type:`module`}),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)))};this._worker.addEventListener(`message`,r),this._worker.postMessage({type:`load`,url:t,sessionOptions:ko.SESSION_OPTIONS})}),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.state.isUpscaling&&(this.state.isUpscaling=!1,this.state.abortController=null,this.dispatchEvent({type:`end`}))}}abort(){this.state.isUpscaling&&(this.state.abortController?.abort(),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:r,height:i}=t,a=this.scaleFactor,o=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});this._cacheUpscaledAlpha(t,r*a,i*a),t.isHDR&&(this._hdrToneMapFn=vo.get(this.getToneMapping())||vo.get(n.ACESFilmicToneMapping),this._hdrExposure=this.getExposure(),this._hdrSaturation=this.getSaturation(),this._tmOut=new Float32Array(3));let s=ko.TILE_OVERLAP,c=this.tileSize,l=c-s*2,u=Math.ceil(r/l),d=Math.ceil(i/l),f=u*d,p=0;for(let n=0;n<d;n++)for(let s=0;s<u;s++){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`);let u=Math.min(s*l,Math.max(0,r-c)),d=Math.min(n*l,Math.max(0,i-c)),m=Math.min(c,r-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:n,total:f,completed:p}}),this.dispatchEvent({type:`tileProgress`,tile:{x:v,y,width:b,height:x},imageWidth:r*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,s=t.createBuffer({size:o,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),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(),s.destroy(),{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,Co(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]**+yo,l[c+d]=this._tmOut[1]**+yo,l[2*c+d]=this._tmOut[2]**+yo}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),e.data.type===`inferred`?i(e.data.outputData):e.data.type===`error`&&a(Error(e.data.message)))};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:r,width:i,height:a}=e,o=t.createImageData(i,a),s=o.data,c=vo.get(this.getToneMapping())||vo.get(n.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,n=r[t]*l,i=r[t+1]*l,a=r[t+2]*l;u!==1&&(d[0]=n,d[1]=i,d[2]=a,Co(d,u),n=d[0],i=d[1],a=d[2]),c(n,i,a,1,d),s[t]=d[0]**+yo*255+.5|0,s[t+1]=d[1]**+yo*255+.5|0,s[t+2]=d[2]**+yo*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(!ko.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}async dispose(){this.abort(),this._worker&&=(this._worker.postMessage({type:`dispose`}),this._worker.terminate(),null),this._currentModelUrl=null,this._backupCanvas=null,this._upscaledAlpha=null,this.state.abortController=null,console.log(`AIUpscaler disposed`)}},jo=class extends n.EventDispatcher{constructor({renderer:e,denoiserCanvas:t,scene:n,camera:r,stages:i,pipeline:a,getExposure:o,getSaturation:s,getTransparentBg:c}){super(),this.renderer=e,this.denoiserCanvas=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}setupDenoiser(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.denoiser=new Do(this.denoiserCanvas,this.renderer,this.scene,this.camera,{...V,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=V.enableOIDN,this.denoiser.addEventListener(`start`,()=>this.dispatchEvent({type:R.DENOISING_START})),this.denoiser.addEventListener(`end`,()=>this.dispatchEvent({type:R.DENOISING_END}))}setupUpscaler(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.upscaler=new Ao(this.denoiserCanvas,this.renderer,{scaleFactor:V.upscalerScale||2,quality:V.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=V.enableUpscaler||!1,this.upscaler.addEventListener(`resolution_changed`,e=>this.dispatchEvent({type:`resolution_changed`,width:e.width,height:e.height})),this.upscaler.addEventListener(`start`,()=>this.dispatchEvent({type:R.UPSCALING_START})),this.upscaler.addEventListener(`progress`,e=>this.dispatchEvent({type:R.UPSCALING_PROGRESS,progress:e.progress})),this.upscaler.addEventListener(`end`,()=>this.dispatchEvent({type:R.UPSCALING_END}))}setDenoiserStrategy(e,t){let n=this._stages;switch(n.asvgf&&(n.asvgf.enabled=!1),n.variance&&!this._isAdaptiveSamplingActive()&&(n.variance.enabled=!1),n.bilateralFilter&&(n.bilateralFilter.enabled=!1),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!1),n.ssrc&&(n.ssrc.enabled=!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`ssrc`:n.ssrc&&(n.ssrc.enabled=!0);break;case`edgeaware`:n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!0);break}}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)}applyASVGFPreset(e){this._applyASVGFPreset(e)}setAutoExposureEnabled(e,t){let n=this._stages;n.autoExposure&&(n.autoExposure.enabled=e,e?n.display?.setExposure(1):(n.display?.setExposure(t),n.display&&this.renderer&&(this.renderer.toneMappingExposure=1)))}setAdaptiveSamplingEnabled(e){let t=this._stages;t.adaptiveSampling&&(t.adaptiveSampling.enabled=e,t.adaptiveSampling.toggleHelper(!1)),e?t.variance&&(t.variance.enabled=!0):t.asvgf?.enabled||t.variance&&(t.variance.enabled=!1),!e&&this.pipeline?.context&&!t.asvgf?.enabled&&this.pipeline.context.removeTexture(`variance:output`)}onRenderComplete({isStillComplete:e,context:t}){(this.denoiser?.enabled||this.upscaler?.enabled)&&this.denoiserCanvas&&(this.denoiserCanvas.style.display=`block`);let n=()=>{e()&&this.upscaler?.enabled&&this.upscaler.start()};this.denoiser?.enabled?(this.denoiser.addEventListener(`end`,n,{once:!0}),this.denoiser.start()):(this.upscaler?.enabled&&this._stages.display&&t&&this._stages.display.render(t),n())}abort(e){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.denoiser&&=(this.denoiser.dispose(),null),this.upscaler&&=(this.upscaler.dispose(),null)}_getEffectiveExposure(){return this._stages.autoExposure?.enabled?this.renderer.toneMappingExposure:this._getExposure()}_getToneMapping(){return this.renderer.toneMapping}_isAdaptiveSamplingActive(){return this._stages.adaptiveSampling?.enabled??!1}_clearDenoiserTextures(){let e=this.pipeline?.context;e&&[`asvgf:output`,`asvgf:temporalColor`,`asvgf:variance`,`variance:output`,`bilateralFiltering:output`,`edgeFiltering:output`,`ssrc:output`].forEach(t=>e.removeTexture(t))}_applyASVGFPreset(e){let t=ke[e];t&&this._stages.asvgf?.updateParameters(t)}},Mo=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}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)}},No=class{constructor(){this.mixer=null,this.timer=new n.Timer,this.actions=[],this.isPlaying=!1,this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._tempVec=new n.Vector3,this._skinnedCache=null,this._totalTriangleCount=0,this._clipsCache=null,this._savedTimeScale=1,this.onFinished=null}init(e,t,r,i,a){if(this.dispose(),!i||i.length===0)return;this._scene=e,this._mixerRoot=t,this._meshes=r,this._totalTriangleCount=a,this.mixer=new n.AnimationMixer(t);let o=i.map(e=>this.mixer.clipAction(e)),s=(e,t)=>e.name===t||e.getObjectByName(t)!==void 0;!o.some(e=>e.getClip().tracks.some(e=>{let n=e.name.split(`.`)[0];return s(t,n)}))&&t!==e&&(console.log(`[AnimationManager] Tracks did not resolve from model root, retrying with scene root`),this.mixer=new n.AnimationMixer(e),this._mixerRoot=e,o=i.map(e=>this.mixer.clipAction(e))),this.actions=o,this.mixer.addEventListener(`finished`,()=>{this.isPlaying=!1,this.timer.reset(),this.onFinished&&this.onFinished()}),this._meshTriRanges=[],this._skinnedCache=[];let c=0;for(let e of r){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:c,count:i,uniqueVerts:a,indices:r}),this._skinnedCache.push(new Float32Array(a*3)),c+=i}this._posBuffer=new Float32Array(a*9);let l=r.filter(e=>e.isSkinnedMesh).length;console.debug(`[AnimationManager] Init: ${i.length} clips, ${r.length} meshes (${l} skinned), ${a} 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}}pause(){this.mixer&&(this.mixer.timeScale=0,this.timer.reset(),this.isPlaying=!1)}resume(){this.mixer&&(this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!0)}stop(){this.mixer&&(this.mixer.stopAllAction(),this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!1)}setSpeed(e){this._savedTimeScale=e,this.mixer&&this.isPlaying&&(this.mixer.timeScale=e)}setLoop(e){let t=e?n.LoopRepeat:n.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}},Po=class{constructor({camera:e,canvas:t,orbitControls:r,app:i}){this._app=i,this._orbitControls=r,this._camera=e,this._controls=new h.TransformControls(e,t),this._gizmoScene=new n.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 n.Vector3,this._normalMatrix=new n.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,t){this._meshes=e,this._meshTriRanges=[],this._skinnedCache=[],this._normalCache=[];let n=0;for(let t of e){let e=t.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:n,count:a,uniqueVerts:o,indices:i}),this._skinnedCache.push(new Float32Array(o*3)),this._normalCache.push(new Float32Array(o*3)),n+=a}this._posBuffer=new Float32Array(t*9),this._normalBuffer=new Float32Array(t*9)}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)}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:R.OBJECT_TRANSFORM_START}):(this._recomputeAndRefit(),this._app.dispatchEvent({type:R.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}},Fo=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._borderWidth=2}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;e.strokeStyle=this._borderColor,e.lineWidth=this._borderWidth,e.strokeRect(o,s,c,l)}show(){this.enabled&&(this.visible=!0)}hide(){this.visible=!1,this._tileBounds=null}dispose(){this.visible=!1}},Io=class{constructor(e,r,i){this.layer=`scene`,this.visible=!0,this._outlineNode=(0,g.outline)(r,i,{selectedObjects:[],edgeThickness:(0,s.uniform)(1),edgeGlow:(0,s.uniform)(0)}),this._displayWidth=1,this._displayHeight=1;let a=this._outlineNode.setSize.bind(this._outlineNode);this._outlineNode.setSize=()=>{a(this._displayWidth,this._displayHeight)};let o=(0,s.uniform)(3),c=(0,s.uniform)(new n.Color(16777215)),l=(0,s.uniform)(new n.Color(1640965)),{visibleEdge:u,hiddenEdge:d}=this._outlineNode,f=u.mul(c).add(d.mul(l)).mul(o);this._material=new t.MeshBasicNodeMaterial,this._material.colorNode=(0,s.vec4)(f,1),this._material.blending=n.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?.dispose()}},Lo=class extends n.EventDispatcher{constructor(e,t=null,n={}){super(),this.canvas=e,this.denoiserCanvas=t,this._autoResize=n.autoResize!==!1,this._statsContainer=n.statsContainer||null,this.settings=new so(V),this.renderer=null,this._camera=null,this.scene=null,this.meshScene=null,this._sceneHelpers=null,this._controls=null,this.assetLoader=null,this._sdf=null,this.animationManager=new No,this._animRefitInFlight=!1,this.pipeline=null,this.stages={},this.cameraManager=null,this.lightManager=null,this.denoisingManager=null,this.overlayManager=null,this.isInitialized=!1,this.pauseRendering=!1,this.pathTracerEnabled=!0,this.animationId=null,this.needsReset=!1,this._renderCompleteDispatched=!1,this._loadingInProgress=!1,this._needsDisplayRefresh=!1,this._paused=!1,this.lastResetTime=performance.now(),this.timeElapsed=0,this._lastRenderWidth=0,this._lastRenderHeight=0,this._resizeDebounceTimer=null}set(e,t,n){this.settings.set(e,t,n)}setMany(e,t){this.settings.setMany(e,t)}get(e){return this.settings.get(e)}getAll(){return this.settings.getAll()}async init(){if(_e(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 a=e.limits;this.renderer=new t.WebGPURenderer({canvas:this.canvas,alpha:!0,powerPreference:`high-performance`,requiredLimits:{maxBufferSize:a.maxBufferSize,maxStorageBufferBindingSize:a.maxStorageBufferBindingSize,maxColorAttachmentBytesPerSample:128}}),window.renderer=this.renderer,await this.renderer.init(),t.RectAreaLightNode.setLTC(r.RectAreaLightTexturesLib.init()),this.renderer.toneMapping=n.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1;let o=this.canvas.clientWidth,s=this.canvas.clientHeight;this.renderer.setPixelRatio(1),this._camera=new n.PerspectiveCamera(60,o/s||1,.01,1e3),this._camera.position.set(0,0,5),this.scene=new n.Scene,this.meshScene=new n.Scene,this._sceneHelpers=new T,this._controls=new i.OrbitControls(this._camera,this.canvas),this._controls.screenSpacePanning=!0,this._controls.zoomToCursor=!0,this._controls.saveState(),this._sdf=new Aa,this.assetLoader=new io(this.meshScene,this._camera,this._controls),this._setupFloorPlane(),this.assetLoader.setFloorPlane(this._floorPlane),this._controls.addEventListener(`change`,()=>{this.needsReset=!0,this.wake()}),this._createStages();let{clientWidth:c,clientHeight:l}=this.canvas;this.pipeline=new to(this.renderer,c||1,l||1),this.pipeline.addStage(this.stages.pathTracer),this.pipeline.addStage(this.stages.normalDepth),this.pipeline.addStage(this.stages.motionVector),this.pipeline.addStage(this.stages.ssrc),this.pipeline.addStage(this.stages.asvgf),this.pipeline.addStage(this.stages.variance),this.pipeline.addStage(this.stages.bilateralFilter),this.pipeline.addStage(this.stages.adaptiveSampling),this.pipeline.addStage(this.stages.edgeFilter),this.pipeline.addStage(this.stages.autoExposure),this.pipeline.addStage(this.stages.display);let u=o||1,d=s||1;this.pipeline.setSize(u,d),this._lastRenderWidth=u,this._lastRenderHeight=d,this._interactionManager=new no({scene:this.meshScene,camera:this._camera,canvas:this.canvas,assetLoader:this.assetLoader,pathTracer:null,floorPlane:this._floorPlane}),this._setupInteractionListeners(),this.cameraManager=new co(this._camera,this._controls,this._interactionManager),this.lightManager=new lo(this.scene,this._sceneHelpers,this.stages.pathTracer),this._setupDenoisingManager(),this._setupOverlayManager(),this._transformManager=new Po({camera:this._camera,canvas:this.canvas,orbitControls:this._controls,app:this}),this.cameraManager.addEventListener(`CameraSwitched`,e=>this.dispatchEvent(e)),this.cameraManager.addEventListener(R.AUTO_FOCUS_UPDATED,e=>this.dispatchEvent(e)),this._forwardEvents(this.denoisingManager,[R.DENOISING_START,R.DENOISING_END,R.UPSCALING_START,R.UPSCALING_PROGRESS,R.UPSCALING_END,`resolution_changed`]),this._setupAutoExposureListener(),this._autoFocusContext={meshScene:this.meshScene,assetLoader:this.assetLoader,floorPlane:this._floorPlane,get currentFocusDistance(){return null},pathTracer:this.stages.pathTracer,setFocusDistance:e=>this.settings.set(`focusDistance`,e,{silent:!0}),softReset:()=>this.reset(!0),hardReset:()=>this.reset()};let f=this.settings;return Object.defineProperty(this._autoFocusContext,`currentFocusDistance`,{get:()=>f.get(`focusDistance`)}),this.settings.bind({pathTracer:this.stages.pathTracer,resetCallback:()=>this.reset(),handlers:this._buildSettingsHandlers(),delegates:{}}),this.onResize(),this.resizeHandler=()=>this.onResize(),this._autoResize&&window.addEventListener(`resize`,this.resizeHandler),this._onAssetLoaded=async e=>{if(!this._loadingInProgress){if(e.model)await this.loadSceneData();else if(e.texture){let e=this.meshScene.environment;e&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(e),ve()}this.pauseRendering=!1,this.reset()}},this.assetLoader.addEventListener(`load`,this._onAssetLoaded),this.assetLoader.addEventListener(`modelProcessed`,e=>{let t=[this._camera,...e.cameras||[]];this.cameraManager.setCameras(t),this._floorPlane=this.assetLoader.floorPlane,this._interactionManager&&(this._interactionManager.floorPlane=this._floorPlane)}),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._initStats(),this.isInitialized=!0,console.log(`WebGPU Path Tracer App initialized`),this}animate(){if(this.animationId=requestAnimationFrame(()=>this.animate()),this._loadingInProgress||this._sdf?.isProcessing){this._stats?.update();return}if(this._controls&&this._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._camera.updateMatrixWorld(),!this.pathTracerEnabled){this.renderer.render(this.meshScene,this._camera),this._renderHelperOverlay();return}if(!this.pauseRendering){if(this.cameraManager.updateAutoFocus(this._autoFocusContext),this.stages.pathTracer?.isReady){if(this.stages.pathTracer.isComplete&&this._renderCompleteDispatched){this._needsDisplayRefresh&&(this._needsDisplayRefresh=!1,this.stages.display.render(this.pipeline.context),this._renderHelperOverlay()),this.stopAnimation();return}this.pipeline.render(),this.stages.pathTracer.isComplete||(this.timeElapsed=(performance.now()-this.lastResetTime)/1e3),ye({timeElapsed:this.timeElapsed,samples:be(this.stages.pathTracer)});let e=this.settings.get(`renderLimitMode`),t=this.settings.get(`renderTimeLimit`);e===`time`&&t>0&&this.timeElapsed>=t&&(this.stages.pathTracer.isComplete=!0),this.stages.pathTracer.isComplete&&!this._renderCompleteDispatched&&(this._renderCompleteDispatched=!0,this.denoisingManager.onRenderComplete({isStillComplete:()=>this._renderCompleteDispatched,context:this.pipeline?.context}),this.dispatchEvent({type:`RenderComplete`}),this.dispatchEvent({type:R.RENDER_COMPLETE}))}this._renderHelperOverlay(),this._stats?.update(),this.renderer.resolveTimestampsAsync?.(n.TimestampQuery.RENDER),this.renderer.resolveTimestampsAsync?.(n.TimestampQuery.COMPUTE)}}stopAnimation(){this.animationId&&=(cancelAnimationFrame(this.animationId),null)}wake(){!this.animationId&&this.isInitialized&&!this._paused&&this.animate()}pause(){this._paused=!0,this.stopAnimation(),this._stats&&(this._stats.dom.style.display=`none`)}resume(){this._paused=!1,this.animationId||this.animate(),this._stats&&(this._stats.dom.style.display=``)}reset(e=!1){if(this.pipeline&&(this.pipeline.reset(),e||this.pipeline.eventBus.emit(`asvgf:reset`)),this.denoisingManager?.abort(this.canvas),this.denoiserCanvas&&this._lastRenderWidth&&this._lastRenderHeight){let e=this.denoiserCanvas.width!==this._lastRenderWidth||this.denoiserCanvas.height!==this._lastRenderHeight;this.denoiserCanvas.width=this._lastRenderWidth,this.denoiserCanvas.height=this._lastRenderHeight,e&&this.dispatchEvent({type:`resolution_changed`,width:this._lastRenderWidth,height:this._lastRenderHeight})}this.timeElapsed=0,this.lastResetTime=performance.now(),this._renderCompleteDispatched=!1,this.wake(),this.dispatchEvent({type:`RenderReset`}),this.dispatchEvent({type:R.RENDER_RESET})}dispose(){this.animationManager?.dispose(),this.stopAnimation(),_e(null),this.assetLoader&&this._onAssetLoaded&&this.assetLoader.removeEventListener(`load`,this._onAssetLoaded),this._transformManager?.dispose(),this.overlayManager?.dispose(),this._sceneHelpers?.clear(),this.denoisingManager?.dispose(),this.pipeline?.dispose(),this._interactionManager?.dispose(),this._controls?.dispose(),this.renderer?.dispose(),this._stats&&=(this._stats.dom.remove(),null),clearTimeout(this._resizeDebounceTimer),window.removeEventListener(`resize`,this.resizeHandler),this.isInitialized=!1}async loadModel(e){await this._loadWithSceneRebuild(()=>this.assetLoader.loadModel(e),{type:`ModelLoaded`,url:e})}async loadEnvironment(e){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})}async _loadWithSceneRebuild(e,t){this._loadingInProgress=!0;try{await e(),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.animationManager.dispose(),this._animRefitInFlight=!1;let e=new Xi(`loadSceneData`),t=this.meshScene.environment,n=null;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)`),await this._sdf.buildBVH(this.meshScene),e.end(`BVH build (SceneProcessor)`);let{triangleData:r,triangleCount:i,bvhData:a,materialData:o}=this._sdf;if(!r)return console.error(`PathTracerApp: Failed to get triangle data`),!1;if(z({status:`Transferring data to GPU...`,progress:86}),await new Promise(e=>setTimeout(e,0)),e.start(`GPU data transfer`),this.stages.pathTracer.setTriangleData(r,i),!a)return console.error(`PathTracerApp: Failed to get BVH data`),!1;this.stages.pathTracer.setBVHData(a),o?this.stages.pathTracer.materialData.setMaterialData(o):console.warn(`PathTracerApp: No material data, using defaults`),t&&this.stages.pathTracer.environment.setEnvironmentTexture(t),this.stages.pathTracer.materialData.setMaterialTextures({albedoMaps:this._sdf.albedoTextures,normalMaps:this._sdf.normalTextures,bumpMaps:this._sdf.bumpTextures,roughnessMaps:this._sdf.roughnessTextures,metalnessMaps:this._sdf.metalnessTextures,emissiveMaps:this._sdf.emissiveTextures,displacementMaps:this._sdf.displacementTextures}),this._sdf.emissiveTriangleData&&this.stages.pathTracer.setEmissiveTriangleData(this._sdf.emissiveTriangleData,this._sdf.emissiveTriangleCount,this._sdf.emissiveTotalPower),this._sdf.lightBVHNodeData&&this.stages.pathTracer.setLightBVHData(this._sdf.lightBVHNodeData,this._sdf.lightBVHNodeCount),this.lightManager.transferSceneLights(this.meshScene),e.end(`GPU data transfer`),z({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)`),n&&(z({status:`Finalizing environment map...`,progress:95}),await n,this.stages.pathTracer.environment.applyCDFResults()),e.start(`Apply settings`),this.settings.applyAll(),this.stages.display.setTransparentBackground(this.settings.get(`transparentBackground`)),e.end(`Apply settings`),e.print(),ve();let s=this.assetLoader?.animations||[];if(s.length>0){let e=this.assetLoader?.targetModel||this.meshScene;this.animationManager.init(this.meshScene,e,this._sdf.meshes,s,this._sdf.triangleCount),this.animationManager.onFinished=()=>{this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_FINISHED})}}return this._transformManager?.setMeshData(this._sdf.meshes,this._sdf.triangleCount),this.dispatchEvent({type:`SceneRebuild`}),!0}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),i=this._sdf.instanceTable,a=[],o=[];for(let t of e){let e=i.entries[t];e&&(a.push({offset:e.triOffset*32,count:e.triCount*32}),o.push({offset:e.blasOffset*16,count:e.blasNodeCount*16}))}return o.push({offset:0,count:i.tlasNodeCount*16}),this.stages.pathTracer.updateBufferRanges(a,o),this.reset(),this._sdf.scheduleBackgroundRebuild(e,()=>{this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset()}),r}playAnimation(e=0){if(!this.animationManager?.hasAnimations){console.warn(`playAnimation: No animation clips available`);return}this.animationManager.play(e),this.wake(),this.dispatchEvent({type:R.ANIMATION_STARTED,clipIndex:e})}pauseAnimation(){this.animationManager?.pause(),this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_PAUSED})}resumeAnimation(){this.animationManager?.resume(),this.wake(),this.dispatchEvent({type:R.ANIMATION_STARTED})}stopAnimationPlayback(){this.animationManager?.stop(),this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_STOPPED})}setAnimationSpeed(e){this.animationManager?.setSpeed(e)}setAnimationLoop(e){this.animationManager?.setLoop(e)}get animationClips(){return this.animationManager?.clips||[]}onResize(){let e=this.canvas.clientWidth,t=this.canvas.clientHeight;if(e===0||t===0)return;this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this._camera.aspect=e/t,this._camera.updateProjectionMatrix();let n=window.devicePixelRatio||1;this.overlayManager?.setSize(Math.round(e*n),Math.round(t*n)),!(e===this._lastRenderWidth&&t===this._lastRenderHeight)&&(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{this._applyRenderResize(e,t)},300))}_applyRenderResize(e,t){this._lastRenderWidth=e,this._lastRenderHeight=t,this.pipeline?.setSize(e,t),this.denoisingManager?.denoiser?.setSize(e,t),this.denoisingManager?.upscaler?.setBaseSize(e,t),this.needsReset=!0,this.dispatchEvent({type:`resolution_changed`,width:e,height:t})}setCanvasSize(e,t){this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.denoiserCanvas&&(this.denoiserCanvas.style.width=`${e}px`,this.denoiserCanvas.style.height=`${t}px`),!(e===0||t===0)&&(this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this._camera.aspect=e/t,this._camera.updateProjectionMatrix(),clearTimeout(this._resizeDebounceTimer),this._applyRenderResize(e,t))}configureForMode(e,t={}){if(e===`results`){this.pauseRendering=!0,this._controls.enabled=!1,this.renderer?.domElement&&(this.renderer.domElement.style.display=`none`),this.denoisingManager?.denoiser?.output&&(this.denoisingManager.denoiser.output.style.display=`none`);return}let n=e===`final-render`,r=n?G:Ie;this._controls.enabled=!n,this.settings.setMany({maxSamples:r.maxSamples,maxBounces:r.bounces,samplesPerPixel:r.samplesPerPixel,transmissiveBounces:r.transmissiveBounces},{silent:!0}),this.setRenderMode(r.renderMode),this.setTileCount(r.tiles),this.setTileHelperEnabled(r.tilesHelper),this.stages.pathTracer?.updateCompletionThreshold?.();let i=this.denoisingManager?.denoiser;i&&(i.abort(),i.enabled=r.enableOIDN,i.updateQuality(r.oidnQuality)),this.denoisingManager?.upscaler?.abort(),t.canvasWidth&&t.canvasHeight&&this.setCanvasSize(t.canvasWidth,t.canvasHeight),this.renderer?.domElement&&(this.renderer.domElement.style.display=`block`),this.denoisingManager?.denoiser?.output&&(this.denoisingManager.denoiser.output.style.display=`block`),this.needsReset=!1,this.pauseRendering=!1,this.reset()}switchCamera(e){this.cameraManager.switchCamera(e,this.settings.get(`focusDistance`),()=>this.onResize(),()=>this.reset())}getCameraNames(){return this.cameraManager.getCameraNames()}addLight(e){let t=this.lightManager.addLight(e);return this.reset(),t}removeLight(e){let t=this.lightManager.removeLight(e);return t&&this.reset(),t}clearLights(){this.lightManager.clearLights(),this.reset()}getLights(){return this.lightManager.getLights()}updateLights(){this.lightManager.updateLights()}setShowLightHelper(e){this.lightManager.setShowLightHelper(e)}setDenoiserStrategy(e,t){this.denoisingManager.setDenoiserStrategy(e,t),this.reset()}setASVGFEnabled(e,t){this.denoisingManager.setASVGFEnabled(e,t),this.reset()}applyASVGFPreset(e){this.denoisingManager.applyASVGFPreset(e),this.reset()}setAutoExposureEnabled(e){this.denoisingManager.setAutoExposureEnabled(e,this.settings.get(`exposure`)),this.reset()}setAdaptiveSamplingEnabled(e){this.settings.set(`useAdaptiveSampling`,e),this.denoisingManager.setAdaptiveSamplingEnabled(e)}selectObject(e){let t=this.overlayManager?.getHelper(`outline`);t&&t.setSelectedObjects(e?[e]:[]),this._interactionManager&&(this._interactionManager.selectedObject=e||null),this._transformManager&&(e?this._transformManager.attach(e):this._transformManager.detach()),this.dispatchEvent({type:R.OBJECT_SELECTED,object:e||null})}toggleFocusMode(){if(!this._interactionManager)return!1;let e=this._interactionManager.toggleFocusMode();return this._controls&&(this._controls.enabled=!e),e}toggleSelectMode(){return this._interactionManager?this._interactionManager.toggleSelectMode():!1}disableSelectMode(){this._interactionManager?.disableSelectMode(),this._transformManager?.detach()}setTransformMode(e){this._transformManager?.setMode(e),this.dispatchEvent({type:R.TRANSFORM_MODE_CHANGED,mode:e})}setTransformSpace(e){this._transformManager?.setSpace(e)}get transformManager(){return this._transformManager}refreshFrame(){this._needsDisplayRefresh=!0,this.wake()}getEnvParams(){return this.stages.pathTracer?.environment?.envParams??null}getEnvironmentTexture(){return this.stages.pathTracer?.environment?.environmentTexture??null}getEnvironmentCDF(){return null}async generateProceduralSkyTexture(){return this.stages.pathTracer?.environment.generateProceduralSkyTexture()}async generateGradientTexture(){return this.stages.pathTracer?.environment.generateGradientTexture()}async generateSolidColorTexture(){return this.stages.pathTracer?.environment.generateSolidColorTexture()}async setEnvironmentMap(e){if(!this.stages.pathTracer){console.warn(`PathTracerApp: PathTracer not initialized`);return}await this.stages.pathTracer.environment.setEnvironmentMap(e),this.reset()}markEnvironmentNeedsUpdate(){let e=this.stages.pathTracer?.environment?.environmentTexture;e&&(e.needsUpdate=!0)}async setEnvironmentMode(e){let t=this._environmentMode||`hdri`;this._environmentMode=e,e!==`hdri`&&t===`hdri`&&(this._previousHDRI=this.getEnvironmentTexture(),this._previousCDF=this.getEnvironmentCDF()),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._previousCDF=null);let n=this.getEnvParams();n&&(n.mode=e),this.markEnvironmentNeedsUpdate(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset()}isComplete(){return this.stages.pathTracer?.isComplete??!1}getFrameCount(){return this.stages.pathTracer?.frameCount||0}get camera(){return this.cameraManager?.camera??this._camera}get controls(){return this.cameraManager?.controls??this._controls}getSceneStatistics(){try{return this._sdf?.getStatistics?.()??null}catch{return null}}getOutputCanvas(){if(!this.renderer?.domElement)return null;let e=this.denoisingManager?.denoiser,t=this.denoisingManager?.upscaler;return(e?.enabled||t?.enabled)&&this.denoiserCanvas&&this.stages.pathTracer?.isComplete?this.denoiserCanvas:(this.stages.display&&this.pipeline?.context&&this.stages.display.render(this.pipeline.context),this.renderer.domElement)}focusOnPoint(e){!e||!this._controls||(this._controls.target.copy(e),this._controls.update(),this.reset())}dispatchInteractionEvent(e){this._interactionManager?.dispatchEvent(e)}onInteractionEvent(e,t){return this._interactionManager?.addEventListener(e,t),()=>this._interactionManager?.removeEventListener(e,t)}takeScreenshot(){let e=this.getOutputCanvas();if(e)try{let t=e.toDataURL(`image/png`),n=document.createElement(`a`);n.href=t,n.download=`screenshot.png`,n.click()}catch(e){console.error(`PathTracerApp: Screenshot failed:`,e)}}setPathTracerEnabled(e){this.pathTracerEnabled=e}setAccumulationEnabled(e){this.stages.pathTracer?.setAccumulationEnabled(e)}setRenderMode(e){this.stages.pathTracer?.setUniform(`renderMode`,parseInt(e))}setTileCount(e){this.stages.pathTracer?.tileManager?.setTileCount(e)}setInteractionModeEnabled(e){this.stages.pathTracer?.setInteractionModeEnabled(e)}setAdaptiveSamplingParameters(e){e.min!==void 0&&this.stages.pathTracer?.setAdaptiveSamplingMin(e.min),e.adaptiveSamplingMax!==void 0&&this.settings.set(`adaptiveSamplingMax`,e.adaptiveSamplingMax),this.stages.adaptiveSampling?.setAdaptiveSamplingParameters(e)}updateMaterialProperty(e,t,n){if(this.stages.pathTracer?.materialData.updateMaterialProperty(e,t,n),[`emissive`,`emissiveIntensity`,`visible`].includes(t)&&this._sdf?.emissiveTriangleBuilder&&this.stages.pathTracer?.enableEmissiveTriangleSampling?.value){let r=this._sdf.materials[e];if(r&&(t===`emissive`?r.emissive=n:t===`emissiveIntensity`?r.emissiveIntensity=n:t===`visible`&&(r.visible=n),this._sdf.emissiveTriangleBuilder.updateMaterialEmissive(e,r,this._sdf.triangleData,this._sdf.materials,this._sdf.triangleCount))){let e=this._sdf.emissiveTriangleBuilder.createEmissiveRawData();this.stages.pathTracer.setEmissiveTriangleData(e,this._sdf.emissiveTriangleBuilder.emissiveCount,this._sdf.emissiveTriangleBuilder.totalEmissivePower)}}this.reset()}updateTextureTransform(e,t,n){this.stages.pathTracer?.materialData.updateTextureTransform(e,t,n),this.reset()}refreshMaterial(){this.reset()}updateMaterial(e,t){this.stages.pathTracer?.materialData.updateMaterial(e,t)}async rebuildMaterials(e){await this.stages.pathTracer?.rebuildMaterials(e||this.meshScene)}updateASVGFParameters(e){this.stages.asvgf?.updateParameters(e)}toggleASVGFHeatmap(e){this.stages.asvgf?.toggleHeatmap?.(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))}updateSSRCParameters(e){this.stages.ssrc?.updateParameters(e)}updateEdgeAwareUniforms(e){this.stages.edgeFilter?.updateUniforms(e)}updateAutoExposureParameters(e){this.stages.autoExposure?.updateParameters(e)}updateAdaptiveSamplingParameters(e){this.stages.adaptiveSampling?.setAdaptiveSamplingParameters(e)}setAdaptiveSamplingVarianceThreshold(e){this.stages.adaptiveSampling?.setVarianceThreshold(e)}setAdaptiveSamplingMaterialBias(e){this.stages.adaptiveSampling?.setMaterialBias(e)}setAdaptiveSamplingEdgeBias(e){this.stages.adaptiveSampling?.setEdgeBias(e)}setAdaptiveSamplingConvergenceSpeed(e){this.stages.adaptiveSampling?.setConvergenceSpeed(e)}toggleAdaptiveSamplingHelper(e){this.stages.adaptiveSampling?.toggleHelper(e)}setTileHighlightEnabled(e){this.setTileHelperEnabled(e)}setOIDNEnabled(e){let t=this.denoisingManager?.denoiser;t&&(t.enabled=e)}updateOIDNQuality(e){this.denoisingManager?.denoiser?.updateQuality(e)}setOIDNTileHelper(e){this.setTileHelperEnabled(e)}setTileHelperEnabled(e){let t=this.overlayManager?.getHelper(`tiles`);t&&(t.enabled=e,e||t.hide())}setUpscalerEnabled(e){let t=this.denoisingManager?.upscaler;t&&(t.enabled=e)}setUpscalerScaleFactor(e){this.denoisingManager?.upscaler?.setScaleFactor(e)}setUpscalerQuality(e){this.denoisingManager?.upscaler?.setQuality(e)}_createStages(){let e=this.settings.get(`adaptiveSamplingMax`),t=this.settings.get(`useAdaptiveSampling`);this.stages.pathTracer=new Pa(this.renderer,this.scene,this._camera),this.stages.normalDepth=new Fa(this.renderer,{pathTracer:this.stages.pathTracer}),this.stages.motionVector=new Ia(this.renderer,this._camera,{pathTracer:this.stages.pathTracer}),this.stages.ssrc=new Za(this.renderer,{enabled:!1}),this.stages.asvgf=new Ra(this.renderer,{enabled:!1}),this.stages.variance=new Ba(this.renderer,{enabled:!1}),this.stages.bilateralFilter=new Ha(this.renderer,{enabled:!1}),this.stages.adaptiveSampling=new Ga(this.renderer,{adaptiveSamplingMax:e,enabled:t}),this.stages.edgeFilter=new Ka(this.renderer,{enabled:!1}),this.stages.autoExposure=new Ja(this.renderer,{enabled:V.autoExposure??!1}),this.stages.display=new Qa(this.renderer,{exposure:V.autoExposure?1:this.settings.get(`exposure`)??1,saturation:this.settings.get(`saturation`)??V.saturation})}_setupDenoisingManager(){this.denoisingManager=new jo({renderer:this.renderer,denoiserCanvas:this.denoiserCanvas,scene:this.scene,camera:this._camera,stages:{pathTracer:this.stages.pathTracer,asvgf:this.stages.asvgf,variance:this.stages.variance,bilateralFilter:this.stages.bilateralFilter,adaptiveSampling:this.stages.adaptiveSampling,edgeFilter:this.stages.edgeFilter,ssrc:this.stages.ssrc,autoExposure:this.stages.autoExposure,display:this.stages.display},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()}_buildSettingsHandlers(){return{handleTransparentBackground:e=>{this.stages.pathTracer?.setUniform(`transparentBackground`,e),this.stages.display?.setTransparentBackground(e)},handleExposure:e=>{this.stages.autoExposure?.enabled||this.stages.display?.setExposure(e)},handleSaturation:e=>{this.stages.display?.setSaturation(e)},handleRenderLimitMode:e=>{this.stages.pathTracer?.setRenderLimitMode&&this.stages.pathTracer.setRenderLimitMode(e)},handleMaxSamples:e=>{this.stages.pathTracer?.setUniform(`maxSamples`,e),this.stages.pathTracer?.updateCompletionThreshold(),this._reconcileCompletion()},handleRenderTimeLimit:()=>{this._reconcileCompletion()},handleRenderMode:e=>{this.stages.pathTracer?.setUniform(`renderMode`,parseInt(e))},handleEnvironmentRotation:e=>{this.stages.pathTracer?.environment.setEnvironmentRotation(e)}}}_reconcileCompletion(){let e=this.stages.pathTracer;if(!e)return;let t=this._isRenderLimitReached();if(t&&!e.isComplete)e.isComplete=!0;else if(!t&&e.isComplete){e.isComplete=!1,this._renderCompleteDispatched=!1,this.lastResetTime=performance.now()-this.timeElapsed*1e3,this.canvas.style.opacity=`1`;let t=this.denoisingManager?.denoiser?.output;t&&(t.style.display=`none`),this.dispatchEvent({type:R.RENDER_RESET}),this.wake()}}_isRenderLimitReached(){let e=this.stages.pathTracer;if(!e)return!1;if(this.settings.get(`renderLimitMode`)===`time`){let e=this.settings.get(`renderTimeLimit`);return e>0&&this.timeElapsed>=e}return e.frameCount>=e.completionThreshold}_setupFloorPlane(){this._floorPlane=new n.Mesh(new n.CircleGeometry,new n.MeshPhysicalMaterial({transparent:!1,color:3158064,roughness:1,metalness:0,opacity:0,transmission:0})),this._floorPlane.name=`Ground`,this._floorPlane.visible=!1,this.meshScene.add(this._floorPlane)}_initStats(){this._stats=new o.default({horizontal:!0,trackGPU:!0}),this._stats.dom.style.position=`absolute`,this._stats.dom.style.top=`unset`,this._stats.dom.style.bottom=`48px`,this._stats.init(this.renderer),(this._statsContainer||this.canvas.parentElement||document.body).appendChild(this._stats.dom);let e=`#ffffff`,t=`#1e293b`,n=this._stats.fpsPanel.context.createLinearGradient(0,this._stats.fpsPanel.GRAPH_Y,0,this._stats.fpsPanel.GRAPH_Y+this._stats.fpsPanel.GRAPH_HEIGHT);n.addColorStop(0,e),this._stats.fpsPanel.fg=this._stats.msPanel.fg=e,this._stats.fpsPanel.bg=this._stats.msPanel.bg=t,this._stats.fpsPanel.gradient=this._stats.msPanel.gradient=n,this._stats.gpuPanel&&(this._stats.gpuPanel.fg=e,this._stats.gpuPanel.bg=t,this._stats.gpuPanel.gradient=n),this._stats.dom.style.display=``}_setupInteractionListeners(){this._interactionManager&&(this._interactionManager.addEventListener(`objectSelected`,e=>{this.selectObject(e.object),this.refreshFrame(),this.dispatchEvent({type:`objectSelected`,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`objectDeselected`,e=>{this.selectObject(null),this.refreshFrame(),this.dispatchEvent({type:`objectDeselected`,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`selectModeChanged`,e=>{this.dispatchEvent({type:R.SELECT_MODE_CHANGED,enabled:e.enabled})}),this._interactionManager.addEventListener(`objectDoubleClicked`,e=>{this.selectObject(e.object),this.refreshFrame(),this.dispatchEvent({type:R.OBJECT_DOUBLE_CLICKED,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`focusChanged`,e=>{this.settings.set(`focusDistance`,e.worldDistance),this.dispatchEvent({type:`focusChanged`,distance:e.distance})}),this._interactionManager.addEventListener(`focusModeChanged`,e=>{!e.enabled&&this._controls&&(this._controls.enabled=!0)}),this._interactionManager.addEventListener(`afPointPlaced`,e=>{this.cameraManager.setAFScreenPoint(e.point.x,e.point.y),this._controls&&(this._controls.enabled=!0),this.dispatchEvent({type:R.AF_POINT_PLACED,point:e.point})}))}_setupAutoExposureListener(){this.stages.autoExposure&&this.stages.autoExposure.on(`autoexposure:updated`,e=>{this.dispatchEvent({type:R.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 Mo(this.renderer,this._camera),this.overlayManager.setHelperScene(this._sceneHelpers);let e=new Fo;this.overlayManager.register(`tiles`,e),e.setRenderSize(this._lastRenderWidth||1,this._lastRenderHeight||1),this.addEventListener(`resolution_changed`,t=>{e.setRenderSize(t.width,t.height)}),this.pipeline.eventBus.on(`tile:changed`,t=>{t.renderMode===1&&t.tileBounds&&(e.setActiveTile(t.tileBounds),e.show())}),this.pipeline.eventBus.on(`pipeline:reset`,()=>e.hide()),this.addEventListener(R.RENDER_COMPLETE,()=>e.hide()),this._setupDenoiserTileHelper(e);let t=new Io(this.renderer,this.meshScene,this._camera);this.overlayManager.register(`outline`,t)}_setupDenoiserTileHelper(e){let t=[this.denoisingManager?.denoiser,this.denoisingManager?.upscaler];for(let n of t)n&&(n.addEventListener(`tileProgress`,t=>{t.tile&&(e.setRenderSize(t.imageWidth,t.imageHeight),e.setActiveTile(t.tile),e.show(),this.overlayManager?.refreshHUD())}),n.addEventListener(`end`,()=>{e.hide(),this.overlayManager?.refreshHUD()}))}_syncControlsAfterLoad(){this._controls.saveState(),this._controls.update()}_forwardEvents(e,t){if(e)for(let n of t)e.addEventListener(n,e=>this.dispatchEvent(e))}},Ro=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=G.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(`final-render`),l.settings.setMany({maxSamples:i},{silent:!0}),l.stages.pathTracer?.updateCompletionThreshold?.(),l._controls&&(l._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.getOutputCanvas();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:R.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:R.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._camera.updateMatrixWorld(),e.pipeline.render(),t.frameCount%4==0&&(ye({samples:be(t)}),await new Promise(e=>setTimeout(e,0)))}_waitForDenoise(e){return new Promise(t=>{let n,r=()=>{e.removeEventListener(R.DENOISING_END,i),clearTimeout(n)},i=()=>{r(),t()};n=setTimeout(()=>{console.warn(`VideoRenderManager: Denoise timed out, skipping`),r(),t()},3e4),e.addEventListener(R.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`),samplesPerPixel:e.settings.get(`samplesPerPixel`),transmissiveBounces:e.settings.get(`transmissiveBounces`),renderMode:e.stages.pathTracer?.renderMode?.value,controlsEnabled:e._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,samplesPerPixel:e.samplesPerPixel,transmissiveBounces:e.transmissiveBounces},{silent:!0}),t.stages.pathTracer&&e.renderMode!==void 0&&t.setRenderMode(e.renderMode),t.stages.pathTracer?.updateCompletionThreshold?.(),t._controls&&(t._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=Pe,e.ASVGF_QUALITY_PRESETS=ke,e.AUTO_FOCUS_MODES=Ne,e.AnimationManager=No,e.BVH_LEAF_MARKERS=Fe,e.CAMERA_PRESETS=Me,e.CAMERA_RANGES=Ae,e.CameraManager=co,e.DEFAULT_TEXTURE_MATRIX=W,e.DenoisingManager=jo,e.ENGINE_DEFAULTS=V,e.EngineEvents=R,e.FINAL_RENDER_CONFIG=G,e.LightManager=lo,e.MEMORY_CONSTANTS=Le,e.OverlayManager=Mo,e.PREVIEW_RENDER_CONFIG=Ie,e.PathTracerApp=Lo,e.PipelineContext=$a,e.RenderPipeline=to,e.RenderSettings=so,e.RenderStage=L,e.SKY_PRESETS=je,e.StageExecutionMode=I,e.TEXTURE_CONSTANTS=U,e.TRIANGLE_DATA_LAYOUT=H,e.TransformManager=Po,e.VideoRenderManager=Ro});
696
+ `),Ja=class extends L{constructor(e,n={}){super(`AutoExposure`,{...n,executionMode:I.ALWAYS}),this.renderer=e,this.REDUCTION_SIZE=64,this.keyValueU=(0,s.uniform)(n.keyValue??.18),this.minExposureU=(0,s.uniform)(n.minExposure??.1),this.maxExposureU=(0,s.uniform)(n.maxExposure??20),this.adaptSpeedBrightU=(0,s.uniform)(n.adaptSpeedBright??3),this.adaptSpeedDarkU=(0,s.uniform)(n.adaptSpeedDark??.5),this.epsilonU=(0,s.uniform)(n.epsilon??1e-4),this.deltaTimeU=(0,s.uniform)(1/60),this.isFirstFrameU=(0,s.uniform)(1),this.previousExposureU=(0,s.uniform)(n.initialExposure??1),this.inputResW=(0,s.uniform)(1),this.inputResH=(0,s.uniform)(1),this._inputTexNode=new t.TextureNode,this._reductionReadTexNode=new t.TextureNode,this.currentExposure=n.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:n.FloatType,format:n.RGBAFormat,minFilter:n.NearestFilter,magFilter:n.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=n.FloatType,this._downsampleStorageTex.format=n.RGBAFormat,this._downsampleStorageTex.minFilter=n.NearestFilter,this._downsampleStorageTex.magFilter=n.NearestFilter,this._reductionStorageTex=new t.StorageTexture(1,1),this._reductionStorageTex.type=n.FloatType,this._reductionStorageTex.format=n.RGBAFormat,this._reductionStorageTex.minFilter=n.NearestFilter,this._reductionStorageTex.magFilter=n.NearestFilter,this._reductionReadTarget=new t.RenderTarget(1,1,e),this._adaptationStorageTex=new t.StorageTexture(1,1),this._adaptationStorageTex.type=n.FloatType,this._adaptationStorageTex.format=n.RGBAFormat,this._adaptationStorageTex.minFilter=n.NearestFilter,this._adaptationStorageTex.magFilter=n.NearestFilter,this._adaptationTarget=new t.RenderTarget(1,1,e)}_buildCompute(){this._buildDownsampleCompute(),this._buildReductionCompute(),this._buildAdaptationCompute()}_buildDownsampleCompute(){let e=this._inputTexNode,t=this._downsampleStorageTex,n=this.epsilonU,r=this.inputResW,i=this.inputResH;this._downsampleComputeNode=(0,s.Fn)(()=>{let a=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),o=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y)),c=r.div((0,s.float)(64)),l=i.div((0,s.float)(64)),u=(0,s.float)(a).mul(c),d=(0,s.float)(o).mul(l),f=(0,s.float)(0).toVar(),p=(0,s.float)(0).toVar();for(let t=0;t<4;t++)for(let r=0;r<4;r++){let i=zt((0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(u.add((0,s.float)((r+.5)/4).mul(c))),(0,s.int)(d.add((0,s.float)((t+.5)/4).mul(l))))).xyz);(0,s.If)(i.greaterThan(n),()=>{f.addAssign(i.add(n).log()),p.addAssign(1)})}(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(a),(0,s.uint)(o)),(0,s.vec4)(f,p,0,1)).toWriteOnly()})().compute([64/8,64/8,1],[8,8,1])}_buildReductionCompute(){let e=this._downsampleTarget.texture,t=this._reductionStorageTex,n=(0,s.workgroupArray)(`float`,256),r=(0,s.workgroupArray)(`float`,256);this._reductionComputeNode=(0,s.Fn)(()=>{let i=s.localId.x,a=(0,s.float)(0).toVar(),o=(0,s.float)(0).toVar();for(let t=0;t<16;t++){let n=i.mul(16).add(t),r=n.mod(64),c=n.div(64),l=(0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(r),(0,s.int)(c)));a.addAssign(l.x),o.addAssign(l.y)}n.element(i).assign(a),r.element(i).assign(o);for(let e=256/2;e>=1;e=Math.floor(e/2))(0,s.workgroupBarrier)(),(0,s.If)(i.lessThan((0,s.uint)(e)),()=>{n.element(i).addAssign(n.element(i.add((0,s.uint)(e)))),r.element(i).addAssign(r.element(i.add((0,s.uint)(e))))});(0,s.workgroupBarrier)(),(0,s.If)(i.equal((0,s.uint)(0)),()=>{let e=n.element((0,s.uint)(0)),i=r.element((0,s.uint)(0)),a=(0,s.max)(i,(0,s.float)(1)),o=e.div(a),c=o.exp();(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(0),(0,s.uint)(0)),(0,s.vec4)(c,i,o,1)).toWriteOnly()})})().compute(1,[256,1,1])}_buildAdaptationCompute(){let e=this._reductionReadTexNode,t=this._adaptationStorageTex,n=this.keyValueU,r=this.minExposureU,i=this.maxExposureU,a=this.adaptSpeedBrightU,o=this.adaptSpeedDarkU,c=this.deltaTimeU,l=this.isFirstFrameU,u=this.previousExposureU;this._adaptationComputeNode=(0,s.Fn)(()=>{let d=(0,s.textureLoad)(e,(0,s.ivec2)((0,s.int)(0),(0,s.int)(0))).x,f=qa(d,u,n,r,i,a,o,c,l);(0,s.textureStore)(t,(0,s.uvec2)((0,s.uint)(0),(0,s.uint)(0)),f).toWriteOnly()})().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&&(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))})}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?1:0,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._reductionComputeNode),this.renderer.copyTextureToTexture(this._reductionStorageTex,this._reductionReadTarget.texture),this._reductionReadTexNode.value=this._reductionReadTarget.texture,this.renderer.compute(this._adaptationComputeNode),this.renderer.copyTextureToTexture(this._adaptationStorageTex,this._adaptationTarget.texture),!this._pendingReadback){this._pendingReadback=!0;let e=this._readbackGeneration;this.renderer.readRenderTargetPixelsAsync(this._adaptationTarget,0,0,1,1).then(t=>{this._pendingReadback=!1,e===this._readbackGeneration&&this._applyReadback(t)}).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)}dispose(){this._downsampleComputeNode?.dispose(),this._reductionComputeNode?.dispose(),this._adaptationComputeNode?.dispose(),this._downsampleTarget?.dispose(),this._downsampleStorageTex?.dispose(),this._reductionStorageTex?.dispose(),this._reductionReadTarget?.dispose(),this._adaptationStorageTex?.dispose(),this._adaptationTarget?.dispose()}};function Ya({colorTexNode:e,ndTexNode:t,motionTexNode:n,readCacheTexNode:r,readPrevNDTexNode:i,writeCacheTex:a,writePrevNDTex:o,resW:c,resH:l,temporalAlpha:u,phiNormal:d,phiDepth:f,maxHistory:p,framesSinceReset:m}){return(0,s.Fn)(()=>{let h=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),g=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y));(0,s.If)(h.lessThan((0,s.int)(c)).and(g.lessThan((0,s.int)(l))),()=>{let _=(0,s.ivec2)(h,g),v=(0,s.textureLoad)(e,_).xyz,y=(0,s.textureLoad)(t,_),b=(0,s.vec4)(v,1).toVar();(0,s.If)(m.greaterThan((0,s.int)(0)),()=>{let e=(0,s.textureLoad)(n,_),t=e.w.greaterThan(.5),a=(0,s.float)(h).sub(e.x.mul(c)),o=(0,s.float)(g).sub(e.y.mul(l)),m=a.greaterThanEqual(0).and(a.lessThan((0,s.float)(c))).and(o.greaterThanEqual(0)).and(o.lessThan((0,s.float)(l)));(0,s.If)(t.and(m),()=>{let e=(0,s.ivec2)((0,s.int)(a).clamp((0,s.int)(0),(0,s.int)(c).sub(1)),(0,s.int)(o).clamp((0,s.int)(0),(0,s.int)(l).sub(1))),t=y.xyz.mul(2).sub(1),n=(0,s.textureLoad)(i,e),m=Xt(t,n.xyz.mul(2).sub(1),y.w,n.w,d,f);(0,s.If)(m.greaterThan(.01),()=>{let t=(0,s.textureLoad)(r,e),n=t.xyz,i=t.w,a=(0,s.mix)(n,v,(0,s.min)((0,s.max)(u,(0,s.float)(1).div(i.add(1))).div((0,s.max)(m,(0,s.float)(.1))),1)),o=(0,s.min)(i.add(1),p);b.assign((0,s.vec4)(a,o))}).Else(()=>{b.assign((0,s.vec4)(v,1))})}).Else(()=>{b.assign((0,s.vec4)(v,1))})}),(0,s.textureStore)(a,(0,s.uvec2)(h,g),b).toWriteOnly(),(0,s.textureStore)(o,(0,s.uvec2)(h,g),y).toWriteOnly()})})}function Xa({colorTexNode:e,ndTexNode:t,readCacheTexNode:n,outputTex:r,resW:i,resH:a,spatialRadius:o,spatialWeight:c,phiNormal:l,phiDepth:u}){let d=[[1,0],[-1,0],[0,1],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];return(0,s.Fn)(()=>{let f=(0,s.int)(s.workgroupId.x).mul(8).add((0,s.int)(s.localId.x)),p=(0,s.int)(s.workgroupId.y).mul(8).add((0,s.int)(s.localId.y));(0,s.If)(f.lessThan((0,s.int)(i)).and(p.lessThan((0,s.int)(a))),()=>{let m=(0,s.ivec2)(f,p),h=(0,s.textureLoad)(n,m),g=h.xyz,_=h.w,v=(0,s.textureLoad)(t,m),y=v.xyz.mul(2).sub(1),b=(0,s.float)(1).sub(_.div(16).clamp(0,1)),x=c.mul(b),S=(0,s.vec3)(g).toVar(),C=(0,s.float)(1).toVar();for(let e=0;e<d.length;e++){let[r,c]=d[e],m=(0,s.ivec2)(f.add((0,s.int)(o).mul(r)).clamp((0,s.int)(0),(0,s.int)(i).sub(1)),p.add((0,s.int)(o).mul(c)).clamp((0,s.int)(0),(0,s.int)(a).sub(1))),h=(0,s.textureLoad)(n,m).xyz,g=(0,s.textureLoad)(t,m),_=Xt(y,g.xyz.mul(2).sub(1),v.w,g.w,l,u);S.addAssign(h.mul(_)),C.addAssign(_)}let w=(0,s.mix)(g,S.div((0,s.max)(C,1e-4)),x),T=(0,s.textureLoad)(e,m).w;(0,s.textureStore)(r,(0,s.uvec2)(f,p),(0,s.vec4)(w,T)).toWriteOnly()})})}var Za=class extends L{constructor(e,r={}){super(`SSRC`,{...r,executionMode:I.PER_CYCLE}),this.renderer=e,this.resW=(0,s.uniform)(1),this.resH=(0,s.uniform)(1),this.temporalAlpha=(0,s.uniform)(r.temporalAlpha??.1),this.phiNormal=(0,s.uniform)(r.phiNormal??128),this.phiDepth=(0,s.uniform)(r.phiDepth??.5),this.maxHistory=(0,s.uniform)(r.maxHistory??128),this.spatialRadius=(0,s.uniform)(r.spatialRadius??4,`int`),this.spatialWeight=(0,s.uniform)(r.spatialWeight??.4),this._framesSinceReset=(0,s.uniform)(0,`int`),this._colorTexNode=new t.TextureNode,this._ndTexNode=new t.TextureNode,this._motionTexNode=new t.TextureNode,this._readCacheTexNode=new t.TextureNode,this._readPrevNDTexNode=new t.TextureNode,this._readPass1CacheTexNode=new t.TextureNode,this._cacheTexA=this._createStorageTex(1,1,n.NearestFilter),this._cacheTexB=this._createStorageTex(1,1,n.NearestFilter),this._prevNDTexA=this._createStorageTex(1,1,n.NearestFilter),this._prevNDTexB=this._createStorageTex(1,1,n.NearestFilter),this._outputTex=this._createStorageTex(1,1,n.LinearFilter),this._currentPingPong=0,this._dispatchX=1,this._dispatchY=1,this._buildComputeNodes()}setupEventListeners(){this.on(`pipeline:reset`,()=>this._resetCache()),this.on(`camera:moved`,()=>this._resetCache())}render(e){if(!this.enabled){e.removeTexture(`ssrc:output`);return}let t=e.getTexture(`pathtracer:color`);if(t?.image){let{width:e,height:n}=t.image;(e!==this._cacheTexA.image.width||n!==this._cacheTexA.image.height)&&this.setSize(e,n)}let n=e.getTexture(`pathtracer:normalDepth`);if(!n||!t)return;this._colorTexNode.value=t,this._ndTexNode.value=n;let r=e.getTexture(`motionVector:screenSpace`);r&&(this._motionTexNode.value=r);let[i,a,o]=this._currentPingPong===0?[this._cacheTexB,this._cacheTexA,this._prevNDTexB]:[this._cacheTexA,this._cacheTexB,this._prevNDTexA];this._readCacheTexNode.value=i,this._readPrevNDTexNode.value=o,this.renderer.compute(this._currentPingPong===0?this._pass1NodeA:this._pass1NodeB),this._readPass1CacheTexNode.value=a,this.renderer.compute(this._pass2Node),this._framesSinceReset.value=Math.min(this._framesSinceReset.value+1,9999),e.setTexture(`ssrc:output`,this._outputTex),this._currentPingPong=1-this._currentPingPong}reset(){this._resetCache()}setSize(e,t){if(e<1||t<1)return;this._cacheTexA.setSize(e,t),this._cacheTexB.setSize(e,t),this._prevNDTexA.setSize(e,t),this._prevNDTexB.setSize(e,t),this._outputTex.setSize(e,t),this.resW.value=e,this.resH.value=t,this._dispatchX=Math.ceil(e/8),this._dispatchY=Math.ceil(t/8);let n=[this._dispatchX,this._dispatchY,1];this._pass1NodeA&&this._pass1NodeA.setCount(n),this._pass1NodeB&&this._pass1NodeB.setCount(n),this._pass2Node&&this._pass2Node.setCount(n),this._resetCache()}dispose(){this._pass1NodeA?.dispose(),this._pass1NodeB?.dispose(),this._pass2Node?.dispose(),this._cacheTexA.dispose(),this._cacheTexB.dispose(),this._prevNDTexA.dispose(),this._prevNDTexB.dispose(),this._outputTex.dispose()}updateParameters(e){e.temporalAlpha!==void 0&&(this.temporalAlpha.value=e.temporalAlpha),e.phiNormal!==void 0&&(this.phiNormal.value=e.phiNormal),e.phiDepth!==void 0&&(this.phiDepth.value=e.phiDepth),e.maxHistory!==void 0&&(this.maxHistory.value=e.maxHistory),e.spatialRadius!==void 0&&(this.spatialRadius.value=e.spatialRadius),e.spatialWeight!==void 0&&(this.spatialWeight.value=e.spatialWeight)}_createStorageTex(e,r,i){let a=new t.StorageTexture(e,r);return a.type=n.HalfFloatType,a.format=n.RGBAFormat,a.minFilter=i,a.magFilter=i,a}_resetCache(){this._currentPingPong=0,this._framesSinceReset.value=0}_buildComputeNodes(){let e={colorTexNode:this._colorTexNode,ndTexNode:this._ndTexNode,motionTexNode:this._motionTexNode,readCacheTexNode:this._readCacheTexNode,readPrevNDTexNode:this._readPrevNDTexNode,resW:this.resW,resH:this.resH,temporalAlpha:this.temporalAlpha,phiNormal:this.phiNormal,phiDepth:this.phiDepth,maxHistory:this.maxHistory},t=Ya({...e,writeCacheTex:this._cacheTexA,writePrevNDTex:this._prevNDTexA,framesSinceReset:this._framesSinceReset}),n=Ya({...e,writeCacheTex:this._cacheTexB,writePrevNDTex:this._prevNDTexB,framesSinceReset:this._framesSinceReset}),r=[this._dispatchX,this._dispatchY,1],i=[8,8,1];this._pass1NodeA=t().compute(r,i),this._pass1NodeB=n().compute(r,i),this._pass2Node=Xa({colorTexNode:this._colorTexNode,ndTexNode:this._ndTexNode,readCacheTexNode:this._readPass1CacheTexNode,outputTex:this._outputTex,resW:this.resW,resH:this.resH,spatialRadius:this.spatialRadius,spatialWeight:this.spatialWeight,phiNormal:this.phiNormal,phiDepth:this.phiDepth})().compute(r,i)}},Qa=class extends L{constructor(e,r={}){super(`Display`,{...r,executionMode:I.ALWAYS}),this.renderer=e,this.exposure=(0,s.uniform)(r.exposure??1),this.saturation=(0,s.uniform)(r.saturation??1),this._transparentBackground=(0,s.uniform)(0,`int`),this._displayTexNode=new t.TextureNode;let i=this._displayTexNode.sample((0,s.uv)()),a=i.xyz.mul(this.exposure),o=(0,s.mix)((0,s.vec3)((0,s.dot)(a,Ft)),a,this.saturation),c=(0,s.select)(this._transparentBackground,i.w,1);this.displayMaterial=new t.MeshBasicNodeMaterial,this.displayMaterial.colorNode=(0,s.vec4)(o,c),this.displayMaterial.blending=n.NoBlending,this.displayMaterial.toneMapped=!0,this.displayQuad=new t.QuadMesh(this.displayMaterial)}_resolveDisplayTexture(e){return e.getTexture(`bloom:output`)||e.getTexture(`edgeFiltering:output`)||e.getTexture(`asvgf:output`)||e.getTexture(`ssrc:output`)||e.getTexture(`pathtracer:color`)}render(e){if(!this.enabled)return;let t=this._resolveDisplayTexture(e);t&&(this._displayTexNode.value=t,this.renderer.setRenderTarget(null),this.displayQuad.render(this.renderer))}setExposure(e){this.exposure.value=e}setSaturation(e){this.saturation.value=e}setTransparentBackground(e){this._transparentBackground.value=e?1:0}dispose(){this.displayMaterial?.dispose()}},$a=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,enableAdaptiveSampling:!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={}}},eo=class extends n.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):[]}},to=class{constructor(e,t,n){this.renderer=e,this.width=t,this.height=n,this.stages=[],this.context=new $a,this.eventBus=new eo,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(),!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}`),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()}},no=class extends n.EventDispatcher{constructor({scene:e,camera:t,canvas:r,assetLoader:i,pathTracer:a,floorPlane:o}){super(),this.scene=e,this.camera=t,this.canvas=r,this.assetLoader=i,this.pathTracer=a,this.floorPlane=o,this.raycaster=new n.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)}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.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 n.Mesh(new n.SphereGeometry(this.assetLoader.getSceneScale()*.02,16,16),new n.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)}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}},ro={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`}},io=class extends n.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.camera=t,this.controls=n,this.targetModel=null,this.floorPlane=null,this.sceneScale=1,this.loaderCache={},this.uploadedFileInfo=null,this.animations=[]}getFileFormat(e){return ro[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}`);z({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){try{this.dispatchEvent({type:`beforeEnvironmentLoad`,url:e});let t;if(e.startsWith(`blob:`))t=await this.loadEnvironmentFromBlob(e);else{let n=e.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 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(e,t){let r;return t===`hdr`||t===`exr`?r=await(t===`hdr`?this.loaderCache.hdr||(this.loaderCache.hdr=new l.HDRLoader().setDataType(n.FloatType)):this.loaderCache.exr||(this.loaderCache.exr=new d.EXRLoader().setDataType(n.FloatType))).loadAsync(e):(this.loaderCache.texture||(this.loaderCache.texture=new n.TextureLoader),r=await this.loaderCache.texture.loadAsync(e)),r.mapping=n.EquirectangularReflectionMapping,r.minFilter=n.LinearFilter,r.magFilter=n.LinearFilter,r}applyEnvironmentToScene(e){this.scene.background=e,this.scene.environment=e}async loadArchiveFromFile(e,t){try{let n=await this.readFileAsArrayBuffer(e),r=(0,m.unzipSync)(new Uint8Array(n));return await this.processObjMtlPairsInZip(r,t)||await this.findAndLoadModelFromZip(r,t)}catch(e){throw console.error(`Error loading ZIP archive:`,e),e}}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,t){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(ro[n]&&ro[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{z({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,m.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,r,i){if(e===`gltf`){let e=(0,m.strFromU8)(t);JSON.parse(e);let a=new n.LoadingManager,o=r.split(`/`).slice(0,-1).join(`/`);a.setURLModifier(e=>this.resolveZipResource(e,o,i));let s=await this.createGLTFLoader();return s.manager=a,await new Promise((t,n)=>{s.parse(e,``,e=>{this.targetModel&&B(this.targetModel),this.targetModel=e.scene,this.onModelLoad(this.targetModel).then(()=>t(e))},e=>n(e))})}else return await this.loadGLBFromArrayBuffer(t.buffer,r)}async handleObjFromZip(e,t,n){let r=(0,m.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.targetModel&&B(this.targetModel),this.targetModel=c,await this.onModelLoad(this.targetModel),c}async loadMtlFromZip(e,t,r){let i=t.split(`/`).slice(0,-1).join(`/`),a=[e,`${i}/${e}`,e.split(`/`).pop()];for(let e of a)if(r[e]){let{MTLLoader:t}=await import(`three/examples/jsm/loaders/MTLLoader.js`),a=(0,m.strFromU8)(r[e]),o=new n.LoadingManager;o.setURLModifier(e=>this.resolveZipResource(e,i,r));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,r,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 n.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,r,s));let d=this.prepareFixedMtlContent(t),f=new a(c).parse(d,u);f.preload();let p=new o(c);p.setMaterials(f);let h=(0,m.strFromU8)(e.content),g=p.parse(h);return this.targetModel&&B(this.targetModel),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,m.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(){if(this.loaderCache.gltf)return this.loaderCache.gltf;let e=new u.DRACOLoader;e.setDecoderConfig({type:`js`}),e.setDecoderPath(`https://www.gstatic.com/draco/v1/decoders/`);let t=new c.GLTFLoader;return t.setDRACOLoader(e),t.setMeshoptDecoder(p.MeshoptDecoder),this.loaderCache.gltf=t,t}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(e){try{let t=await this.createGLTFLoader();z({status:`Loading Model...`,progress:2});let n=await t.loadAsync(e);return z({status:`Processing Data...`,progress:10}),this.targetModel&&B(this.targetModel),this.targetModel=n.scene,this.animations=n.animations||[],await this.onModelLoad(this.targetModel),this.dispatchEvent({type:`load`,model:n.scene,filename:e.split(`/`).pop()}),n}catch(t){throw console.error(`Error loading model:`,t),this.dispatchEvent({type:`error`,message:t.message,filename:e}),t}}async loadGLBFromArrayBuffer(e,t=`model.glb`){try{let n=await this.createGLTFLoader();z({isLoading:!0,status:`Processing GLB Data...`,progress:5}),await new Promise(e=>setTimeout(e,0));let r=await n.parseAsync(e,``);return this.targetModel&&B(this.targetModel),this.targetModel=r.scene,this.animations=r.animations||[],z({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}}async loadFBXFromArrayBuffer(e,t=`model.fbx`){try{if(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=r,z({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(z({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 r=new n.Mesh(this.loaderCache.stl.parse(e),new n.MeshStandardMaterial);return r.name=t,this.targetModel&&B(this.targetModel),this.targetModel=r,z({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 STL:`,e),this.dispatchEvent({type:`error`,message:e.message,filename:t}),e}}async loadPLYFromArrayBuffer(e,t=`model.ply`){try{if(z({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 r=this.loaderCache.ply.parse(e),i;if(r.index!==null)i=new n.Mesh(r,new n.MeshStandardMaterial);else{let e=new n.PointsMaterial({size:.01});e.vertexColors=r.hasAttribute(`color`),i=new n.Points(r,e)}return i.name=t,this.targetModel&&B(this.targetModel),this.targetModel=i,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=r.scene,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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(z({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.targetModel&&B(this.targetModel),this.targetModel=n,z({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.targetModel&&B(this.targetModel),this.targetModel=e,z({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 Xi(`onModelLoad`);t.start(`Camera extraction`);let r=this.extractCamerasFromModel(e);t.end(`Camera extraction`),t.start(`Camera setup`);let i=new n.Box3().setFromObject(e),a=i.getCenter(new n.Vector3),o=i.getSize(new n.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 n.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:r,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 r=e.userData;if(e.isRectAreaLight&&!t.includes(e.uuid)&&(e.intensity*=100/4),e.name.startsWith(`RectAreaLightPlaceholder`)&&r.name&&r.type===`RectAreaLight`){let i=new n.RectAreaLight(new n.Color(...r.color),r.intensity*.1/4,r.width,r.height);i.position.z=-2,i.name=r.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,f.createMeshesFromMultiMaterialMesh)(e);e.parent&&(e.parent.add(t),e.parent.remove(e))}})}async setupPathTracing(e,t){this.sceneScale=t}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(ro))r.type===e&&(t[n]=r);return t}return ro}dispose(){for(let e in this.loaderCache){let t=this.loaderCache[e];t&&typeof t.dispose==`function`&&t.dispose()}this.loaderCache={},super.dispose(),this.targetModel&&=(B(this.targetModel),null),console.log(`AssetLoader resources disposed`)}removeAllEventListeners(){super.dispose()}},ao={maxBounces:{uniform:`maxBounces`,reset:!0},samplesPerPixel:{uniform:`samplesPerPixel`,reset:!0},transmissiveBounces:{uniform:`transmissiveBounces`,reset:!0},environmentIntensity:{uniform:`environmentIntensity`,reset:!0},backgroundIntensity:{uniform:`backgroundIntensity`,reset:!0},showBackground:{uniform:`showBackground`,reset:!0},enableEnvironment:{uniform:`enableEnvironment`,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},enableEmissiveTriangleSampling:{uniform:`enableEmissiveTriangleSampling`,reset:!0},emissiveBoost:{uniform:`emissiveBoost`,reset:!0},visMode:{uniform:`visMode`,reset:!0},debugVisScale:{uniform:`debugVisScale`,reset:!0},useAdaptiveSampling:{uniform:`useAdaptiveSampling`,reset:!0},adaptiveSamplingMax:{uniform:`adaptiveSamplingMax`,reset:!0},maxSamples:{handler:`handleMaxSamples`,reset:!1},transparentBackground:{handler:`handleTransparentBackground`},exposure:{handler:`handleExposure`},saturation:{handler:`handleSaturation`},renderLimitMode:{handler:`handleRenderLimitMode`},renderTimeLimit:{handler:`handleRenderTimeLimit`,reset:!1},renderMode:{handler:`handleRenderMode`},environmentRotation:{handler:`handleEnvironmentRotation`}},oo={bounces:`maxBounces`,adaptiveSampling:`useAdaptiveSampling`,debugMode:`visMode`},so=class extends n.EventDispatcher{constructor(e=V){super(),this._values=new Map,this._pathTracer=null,this._resetCallback=null,this._handlers={},this._delegates={},this._initDefaults(e)}bind({pathTracer:e,resetCallback:t,handlers:n={},delegates:r={}}){this._pathTracer=e,this._resetCallback=t,this._handlers=n,this._delegates=r}set(e,t,{reset:n,silent:r}={}){let i=this._values.get(e);if(i===t)return;this._values.set(e,t);let a=ao[e];a&&(this._applyRoute(a,t,i),(n===void 0?a.reset??!0:n)&&this._resetCallback?.(),r||this.dispatchEvent({type:R.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=ao[r];a&&(this._applyRoute(a,i,e),(a.reset??!0)&&(n=!0),t||this.dispatchEvent({type:R.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=ao[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(ao))t in e&&this._values.set(t,e[t]);for(let[t,n]of Object.entries(oo))t in e&&this._values.set(n,e[t])}},co=class extends n.EventDispatcher{constructor(e,t,n){super(),this.camera=e,this.controls=t,this.interactionManager=n,this.cameras=[e],this.currentCameraIndex=0,this.autoFocusMode=Pe.SMOOTHING_FACTOR?`auto`:`manual`,this.afScreenPoint={x:.5,y:.5},this.afSmoothingFactor=Pe.SMOOTHING_FACTOR,this._lastValidFocusDistance=null,this._smoothedFocusDistance=null,this._afPointDirty=!1,this._defaultCameraState=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}`)}switchCamera(e,t,r,i){if(!(!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 r=this.cameras[e];if(this.camera.position.copy(r.position),this.camera.quaternion.copy(r.quaternion),this.camera.fov=r.fov,this.camera.near=r.near,this.camera.far=r.far,this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld(!0),this.controls){let e=new n.Vector3(0,0,-1).applyQuaternion(r.quaternion),i=t||5;this.controls.target.copy(this.camera.position).addScaledVector(e,i),this.controls.update()}}r?.(),i?.(),this.dispatchEvent({type:`CameraSwitched`,cameraIndex:e})}}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({meshScene:e,assetLoader:t,floorPlane:n,currentFocusDistance:r,pathTracer:i,setFocusDistance:a,softReset:o,hardReset:s}){if(this.autoFocusMode===`manual`)return;let c=i;if(c?.isReady&&c.renderMode?.value===1&&c.frameCount>0&&!c.isComplete)return;let l=this.afScreenPoint.x*2-1,u=-(this.afScreenPoint.y*2-1),d=this.interactionManager?.raycaster;if(!d)return;d.setFromCamera({x:l,y:u},this.camera);let f=d.intersectObjects(e.children,!0).find(e=>e.object!==this.interactionManager?.focusPointIndicator&&e.object!==n&&!e.object.name.includes(`Helper`)&&e.object.type===`Mesh`),p;if(f)p=f.distance,this._lastValidFocusDistance=p;else if(this._lastValidFocusDistance!==null)p=this._lastValidFocusDistance;else{let e=t?.getSceneScale()||1;p=Pe.FALLBACK_DISTANCE*e,this._lastValidFocusDistance=p}let m=this._afPointDirty;this._afPointDirty=!1,m||this._smoothedFocusDistance===null||this._smoothedFocusDistance===0||Math.abs(p-this._smoothedFocusDistance)/this._smoothedFocusDistance>Pe.SNAP_THRESHOLD?this._smoothedFocusDistance=p:this._smoothedFocusDistance+=this.afSmoothingFactor*(p-this._smoothedFocusDistance);let h=r,g=this._smoothedFocusDistance;if(m||h===0||Math.abs(g-h)/Math.max(h,.001)>.001){a(g);let e=t?.getSceneScale()||1;this.dispatchEvent({type:R.AUTO_FOCUS_UPDATED,distance:g/e});let n=Math.abs(g-h)/Math.max(h,.001);m?s?.():n>Pe.RESET_THRESHOLD&&o?.()}}},lo=class extends n.EventDispatcher{constructor(e,t,n){super(),this.scene=e,this.sceneHelpers=t,this.pathTracer=n}addLight(e){let t={DirectionalLight:{position:[1,1,1],intensity:1,color:`#ffffff`},PointLight:{position:[0,2,0],intensity:100,color:`#ffffff`},SpotLight:{position:[0,1,0],intensity:300,color:`#ffffff`,angle:15},RectAreaLight:{position:[0,2,0],intensity:500,color:`#ffffff`,width:2,height:2}}[e];if(!t)return null;let r;if(e===`DirectionalLight`)r=new n.DirectionalLight(t.color,t.intensity),r.position.fromArray(t.position);else if(e===`PointLight`)r=new n.PointLight(t.color,t.intensity),r.position.fromArray(t.position);else if(e===`SpotLight`){r=new n.SpotLight(t.color,t.intensity),r.position.fromArray(t.position),r.angle=n.MathUtils.degToRad(t.angle);let e=new n.Object3D;this.scene.add(e),r.target=e}else e===`RectAreaLight`&&(r=new n.RectAreaLight(t.color,t.intensity,t.width,t.height),r.position.fromArray(t.position),r.lookAt(0,0,0));let i=this.scene.getObjectsByProperty(`isLight`,!0).length;return r.name=`${e.replace(`Light`,``)} ${i+1}`,this.scene.add(r),this.updateLights(),this._syncHelpers(),this._buildDescriptor(r)}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(),!0)}clearLights(){this.sceneHelpers.clear(),this._removeAllLights(),this.updateLights()}getLights(){return this.scene.getObjectsByProperty(`isLight`,!0).map(e=>this._buildDescriptor(e))}updateLights(){this.pathTracer?.updateLights()}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.target){let r=new n.Object3D;e.target.updateWorldMatrix(!0,!1),e.target.getWorldPosition(r.position),this.scene.add(r),t.target=r}this.scene.add(t)}this.updateLights(),this._syncHelpers()}setShowLightHelper(e){this.sceneHelpers.visible=e,e?this._syncHelpers():this.sceneHelpers.clear()}_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=n.MathUtils.radToDeg(e.angle));let r={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};if(e.type===`RectAreaLight`){r.width=e.width,r.height=e.height;let t=e.getWorldDirection(e.position.clone());r.target=[e.position.x+t.x,e.position.y+t.y,e.position.z+t.z]}else e.type===`SpotLight`&&e.target&&(r.target=[e.target.position.x,e.target.position.y,e.target.position.z]);return r}},Q=e=>Math.min(Math.max(e,0),1);function uo(e,t,n,r,i){i[0]=Q(e),i[1]=Q(t),i[2]=Q(n)}function fo(e,t,n,r,i){i[0]=Q(e*r),i[1]=Q(t*r),i[2]=Q(n*r)}function po(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=Q(e/(e+1)),i[1]=Q(t/(t+1)),i[2]=Q(n/(n+1))}function mo(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 ho(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]=Q(1.60475*a-.53108*o-.07367*s),i[1]=Q(-.10208*a+1.10813*o-.00605*s),i[2]=Q(-.00327*a-.07276*o+1.07602*s)}function go(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=Q((Math.log2(Math.max(c,1e-10))-d)/f),l=Q((Math.log2(Math.max(l,1e-10))-d)/f),u=Q((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]=Q(1.6605*m-.5876*h-.0728*g),i[1]=Q(-.1246*m+1.1329*h-.0083*g),i[2]=Q(-.0182*m-.1006*h+1.1187*g)}function _o(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 vo=new Map([[n.NoToneMapping,uo],[n.LinearToneMapping,fo],[n.ReinhardToneMapping,po],[n.CineonToneMapping,mo],[n.ACESFilmicToneMapping,ho],[n.AgXToneMapping,go],[n.NeutralToneMapping,_o]]),yo=1/2.2,bo=.2126,xo=.7152,So=.0722;function Co(e,t){if(t===1)return;let n=e[0]*bo+e[1]*xo+e[2]*So;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}var wo=null;async function To(){return wo||=(await import(`oidn-web`)).initUNetFromURL,wo}var $=new Float32Array(3),Eo={BASE_URL:`https://cdn.jsdelivr.net/npm/denoiser/tzas/`,QUALITY_SUFFIXES:{fast:`_small`,balance:``,high:`_large`},DEFAULT_OPTIONS:{enableOIDN:!0,oidnQuality:`fast`,debugGbufferMaps:!0,tileSize:256}},Do=class extends n.EventDispatcher{constructor(e,t,r,i,a={}){if(super(),!e||!t||!r||!i)throw Error(`OIDNDenoiser requires output canvas, renderer, scene, and camera`);this.renderer=t,this.scene=r,this.camera=i,this.input=t.domElement,this.output=e,this.debugContainer=a.debugContainer||null,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||(()=>n.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._cachedAlpha=null,this._cachedAlphaWidth=0,this.config={...Eo.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.currentTZAUrl=null,this.unet=null,this.debugHelpers=null,this._lastAlbedoTexture=null,this._lastNormalTexture=null,this._initialize().catch(e=>{console.error(`Failed to initialize OIDNDenoiser:`,e),this.dispatchEvent({type:`error`,error:e})})}async _initialize(){try{this._setupCanvas(),this._initDebugVisualization(),await this._setupUNetDenoiser()}catch(e){throw Error(`Initialization failed: ${e.message}`)}}_initDebugVisualization(){this.debugHelpers=null}_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 To())(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}}_generateTzaUrl(){let{BASE_URL:e,QUALITY_SUFFIXES:t}=Eo;return`${e}rt_hdr_alb_nrm${t[this.quality]||``}.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(Eo.QUALITY_SUFFIXES,e))throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(Eo.QUALITY_SUFFIXES).join(`, `)}`);await this.updateConfiguration({oidnQuality:e})}async start(){if(!this.enabled||this.state.isDenoising||this.state.isLoading)return!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=(n,r)=>i.copyTextureToBuffer({texture:n,mipLevel:0},{buffer:r,offset:0,bytesPerRow:a,rowsPerImage:t},{width:e,height:t,depthOrArrayLayers:1});o(n.color,this._gpuInputBuffers.color),o(n.albedo,this._gpuInputBuffers.albedo),o(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 s={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(s)}_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*4*4,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}}_destroyGPUInputBuffers(){this._gpuInputBuffers.color?.destroy(),this._gpuInputBuffers.albedo?.destroy(),this._gpuInputBuffers.normal?.destroy(),this._gpuInputBuffers={color:null,albedo:null,normal:null},this._gpuInputBufferSize={width:0,height:0}}async _cacheInputAlpha(e,t,n){let r=t*n*4*4,i=e.createBuffer({label:`oidn-alpha-staging`,size:r,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),a=e.createCommandEncoder();a.copyBufferToBuffer(this._gpuInputBuffers.color,0,i,0,r),e.queue.submit([a.finish()]),await i.mapAsync(GPUMapMode.READ);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(),i.destroy(),this._cachedAlpha=c,this._cachedAlphaWidth=t}_executeWithAbortGPU(e){return new Promise((t,r)=>{if(this.state.abortController?.signal.aborted){r(new DOMException(`Aborted`,`AbortError`));return}let i=null,a=()=>{i&&=(i(),null),r(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{await this._displayGPUOutput(e),t()}catch(e){r(e)}},progress:(e,t,r)=>{if(!e?.data||!r)return;this.dispatchEvent({type:`tileProgress`,tile:r,imageWidth:e.width,imageHeight:e.height});let i=this.gpuDevice,a=e.width,o=r.width*16,s=r.width*r.height*16,c=i.createBuffer({size:s,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),l=i.createCommandEncoder();for(let t=0;t<r.height;t++){let n=((r.y+t)*a+r.x)*16,i=t*o;l.copyBufferToBuffer(e.data,n,c,i,o)}i.queue.submit([l.finish()]),c.mapAsync(GPUMapMode.READ).then(()=>{let e=new Float32Array(c.getMappedRange()),t=new ImageData(r.width,r.height),i=this.getExposure(),a=this.getSaturation(),o=vo.get(this.getToneMapping())||vo.get(n.ACESFilmicToneMapping),s=this._cachedAlpha,l=this._cachedAlphaWidth;for(let n=0,c=e.length;n<c;n+=4){let c=e[n]*i,u=e[n+1]*i,d=e[n+2]*i;if(a!==1&&($[0]=c,$[1]=u,$[2]=d,Co($,a),c=$[0],u=$[1],d=$[2]),o(c,u,d,1,$),t.data[n]=$[0]**yo*255|0,t.data[n+1]=$[1]**yo*255|0,t.data[n+2]=$[2]**yo*255|0,s){let e=(n>>2)%r.width,i=(n>>2)/r.width|0;t.data[n+3]=s[(r.y+i)*l+r.x+e]}else t.data[n+3]=255}c.unmap(),c.destroy(),this.ctx.putImageData(t,r.x,r.y)})}})})}async _displayGPUOutput({data:e,width:t,height:r}){let i=this.gpuDevice;if(!i){console.error(`OIDNDenoiser: gpuDevice not available for output readback`);return}let a=t*r*4*4,o=i.createBuffer({label:`oidn-output-staging`,size:a,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),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,r),u=this.getExposure(),d=this.getSaturation(),f=vo.get(this.getToneMapping())||vo.get(n.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&&($[0]=t,$[1]=n,$[2]=r,Co($,d),t=$[0],n=$[1],r=$[2]),f(t,n,r,1,$),l.data[e]=$[0]**yo*255|0,l.data[e+1]=$[1]**yo*255|0,l.data[e+2]=$[2]**yo*255|0,l.data[e+3]=p?p[e>>2]:255}o.unmap(),o.destroy(),this.ctx.putImageData(l,0,0)}abort(){!this.enabled||!this.state.isDenoising||(this.state.abortController?.abort(),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)})}_updateDebugVisualization(e){if(!e?.textures||e.textures.length<3)return;let t=this.debugHelpers&&(this._lastAlbedoTexture!==e.textures[2]||this._lastNormalTexture!==e.textures[1]);if(!this.debugHelpers||t){this.debugHelpers&&(this.debugHelpers.albedo?.dispose(),this.debugHelpers.normal?.dispose(),console.log(`OIDNDenoiser: Recreating debug helpers due to texture change`)),this.debugHelpers={albedo:La(this.renderer,e,{width:250,height:250,position:`bottom-right`,theme:`dark`,title:`OIDN Albedo`,autoUpdate:!1,textureIndex:2}),normal:La(this.renderer,e,{width:250,height:250,position:`bottom-left`,theme:`dark`,title:`OIDN Normal`,autoUpdate:!1,textureIndex:1})},this._lastAlbedoTexture=e.textures[2],this._lastNormalTexture=e.textures[1];let t=this.debugContainer||document.body;t.appendChild(this.debugHelpers.albedo),t.appendChild(this.debugHelpers.normal),this.debugHelpers.albedo.hide(),this.debugHelpers.normal.hide()}this.debugHelpers.albedo.update(),this.debugHelpers.normal.update()}dispose(){this.abort(),this.unet?.dispose(),this._destroyGPUInputBuffers(),this.debugHelpers&&=(this.debugHelpers.albedo?.dispose(),this.debugHelpers.normal?.dispose(),null),this._lastAlbedoTexture=null,this._lastNormalTexture=null,this.output?.parentNode&&this.output.remove(),this.unet=null,this.ctx=null,this.state.abortController=null,this.removeAllListeners?.(),console.log(`OIDNDenoiser disposed`)}},Oo=`https://huggingface.co/notaneimu/onnx-image-models/resolve/main/`,ko={QUALITY_PRESETS:{fast:{2:Oo+`2x-spanx2-ch48.onnx`,4:Oo+`4xNomos8k_span_otf_strong_fp32_opset17.onnx`},balanced:{2:Oo+`2xNomosUni_compact_otf_medium.onnx`,4:Oo+`RealESRGAN_x4plus.onnx`},quality:{2:Oo+`2x-realesrgan-x2plus.onnx`,4:Oo+`4xNomos2_hq_mosr_fp32.onnx`}},TILE_SIZE:512,TILE_OVERLAP:16,SESSION_OPTIONS:{executionProviders:[{name:`webgpu`,preferredLayout:`NCHW`}],graphOptimizationLevel:`all`}},Ao=class extends n.EventDispatcher{constructor(e,t,r={}){if(super(),!e||!t)throw Error(`AIUpscaler requires output canvas and renderer`);this.renderer=t,this.input=t.domElement,this.output=e,this.getSourceCanvas=r.getSourceCanvas||null,this.getGPUTextures=r.getGPUTextures||null,this.getExposure=r.getExposure||(()=>1),this.getToneMapping=r.getToneMapping||(()=>n.ACESFilmicToneMapping),this.getSaturation=r.getSaturation||(()=>1),this.enabled=!1,this.hdr=!1,this.scaleFactor=r.scaleFactor||2,this.quality=r.quality||`fast`,this.tileSize=r.tileSize||ko.TILE_SIZE,this._tileSizeOverride=!!r.tileSize,this.state={isUpscaling:!1,isLoading:!1,abortController:null},this._worker=null,this._currentModelUrl=null,this._tileId=0,this._upscaledAlpha=null,this._upscaledAlphaWidth=0,this._backupCanvas=null,this._baseWidth=e.width,this._baseHeight=e.height}async _ensureSession(){let e=ko.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{this._worker||=new Worker(new URL(``+(typeof document>`u`&&typeof location>`u`?require(`url`).pathToFileURL(__dirname+`/assets/AIUpscalerWorker-BRtNMgzZ.js`).href:new URL(`assets/AIUpscalerWorker-BRtNMgzZ.js`,typeof document>`u`?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()===`SCRIPT`&&document.currentScript.src||document.baseURI).href),``+{}.url),{type:`module`}),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)))};this._worker.addEventListener(`message`,r),this._worker.postMessage({type:`load`,url:t,sessionOptions:ko.SESSION_OPTIONS})}),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.state.isUpscaling&&(this.state.isUpscaling=!1,this.state.abortController=null,this.dispatchEvent({type:`end`}))}}abort(){this.state.isUpscaling&&(this.state.abortController?.abort(),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:r,height:i}=t,a=this.scaleFactor,o=this.output.getContext(`2d`,{willReadFrequently:!0,alpha:!0});this._cacheUpscaledAlpha(t,r*a,i*a),t.isHDR&&(this._hdrToneMapFn=vo.get(this.getToneMapping())||vo.get(n.ACESFilmicToneMapping),this._hdrExposure=this.getExposure(),this._hdrSaturation=this.getSaturation(),this._tmOut=new Float32Array(3));let s=ko.TILE_OVERLAP,c=this.tileSize,l=c-s*2,u=Math.ceil(r/l),d=Math.ceil(i/l),f=u*d,p=0;for(let n=0;n<d;n++)for(let s=0;s<u;s++){if(e.aborted)throw new DOMException(`Aborted`,`AbortError`);let u=Math.min(s*l,Math.max(0,r-c)),d=Math.min(n*l,Math.max(0,i-c)),m=Math.min(c,r-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:n,total:f,completed:p}}),this.dispatchEvent({type:`tileProgress`,tile:{x:v,y,width:b,height:x},imageWidth:r*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,s=t.createBuffer({size:o,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),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(),s.destroy(),{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,Co(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]**+yo,l[c+d]=this._tmOut[1]**+yo,l[2*c+d]=this._tmOut[2]**+yo}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),e.data.type===`inferred`?i(e.data.outputData):e.data.type===`error`&&a(Error(e.data.message)))};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:r,width:i,height:a}=e,o=t.createImageData(i,a),s=o.data,c=vo.get(this.getToneMapping())||vo.get(n.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,n=r[t]*l,i=r[t+1]*l,a=r[t+2]*l;u!==1&&(d[0]=n,d[1]=i,d[2]=a,Co(d,u),n=d[0],i=d[1],a=d[2]),c(n,i,a,1,d),s[t]=d[0]**+yo*255+.5|0,s[t+1]=d[1]**+yo*255+.5|0,s[t+2]=d[2]**+yo*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(!ko.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}async dispose(){this.abort(),this._worker&&=(this._worker.postMessage({type:`dispose`}),this._worker.terminate(),null),this._currentModelUrl=null,this._backupCanvas=null,this._upscaledAlpha=null,this.state.abortController=null,console.log(`AIUpscaler disposed`)}},jo=class extends n.EventDispatcher{constructor({renderer:e,denoiserCanvas:t,scene:n,camera:r,stages:i,pipeline:a,getExposure:o,getSaturation:s,getTransparentBg:c}){super(),this.renderer=e,this.denoiserCanvas=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}setupDenoiser(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.denoiser=new Do(this.denoiserCanvas,this.renderer,this.scene,this.camera,{...V,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=V.enableOIDN,this.denoiser.addEventListener(`start`,()=>this.dispatchEvent({type:R.DENOISING_START})),this.denoiser.addEventListener(`end`,()=>this.dispatchEvent({type:R.DENOISING_END}))}setupUpscaler(){if(!this.denoiserCanvas)return;let e=this._stages.pathTracer;this.upscaler=new Ao(this.denoiserCanvas,this.renderer,{scaleFactor:V.upscalerScale||2,quality:V.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=V.enableUpscaler||!1,this.upscaler.addEventListener(`resolution_changed`,e=>this.dispatchEvent({type:`resolution_changed`,width:e.width,height:e.height})),this.upscaler.addEventListener(`start`,()=>this.dispatchEvent({type:R.UPSCALING_START})),this.upscaler.addEventListener(`progress`,e=>this.dispatchEvent({type:R.UPSCALING_PROGRESS,progress:e.progress})),this.upscaler.addEventListener(`end`,()=>this.dispatchEvent({type:R.UPSCALING_END}))}setDenoiserStrategy(e,t){let n=this._stages;switch(n.asvgf&&(n.asvgf.enabled=!1),n.variance&&!this._isAdaptiveSamplingActive()&&(n.variance.enabled=!1),n.bilateralFilter&&(n.bilateralFilter.enabled=!1),n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!1),n.ssrc&&(n.ssrc.enabled=!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`ssrc`:n.ssrc&&(n.ssrc.enabled=!0);break;case`edgeaware`:n.edgeFilter&&n.edgeFilter.setFilteringEnabled(!0);break}}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)}applyASVGFPreset(e){this._applyASVGFPreset(e)}setAutoExposureEnabled(e,t){let n=this._stages;n.autoExposure&&(n.autoExposure.enabled=e,e?n.display?.setExposure(1):(n.display?.setExposure(t),n.display&&this.renderer&&(this.renderer.toneMappingExposure=1)))}setAdaptiveSamplingEnabled(e){let t=this._stages;t.adaptiveSampling&&(t.adaptiveSampling.enabled=e,t.adaptiveSampling.toggleHelper(!1)),e?t.variance&&(t.variance.enabled=!0):t.asvgf?.enabled||t.variance&&(t.variance.enabled=!1),!e&&this.pipeline?.context&&!t.asvgf?.enabled&&this.pipeline.context.removeTexture(`variance:output`)}onRenderComplete({isStillComplete:e,context:t}){(this.denoiser?.enabled||this.upscaler?.enabled)&&this.denoiserCanvas&&(this.denoiserCanvas.style.display=`block`);let n=()=>{e()&&this.upscaler?.enabled&&this.upscaler.start()};this.denoiser?.enabled?(this.denoiser.addEventListener(`end`,n,{once:!0}),this.denoiser.start()):(this.upscaler?.enabled&&this._stages.display&&t&&this._stages.display.render(t),n())}abort(e){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.denoiser&&=(this.denoiser.dispose(),null),this.upscaler&&=(this.upscaler.dispose(),null)}_getEffectiveExposure(){return this._stages.autoExposure?.enabled?this.renderer.toneMappingExposure:this._getExposure()}_getToneMapping(){return this.renderer.toneMapping}_isAdaptiveSamplingActive(){return this._stages.adaptiveSampling?.enabled??!1}_clearDenoiserTextures(){let e=this.pipeline?.context;e&&[`asvgf:output`,`asvgf:temporalColor`,`asvgf:variance`,`variance:output`,`bilateralFiltering:output`,`edgeFiltering:output`,`ssrc:output`].forEach(t=>e.removeTexture(t))}_applyASVGFPreset(e){let t=ke[e];t&&this._stages.asvgf?.updateParameters(t)}},Mo=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}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)}},No=class{constructor(){this.mixer=null,this.timer=new n.Timer,this.actions=[],this.isPlaying=!1,this._scene=null,this._mixerRoot=null,this._meshes=null,this._meshTriRanges=null,this._posBuffer=null,this._tempVec=new n.Vector3,this._skinnedCache=null,this._totalTriangleCount=0,this._clipsCache=null,this._savedTimeScale=1,this.onFinished=null}init(e,t,r,i,a){if(this.dispose(),!i||i.length===0)return;this._scene=e,this._mixerRoot=t,this._meshes=r,this._totalTriangleCount=a,this.mixer=new n.AnimationMixer(t);let o=i.map(e=>this.mixer.clipAction(e)),s=(e,t)=>e.name===t||e.getObjectByName(t)!==void 0;!o.some(e=>e.getClip().tracks.some(e=>{let n=e.name.split(`.`)[0];return s(t,n)}))&&t!==e&&(console.log(`[AnimationManager] Tracks did not resolve from model root, retrying with scene root`),this.mixer=new n.AnimationMixer(e),this._mixerRoot=e,o=i.map(e=>this.mixer.clipAction(e))),this.actions=o,this.mixer.addEventListener(`finished`,()=>{this.isPlaying=!1,this.timer.reset(),this.onFinished&&this.onFinished()}),this._meshTriRanges=[],this._skinnedCache=[];let c=0;for(let e of r){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:c,count:i,uniqueVerts:a,indices:r}),this._skinnedCache.push(new Float32Array(a*3)),c+=i}this._posBuffer=new Float32Array(a*9);let l=r.filter(e=>e.isSkinnedMesh).length;console.debug(`[AnimationManager] Init: ${i.length} clips, ${r.length} meshes (${l} skinned), ${a} 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}}pause(){this.mixer&&(this.mixer.timeScale=0,this.timer.reset(),this.isPlaying=!1)}resume(){this.mixer&&(this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!0)}stop(){this.mixer&&(this.mixer.stopAllAction(),this.mixer.timeScale=this._savedTimeScale||1,this.timer.reset(),this.isPlaying=!1)}setSpeed(e){this._savedTimeScale=e,this.mixer&&this.isPlaying&&(this.mixer.timeScale=e)}setLoop(e){let t=e?n.LoopRepeat:n.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}},Po=class{constructor({camera:e,canvas:t,orbitControls:r,app:i}){this._app=i,this._orbitControls=r,this._camera=e,this._controls=new h.TransformControls(e,t),this._gizmoScene=new n.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 n.Vector3,this._normalMatrix=new n.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,t){this._meshes=e,this._meshTriRanges=[],this._skinnedCache=[],this._normalCache=[];let n=0;for(let t of e){let e=t.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:n,count:a,uniqueVerts:o,indices:i}),this._skinnedCache.push(new Float32Array(o*3)),this._normalCache.push(new Float32Array(o*3)),n+=a}this._posBuffer=new Float32Array(t*9),this._normalBuffer=new Float32Array(t*9)}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)}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:R.OBJECT_TRANSFORM_START}):(this._recomputeAndRefit(),this._app.dispatchEvent({type:R.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}},Fo=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._borderWidth=2}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;e.strokeStyle=this._borderColor,e.lineWidth=this._borderWidth,e.strokeRect(o,s,c,l)}show(){this.enabled&&(this.visible=!0)}hide(){this.visible=!1,this._tileBounds=null}dispose(){this.visible=!1}},Io=class{constructor(e,r,i){this.layer=`scene`,this.visible=!0,this._outlineNode=(0,g.outline)(r,i,{selectedObjects:[],edgeThickness:(0,s.uniform)(1),edgeGlow:(0,s.uniform)(0)}),this._displayWidth=1,this._displayHeight=1;let a=this._outlineNode.setSize.bind(this._outlineNode);this._outlineNode.setSize=()=>{a(this._displayWidth,this._displayHeight)};let o=(0,s.uniform)(3),c=(0,s.uniform)(new n.Color(16777215)),l=(0,s.uniform)(new n.Color(1640965)),{visibleEdge:u,hiddenEdge:d}=this._outlineNode,f=u.mul(c).add(d.mul(l)).mul(o);this._material=new t.MeshBasicNodeMaterial,this._material.colorNode=(0,s.vec4)(f,1),this._material.blending=n.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?.dispose()}},Lo=class extends n.EventDispatcher{constructor(e,t=null,n={}){super(),this.canvas=e,this.denoiserCanvas=t,this._autoResize=n.autoResize!==!1,this._statsContainer=n.statsContainer||null,this.settings=new so(V),this.renderer=null,this._camera=null,this.scene=null,this.meshScene=null,this._sceneHelpers=null,this._controls=null,this.assetLoader=null,this._sdf=null,this.animationManager=new No,this._animRefitInFlight=!1,this.pipeline=null,this.stages={},this.cameraManager=null,this.lightManager=null,this.denoisingManager=null,this.overlayManager=null,this.isInitialized=!1,this.pauseRendering=!1,this.pathTracerEnabled=!0,this.animationId=null,this.needsReset=!1,this._renderCompleteDispatched=!1,this._loadingInProgress=!1,this._needsDisplayRefresh=!1,this._paused=!1,this.lastResetTime=performance.now(),this.timeElapsed=0,this._lastRenderWidth=0,this._lastRenderHeight=0,this._resizeDebounceTimer=null}set(e,t,n){this.settings.set(e,t,n)}setMany(e,t){this.settings.setMany(e,t)}get(e){return this.settings.get(e)}getAll(){return this.settings.getAll()}async init(){if(_e(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 a=e.limits;this.renderer=new t.WebGPURenderer({canvas:this.canvas,alpha:!0,powerPreference:`high-performance`,requiredLimits:{maxBufferSize:a.maxBufferSize,maxStorageBufferBindingSize:a.maxStorageBufferBindingSize,maxColorAttachmentBytesPerSample:128}}),window.renderer=this.renderer,await this.renderer.init(),t.RectAreaLightNode.setLTC(r.RectAreaLightTexturesLib.init()),this.renderer.toneMapping=n.ACESFilmicToneMapping,this.renderer.toneMappingExposure=1;let o=this.canvas.clientWidth,s=this.canvas.clientHeight;this.renderer.setPixelRatio(1),this._camera=new n.PerspectiveCamera(60,o/s||1,.01,1e3),this._camera.position.set(0,0,5),this.scene=new n.Scene,this.meshScene=new n.Scene,this._sceneHelpers=new T,this._controls=new i.OrbitControls(this._camera,this.canvas),this._controls.screenSpacePanning=!0,this._controls.zoomToCursor=!0,this._controls.saveState(),this._sdf=new Aa,this.assetLoader=new io(this.meshScene,this._camera,this._controls),this._setupFloorPlane(),this.assetLoader.setFloorPlane(this._floorPlane),this._controls.addEventListener(`change`,()=>{this.needsReset=!0,this.wake()}),this._createStages();let{clientWidth:c,clientHeight:l}=this.canvas;this.pipeline=new to(this.renderer,c||1,l||1),this.pipeline.addStage(this.stages.pathTracer),this.pipeline.addStage(this.stages.normalDepth),this.pipeline.addStage(this.stages.motionVector),this.pipeline.addStage(this.stages.ssrc),this.pipeline.addStage(this.stages.asvgf),this.pipeline.addStage(this.stages.variance),this.pipeline.addStage(this.stages.bilateralFilter),this.pipeline.addStage(this.stages.adaptiveSampling),this.pipeline.addStage(this.stages.edgeFilter),this.pipeline.addStage(this.stages.autoExposure),this.pipeline.addStage(this.stages.display);let u=o||1,d=s||1;this.pipeline.setSize(u,d),this._lastRenderWidth=u,this._lastRenderHeight=d,this._interactionManager=new no({scene:this.meshScene,camera:this._camera,canvas:this.canvas,assetLoader:this.assetLoader,pathTracer:null,floorPlane:this._floorPlane}),this._setupInteractionListeners(),this.cameraManager=new co(this._camera,this._controls,this._interactionManager),this.lightManager=new lo(this.scene,this._sceneHelpers,this.stages.pathTracer),this._setupDenoisingManager(),this._setupOverlayManager(),this._transformManager=new Po({camera:this._camera,canvas:this.canvas,orbitControls:this._controls,app:this}),this.cameraManager.addEventListener(`CameraSwitched`,e=>this.dispatchEvent(e)),this.cameraManager.addEventListener(R.AUTO_FOCUS_UPDATED,e=>this.dispatchEvent(e)),this._forwardEvents(this.denoisingManager,[R.DENOISING_START,R.DENOISING_END,R.UPSCALING_START,R.UPSCALING_PROGRESS,R.UPSCALING_END,`resolution_changed`]),this._setupAutoExposureListener(),this._autoFocusContext={meshScene:this.meshScene,assetLoader:this.assetLoader,floorPlane:this._floorPlane,get currentFocusDistance(){return null},pathTracer:this.stages.pathTracer,setFocusDistance:e=>this.settings.set(`focusDistance`,e,{silent:!0}),softReset:()=>this.reset(!0),hardReset:()=>this.reset()};let f=this.settings;return Object.defineProperty(this._autoFocusContext,`currentFocusDistance`,{get:()=>f.get(`focusDistance`)}),this.settings.bind({pathTracer:this.stages.pathTracer,resetCallback:()=>this.reset(),handlers:this._buildSettingsHandlers(),delegates:{}}),this.onResize(),this.resizeHandler=()=>this.onResize(),this._autoResize&&window.addEventListener(`resize`,this.resizeHandler),this._onAssetLoaded=async e=>{if(!this._loadingInProgress){if(e.model)await this.loadSceneData();else if(e.texture){let e=this.meshScene.environment;e&&this.stages.pathTracer&&await this.stages.pathTracer.environment.setEnvironmentMap(e),ve()}this.pauseRendering=!1,this.reset()}},this.assetLoader.addEventListener(`load`,this._onAssetLoaded),this.assetLoader.addEventListener(`modelProcessed`,e=>{let t=[this._camera,...e.cameras||[]];this.cameraManager.setCameras(t),this._floorPlane=this.assetLoader.floorPlane,this._interactionManager&&(this._interactionManager.floorPlane=this._floorPlane)}),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._initStats(),this.isInitialized=!0,console.log(`WebGPU Path Tracer App initialized`),this}animate(){if(this.animationId=requestAnimationFrame(()=>this.animate()),this._loadingInProgress||this._sdf?.isProcessing){this._stats?.update();return}if(this._controls&&this._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._camera.updateMatrixWorld(),!this.pathTracerEnabled){this.renderer.render(this.meshScene,this._camera),this._renderHelperOverlay();return}if(!this.pauseRendering){if(this.cameraManager.updateAutoFocus(this._autoFocusContext),this.stages.pathTracer?.isReady){if(this.stages.pathTracer.isComplete&&this._renderCompleteDispatched){this._needsDisplayRefresh&&(this._needsDisplayRefresh=!1,this.stages.display.render(this.pipeline.context),this._renderHelperOverlay()),this.stopAnimation();return}this.pipeline.render(),this.stages.pathTracer.isComplete||(this.timeElapsed=(performance.now()-this.lastResetTime)/1e3),ye({timeElapsed:this.timeElapsed,samples:be(this.stages.pathTracer)});let e=this.settings.get(`renderLimitMode`),t=this.settings.get(`renderTimeLimit`);e===`time`&&t>0&&this.timeElapsed>=t&&(this.stages.pathTracer.isComplete=!0),this.stages.pathTracer.isComplete&&!this._renderCompleteDispatched&&(this._renderCompleteDispatched=!0,this.denoisingManager.onRenderComplete({isStillComplete:()=>this._renderCompleteDispatched,context:this.pipeline?.context}),this.dispatchEvent({type:`RenderComplete`}),this.dispatchEvent({type:R.RENDER_COMPLETE}))}this._renderHelperOverlay(),this._stats?.update(),this.renderer.resolveTimestampsAsync?.(n.TimestampQuery.RENDER),this.renderer.resolveTimestampsAsync?.(n.TimestampQuery.COMPUTE)}}stopAnimation(){this.animationId&&=(cancelAnimationFrame(this.animationId),null)}wake(){!this.animationId&&this.isInitialized&&!this._paused&&this.animate()}pause(){this._paused=!0,this.stopAnimation(),this._stats&&(this._stats.dom.style.display=`none`)}resume(){this._paused=!1,this.animationId||this.animate(),this._stats&&(this._stats.dom.style.display=``)}reset(e=!1){if(this.pipeline&&(this.pipeline.reset(),e||this.pipeline.eventBus.emit(`asvgf:reset`)),this.denoisingManager?.abort(this.canvas),this.denoiserCanvas&&this._lastRenderWidth&&this._lastRenderHeight){let e=this.denoiserCanvas.width!==this._lastRenderWidth||this.denoiserCanvas.height!==this._lastRenderHeight;this.denoiserCanvas.width=this._lastRenderWidth,this.denoiserCanvas.height=this._lastRenderHeight,e&&this.dispatchEvent({type:`resolution_changed`,width:this._lastRenderWidth,height:this._lastRenderHeight})}this.timeElapsed=0,this.lastResetTime=performance.now(),this._renderCompleteDispatched=!1,this.wake(),this.dispatchEvent({type:`RenderReset`}),this.dispatchEvent({type:R.RENDER_RESET})}dispose(){this.animationManager?.dispose(),this.stopAnimation(),_e(null),this.assetLoader&&this._onAssetLoaded&&this.assetLoader.removeEventListener(`load`,this._onAssetLoaded),this._transformManager?.dispose(),this.overlayManager?.dispose(),this._sceneHelpers?.clear(),this.denoisingManager?.dispose(),this.pipeline?.dispose(),this._interactionManager?.dispose(),this._controls?.dispose(),this.renderer?.dispose(),this._stats&&=(this._stats.dom.remove(),null),clearTimeout(this._resizeDebounceTimer),window.removeEventListener(`resize`,this.resizeHandler),this.isInitialized=!1}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){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})}async _loadWithSceneRebuild(e,t){this._loadingInProgress=!0;try{await e(),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.animationManager.dispose(),this._animRefitInFlight=!1;let e=new Xi(`loadSceneData`),t=this.meshScene.environment,n=null;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)`),await this._sdf.buildBVH(this.meshScene),e.end(`BVH build (SceneProcessor)`);let{triangleData:r,triangleCount:i,bvhData:a,materialData:o}=this._sdf;if(!r)return console.error(`PathTracerApp: Failed to get triangle data`),!1;if(z({status:`Transferring data to GPU...`,progress:86}),await new Promise(e=>setTimeout(e,0)),e.start(`GPU data transfer`),this.stages.pathTracer.setTriangleData(r,i),!a)return console.error(`PathTracerApp: Failed to get BVH data`),!1;this.stages.pathTracer.setBVHData(a),o?this.stages.pathTracer.materialData.setMaterialData(o):console.warn(`PathTracerApp: No material data, using defaults`),t&&this.stages.pathTracer.environment.setEnvironmentTexture(t),this.stages.pathTracer.materialData.setMaterialTextures({albedoMaps:this._sdf.albedoTextures,normalMaps:this._sdf.normalTextures,bumpMaps:this._sdf.bumpTextures,roughnessMaps:this._sdf.roughnessTextures,metalnessMaps:this._sdf.metalnessTextures,emissiveMaps:this._sdf.emissiveTextures,displacementMaps:this._sdf.displacementTextures}),this._sdf.emissiveTriangleData&&this.stages.pathTracer.setEmissiveTriangleData(this._sdf.emissiveTriangleData,this._sdf.emissiveTriangleCount,this._sdf.emissiveTotalPower),this._sdf.lightBVHNodeData&&this.stages.pathTracer.setLightBVHData(this._sdf.lightBVHNodeData,this._sdf.lightBVHNodeCount),this.lightManager.transferSceneLights(this.meshScene),e.end(`GPU data transfer`),z({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)`),n&&(z({status:`Finalizing environment map...`,progress:95}),await n,this.stages.pathTracer.environment.applyCDFResults()),e.start(`Apply settings`),this.settings.applyAll(),this.stages.display.setTransparentBackground(this.settings.get(`transparentBackground`)),e.end(`Apply settings`),e.print(),ve();let s=this.assetLoader?.animations||[];if(s.length>0){let e=this.assetLoader?.targetModel||this.meshScene;this.animationManager.init(this.meshScene,e,this._sdf.meshes,s,this._sdf.triangleCount),this.animationManager.onFinished=()=>{this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_FINISHED})}}return this._transformManager?.setMeshData(this._sdf.meshes,this._sdf.triangleCount),this.dispatchEvent({type:`SceneRebuild`}),!0}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),i=this._sdf.instanceTable,a=[],o=[];for(let t of e){let e=i.entries[t];e&&(a.push({offset:e.triOffset*32,count:e.triCount*32}),o.push({offset:e.blasOffset*16,count:e.blasNodeCount*16}))}return o.push({offset:0,count:i.tlasNodeCount*16}),this.stages.pathTracer.updateBufferRanges(a,o),this.reset(),this._sdf.scheduleBackgroundRebuild(e,()=>{this.stages.pathTracer.updateTriangleData(this._sdf.triangleData),this.stages.pathTracer.updateBVHData(this._sdf.bvhData),this.reset()}),r}playAnimation(e=0){if(!this.animationManager?.hasAnimations){console.warn(`playAnimation: No animation clips available`);return}this.animationManager.play(e),this.wake(),this.dispatchEvent({type:R.ANIMATION_STARTED,clipIndex:e})}pauseAnimation(){this.animationManager?.pause(),this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_PAUSED})}resumeAnimation(){this.animationManager?.resume(),this.wake(),this.dispatchEvent({type:R.ANIMATION_STARTED})}stopAnimationPlayback(){this.animationManager?.stop(),this._animRefitInFlight=!1,this.dispatchEvent({type:R.ANIMATION_STOPPED})}setAnimationSpeed(e){this.animationManager?.setSpeed(e)}setAnimationLoop(e){this.animationManager?.setLoop(e)}get animationClips(){return this.animationManager?.clips||[]}onResize(){let e=this.canvas.clientWidth,t=this.canvas.clientHeight;if(e===0||t===0)return;this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this._camera.aspect=e/t,this._camera.updateProjectionMatrix();let n=window.devicePixelRatio||1;this.overlayManager?.setSize(Math.round(e*n),Math.round(t*n)),!(e===this._lastRenderWidth&&t===this._lastRenderHeight)&&(clearTimeout(this._resizeDebounceTimer),this._resizeDebounceTimer=setTimeout(()=>{this._applyRenderResize(e,t)},300))}_applyRenderResize(e,t){this._lastRenderWidth=e,this._lastRenderHeight=t,this.pipeline?.setSize(e,t),this.denoisingManager?.denoiser?.setSize(e,t),this.denoisingManager?.upscaler?.setBaseSize(e,t),this.needsReset=!0,this.dispatchEvent({type:`resolution_changed`,width:e,height:t})}setCanvasSize(e,t){this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.denoiserCanvas&&(this.denoiserCanvas.style.width=`${e}px`,this.denoiserCanvas.style.height=`${t}px`),!(e===0||t===0)&&(this.renderer.setPixelRatio(1),this.renderer.setSize(e,t,!1),this._camera.aspect=e/t,this._camera.updateProjectionMatrix(),clearTimeout(this._resizeDebounceTimer),this._applyRenderResize(e,t))}configureForMode(e,t={}){if(e===`results`){this.pauseRendering=!0,this._controls.enabled=!1,this.renderer?.domElement&&(this.renderer.domElement.style.display=`none`),this.denoisingManager?.denoiser?.output&&(this.denoisingManager.denoiser.output.style.display=`none`);return}let n=e===`final-render`,r=n?G:Ie;this._controls.enabled=!n,this.settings.setMany({maxSamples:r.maxSamples,maxBounces:r.bounces,samplesPerPixel:r.samplesPerPixel,transmissiveBounces:r.transmissiveBounces},{silent:!0}),this.setRenderMode(r.renderMode),this.setTileCount(r.tiles),this.setTileHelperEnabled(r.tilesHelper),this.stages.pathTracer?.updateCompletionThreshold?.();let i=this.denoisingManager?.denoiser;i&&(i.abort(),i.enabled=r.enableOIDN,i.updateQuality(r.oidnQuality)),this.denoisingManager?.upscaler?.abort(),t.canvasWidth&&t.canvasHeight&&this.setCanvasSize(t.canvasWidth,t.canvasHeight),this.renderer?.domElement&&(this.renderer.domElement.style.display=`block`),this.denoisingManager?.denoiser?.output&&(this.denoisingManager.denoiser.output.style.display=`block`),this.needsReset=!1,this.pauseRendering=!1,this.reset()}switchCamera(e){this.cameraManager.switchCamera(e,this.settings.get(`focusDistance`),()=>this.onResize(),()=>this.reset())}getCameraNames(){return this.cameraManager.getCameraNames()}addLight(e){let t=this.lightManager.addLight(e);return this.reset(),t}removeLight(e){let t=this.lightManager.removeLight(e);return t&&this.reset(),t}clearLights(){this.lightManager.clearLights(),this.reset()}getLights(){return this.lightManager.getLights()}updateLights(){this.lightManager.updateLights()}setShowLightHelper(e){this.lightManager.setShowLightHelper(e)}setDenoiserStrategy(e,t){this.denoisingManager.setDenoiserStrategy(e,t),this.reset()}setASVGFEnabled(e,t){this.denoisingManager.setASVGFEnabled(e,t),this.reset()}applyASVGFPreset(e){this.denoisingManager.applyASVGFPreset(e),this.reset()}setAutoExposureEnabled(e){this.denoisingManager.setAutoExposureEnabled(e,this.settings.get(`exposure`)),this.reset()}setAdaptiveSamplingEnabled(e){this.settings.set(`useAdaptiveSampling`,e),this.denoisingManager.setAdaptiveSamplingEnabled(e)}selectObject(e){let t=this.overlayManager?.getHelper(`outline`);t&&t.setSelectedObjects(e?[e]:[]),this._interactionManager&&(this._interactionManager.selectedObject=e||null),this._transformManager&&(e?this._transformManager.attach(e):this._transformManager.detach()),this.dispatchEvent({type:R.OBJECT_SELECTED,object:e||null})}toggleFocusMode(){if(!this._interactionManager)return!1;let e=this._interactionManager.toggleFocusMode();return this._controls&&(this._controls.enabled=!e),e}toggleSelectMode(){return this._interactionManager?this._interactionManager.toggleSelectMode():!1}disableSelectMode(){this._interactionManager?.disableSelectMode(),this._transformManager?.detach()}setTransformMode(e){this._transformManager?.setMode(e),this.dispatchEvent({type:R.TRANSFORM_MODE_CHANGED,mode:e})}setTransformSpace(e){this._transformManager?.setSpace(e)}get transformManager(){return this._transformManager}refreshFrame(){this._needsDisplayRefresh=!0,this.wake()}getEnvParams(){return this.stages.pathTracer?.environment?.envParams??null}getEnvironmentTexture(){return this.stages.pathTracer?.environment?.environmentTexture??null}getEnvironmentCDF(){return null}async generateProceduralSkyTexture(){return this.stages.pathTracer?.environment.generateProceduralSkyTexture()}async generateGradientTexture(){return this.stages.pathTracer?.environment.generateGradientTexture()}async generateSolidColorTexture(){return this.stages.pathTracer?.environment.generateSolidColorTexture()}async setEnvironmentMap(e){if(!this.stages.pathTracer){console.warn(`PathTracerApp: PathTracer not initialized`);return}await this.stages.pathTracer.environment.setEnvironmentMap(e),this.reset()}markEnvironmentNeedsUpdate(){let e=this.stages.pathTracer?.environment?.environmentTexture;e&&(e.needsUpdate=!0)}async setEnvironmentMode(e){let t=this._environmentMode||`hdri`;this._environmentMode=e,e!==`hdri`&&t===`hdri`&&(this._previousHDRI=this.getEnvironmentTexture(),this._previousCDF=this.getEnvironmentCDF()),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._previousCDF=null);let n=this.getEnvParams();n&&(n.mode=e),this.markEnvironmentNeedsUpdate(),this.pipeline?.eventBus.emit(`autoexposure:resetHistory`),this.reset()}isComplete(){return this.stages.pathTracer?.isComplete??!1}getFrameCount(){return this.stages.pathTracer?.frameCount||0}get camera(){return this.cameraManager?.camera??this._camera}get controls(){return this.cameraManager?.controls??this._controls}getSceneStatistics(){try{return this._sdf?.getStatistics?.()??null}catch{return null}}getOutputCanvas(){if(!this.renderer?.domElement)return null;let e=this.denoisingManager?.denoiser,t=this.denoisingManager?.upscaler;return(e?.enabled||t?.enabled)&&this.denoiserCanvas&&this.stages.pathTracer?.isComplete?this.denoiserCanvas:(this.stages.display&&this.pipeline?.context&&this.stages.display.render(this.pipeline.context),this.renderer.domElement)}focusOnPoint(e){!e||!this._controls||(this._controls.target.copy(e),this._controls.update(),this.reset())}dispatchInteractionEvent(e){this._interactionManager?.dispatchEvent(e)}onInteractionEvent(e,t){return this._interactionManager?.addEventListener(e,t),()=>this._interactionManager?.removeEventListener(e,t)}takeScreenshot(){let e=this.getOutputCanvas();if(e)try{let t=e.toDataURL(`image/png`),n=document.createElement(`a`);n.href=t,n.download=`screenshot.png`,n.click()}catch(e){console.error(`PathTracerApp: Screenshot failed:`,e)}}setPathTracerEnabled(e){this.pathTracerEnabled=e}setAccumulationEnabled(e){this.stages.pathTracer?.setAccumulationEnabled(e)}setRenderMode(e){this.stages.pathTracer?.setUniform(`renderMode`,parseInt(e))}setTileCount(e){this.stages.pathTracer?.tileManager?.setTileCount(e)}setInteractionModeEnabled(e){this.stages.pathTracer?.setInteractionModeEnabled(e)}setAdaptiveSamplingParameters(e){e.min!==void 0&&this.stages.pathTracer?.setAdaptiveSamplingMin(e.min),e.adaptiveSamplingMax!==void 0&&this.settings.set(`adaptiveSamplingMax`,e.adaptiveSamplingMax),this.stages.adaptiveSampling?.setAdaptiveSamplingParameters(e)}updateMaterialProperty(e,t,n){if(this.stages.pathTracer?.materialData.updateMaterialProperty(e,t,n),[`emissive`,`emissiveIntensity`,`visible`].includes(t)&&this._sdf?.emissiveTriangleBuilder&&this.stages.pathTracer?.enableEmissiveTriangleSampling?.value){let r=this._sdf.materials[e];if(r&&(t===`emissive`?r.emissive=n:t===`emissiveIntensity`?r.emissiveIntensity=n:t===`visible`&&(r.visible=n),this._sdf.emissiveTriangleBuilder.updateMaterialEmissive(e,r,this._sdf.triangleData,this._sdf.materials,this._sdf.triangleCount))){let e=this._sdf.emissiveTriangleBuilder.createEmissiveRawData();this.stages.pathTracer.setEmissiveTriangleData(e,this._sdf.emissiveTriangleBuilder.emissiveCount,this._sdf.emissiveTriangleBuilder.totalEmissivePower)}}this.reset()}updateTextureTransform(e,t,n){this.stages.pathTracer?.materialData.updateTextureTransform(e,t,n),this.reset()}refreshMaterial(){this.reset()}updateMaterial(e,t){this.stages.pathTracer?.materialData.updateMaterial(e,t)}async rebuildMaterials(e){await this.stages.pathTracer?.rebuildMaterials(e||this.meshScene)}updateASVGFParameters(e){this.stages.asvgf?.updateParameters(e)}toggleASVGFHeatmap(e){this.stages.asvgf?.toggleHeatmap?.(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))}updateSSRCParameters(e){this.stages.ssrc?.updateParameters(e)}updateEdgeAwareUniforms(e){this.stages.edgeFilter?.updateUniforms(e)}updateAutoExposureParameters(e){this.stages.autoExposure?.updateParameters(e)}updateAdaptiveSamplingParameters(e){this.stages.adaptiveSampling?.setAdaptiveSamplingParameters(e)}setAdaptiveSamplingVarianceThreshold(e){this.stages.adaptiveSampling?.setVarianceThreshold(e)}setAdaptiveSamplingMaterialBias(e){this.stages.adaptiveSampling?.setMaterialBias(e)}setAdaptiveSamplingEdgeBias(e){this.stages.adaptiveSampling?.setEdgeBias(e)}setAdaptiveSamplingConvergenceSpeed(e){this.stages.adaptiveSampling?.setConvergenceSpeed(e)}toggleAdaptiveSamplingHelper(e){this.stages.adaptiveSampling?.toggleHelper(e)}setTileHighlightEnabled(e){this.setTileHelperEnabled(e)}setOIDNEnabled(e){let t=this.denoisingManager?.denoiser;t&&(t.enabled=e)}updateOIDNQuality(e){this.denoisingManager?.denoiser?.updateQuality(e)}setOIDNTileHelper(e){this.setTileHelperEnabled(e)}setTileHelperEnabled(e){let t=this.overlayManager?.getHelper(`tiles`);t&&(t.enabled=e,e||t.hide())}setUpscalerEnabled(e){let t=this.denoisingManager?.upscaler;t&&(t.enabled=e)}setUpscalerScaleFactor(e){this.denoisingManager?.upscaler?.setScaleFactor(e)}setUpscalerQuality(e){this.denoisingManager?.upscaler?.setQuality(e)}_createStages(){let e=this.settings.get(`adaptiveSamplingMax`),t=this.settings.get(`useAdaptiveSampling`);this.stages.pathTracer=new Pa(this.renderer,this.scene,this._camera),this.stages.normalDepth=new Fa(this.renderer,{pathTracer:this.stages.pathTracer}),this.stages.motionVector=new Ia(this.renderer,this._camera,{pathTracer:this.stages.pathTracer}),this.stages.ssrc=new Za(this.renderer,{enabled:!1}),this.stages.asvgf=new Ra(this.renderer,{enabled:!1}),this.stages.variance=new Ba(this.renderer,{enabled:!1}),this.stages.bilateralFilter=new Ha(this.renderer,{enabled:!1}),this.stages.adaptiveSampling=new Ga(this.renderer,{adaptiveSamplingMax:e,enabled:t}),this.stages.edgeFilter=new Ka(this.renderer,{enabled:!1}),this.stages.autoExposure=new Ja(this.renderer,{enabled:V.autoExposure??!1}),this.stages.display=new Qa(this.renderer,{exposure:V.autoExposure?1:this.settings.get(`exposure`)??1,saturation:this.settings.get(`saturation`)??V.saturation})}_setupDenoisingManager(){this.denoisingManager=new jo({renderer:this.renderer,denoiserCanvas:this.denoiserCanvas,scene:this.scene,camera:this._camera,stages:{pathTracer:this.stages.pathTracer,asvgf:this.stages.asvgf,variance:this.stages.variance,bilateralFilter:this.stages.bilateralFilter,adaptiveSampling:this.stages.adaptiveSampling,edgeFilter:this.stages.edgeFilter,ssrc:this.stages.ssrc,autoExposure:this.stages.autoExposure,display:this.stages.display},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()}_buildSettingsHandlers(){return{handleTransparentBackground:e=>{this.stages.pathTracer?.setUniform(`transparentBackground`,e),this.stages.display?.setTransparentBackground(e)},handleExposure:e=>{this.stages.autoExposure?.enabled||this.stages.display?.setExposure(e)},handleSaturation:e=>{this.stages.display?.setSaturation(e)},handleRenderLimitMode:e=>{this.stages.pathTracer?.setRenderLimitMode&&this.stages.pathTracer.setRenderLimitMode(e)},handleMaxSamples:e=>{this.stages.pathTracer?.setUniform(`maxSamples`,e),this.stages.pathTracer?.updateCompletionThreshold(),this._reconcileCompletion()},handleRenderTimeLimit:()=>{this._reconcileCompletion()},handleRenderMode:e=>{this.stages.pathTracer?.setUniform(`renderMode`,parseInt(e))},handleEnvironmentRotation:e=>{this.stages.pathTracer?.environment.setEnvironmentRotation(e)}}}_reconcileCompletion(){let e=this.stages.pathTracer;if(!e)return;let t=this._isRenderLimitReached();if(t&&!e.isComplete)e.isComplete=!0;else if(!t&&e.isComplete){e.isComplete=!1,this._renderCompleteDispatched=!1,this.lastResetTime=performance.now()-this.timeElapsed*1e3,this.canvas.style.opacity=`1`;let t=this.denoisingManager?.denoiser?.output;t&&(t.style.display=`none`),this.dispatchEvent({type:R.RENDER_RESET}),this.wake()}}_isRenderLimitReached(){let e=this.stages.pathTracer;if(!e)return!1;if(this.settings.get(`renderLimitMode`)===`time`){let e=this.settings.get(`renderTimeLimit`);return e>0&&this.timeElapsed>=e}return e.frameCount>=e.completionThreshold}_setupFloorPlane(){this._floorPlane=new n.Mesh(new n.CircleGeometry,new n.MeshPhysicalMaterial({transparent:!1,color:3158064,roughness:1,metalness:0,opacity:0,transmission:0})),this._floorPlane.name=`Ground`,this._floorPlane.visible=!1,this.meshScene.add(this._floorPlane)}_initStats(){this._stats=new o.default({horizontal:!0,trackGPU:!0}),this._stats.dom.style.position=`absolute`,this._stats.dom.style.top=`unset`,this._stats.dom.style.bottom=`48px`,this._stats.init(this.renderer),(this._statsContainer||this.canvas.parentElement||document.body).appendChild(this._stats.dom);let e=`#ffffff`,t=`#1e293b`,n=this._stats.fpsPanel.context.createLinearGradient(0,this._stats.fpsPanel.GRAPH_Y,0,this._stats.fpsPanel.GRAPH_Y+this._stats.fpsPanel.GRAPH_HEIGHT);n.addColorStop(0,e),this._stats.fpsPanel.fg=this._stats.msPanel.fg=e,this._stats.fpsPanel.bg=this._stats.msPanel.bg=t,this._stats.fpsPanel.gradient=this._stats.msPanel.gradient=n,this._stats.gpuPanel&&(this._stats.gpuPanel.fg=e,this._stats.gpuPanel.bg=t,this._stats.gpuPanel.gradient=n),this._stats.dom.style.display=``}_setupInteractionListeners(){this._interactionManager&&(this._interactionManager.addEventListener(`objectSelected`,e=>{this.selectObject(e.object),this.refreshFrame(),this.dispatchEvent({type:`objectSelected`,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`objectDeselected`,e=>{this.selectObject(null),this.refreshFrame(),this.dispatchEvent({type:`objectDeselected`,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`selectModeChanged`,e=>{this.dispatchEvent({type:R.SELECT_MODE_CHANGED,enabled:e.enabled})}),this._interactionManager.addEventListener(`objectDoubleClicked`,e=>{this.selectObject(e.object),this.refreshFrame(),this.dispatchEvent({type:R.OBJECT_DOUBLE_CLICKED,object:e.object,uuid:e.uuid})}),this._interactionManager.addEventListener(`focusChanged`,e=>{this.settings.set(`focusDistance`,e.worldDistance),this.dispatchEvent({type:`focusChanged`,distance:e.distance})}),this._interactionManager.addEventListener(`focusModeChanged`,e=>{!e.enabled&&this._controls&&(this._controls.enabled=!0)}),this._interactionManager.addEventListener(`afPointPlaced`,e=>{this.cameraManager.setAFScreenPoint(e.point.x,e.point.y),this._controls&&(this._controls.enabled=!0),this.dispatchEvent({type:R.AF_POINT_PLACED,point:e.point})}))}_setupAutoExposureListener(){this.stages.autoExposure&&this.stages.autoExposure.on(`autoexposure:updated`,e=>{this.dispatchEvent({type:R.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 Mo(this.renderer,this._camera),this.overlayManager.setHelperScene(this._sceneHelpers);let e=new Fo;this.overlayManager.register(`tiles`,e),e.setRenderSize(this._lastRenderWidth||1,this._lastRenderHeight||1),this.addEventListener(`resolution_changed`,t=>{e.setRenderSize(t.width,t.height)}),this.pipeline.eventBus.on(`tile:changed`,t=>{t.renderMode===1&&t.tileBounds&&(e.setActiveTile(t.tileBounds),e.show())}),this.pipeline.eventBus.on(`pipeline:reset`,()=>e.hide()),this.addEventListener(R.RENDER_COMPLETE,()=>e.hide()),this._setupDenoiserTileHelper(e);let t=new Io(this.renderer,this.meshScene,this._camera);this.overlayManager.register(`outline`,t)}_setupDenoiserTileHelper(e){let t=[this.denoisingManager?.denoiser,this.denoisingManager?.upscaler];for(let n of t)n&&(n.addEventListener(`tileProgress`,t=>{t.tile&&(e.setRenderSize(t.imageWidth,t.imageHeight),e.setActiveTile(t.tile),e.show(),this.overlayManager?.refreshHUD())}),n.addEventListener(`end`,()=>{e.hide(),this.overlayManager?.refreshHUD()}))}_syncControlsAfterLoad(){this._controls.saveState(),this._controls.update()}_forwardEvents(e,t){if(e)for(let n of t)e.addEventListener(n,e=>this.dispatchEvent(e))}},Ro=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=G.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(`final-render`),l.settings.setMany({maxSamples:i},{silent:!0}),l.stages.pathTracer?.updateCompletionThreshold?.(),l._controls&&(l._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.getOutputCanvas();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:R.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:R.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._camera.updateMatrixWorld(),e.pipeline.render(),t.frameCount%4==0&&(ye({samples:be(t)}),await new Promise(e=>setTimeout(e,0)))}_waitForDenoise(e){return new Promise(t=>{let n,r=()=>{e.removeEventListener(R.DENOISING_END,i),clearTimeout(n)},i=()=>{r(),t()};n=setTimeout(()=>{console.warn(`VideoRenderManager: Denoise timed out, skipping`),r(),t()},3e4),e.addEventListener(R.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`),samplesPerPixel:e.settings.get(`samplesPerPixel`),transmissiveBounces:e.settings.get(`transmissiveBounces`),renderMode:e.stages.pathTracer?.renderMode?.value,controlsEnabled:e._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,samplesPerPixel:e.samplesPerPixel,transmissiveBounces:e.transmissiveBounces},{silent:!0}),t.stages.pathTracer&&e.renderMode!==void 0&&t.setRenderMode(e.renderMode),t.stages.pathTracer?.updateCompletionThreshold?.(),t._controls&&(t._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=Pe,e.ASVGF_QUALITY_PRESETS=ke,e.AUTO_FOCUS_MODES=Ne,e.AnimationManager=No,e.BVH_LEAF_MARKERS=Fe,e.CAMERA_PRESETS=Me,e.CAMERA_RANGES=Ae,e.CameraManager=co,e.DEFAULT_TEXTURE_MATRIX=W,e.DenoisingManager=jo,e.ENGINE_DEFAULTS=V,e.EngineEvents=R,e.FINAL_RENDER_CONFIG=G,e.LightManager=lo,e.MEMORY_CONSTANTS=Le,e.OverlayManager=Mo,e.PREVIEW_RENDER_CONFIG=Ie,e.PathTracerApp=Lo,e.PipelineContext=$a,e.RenderPipeline=to,e.RenderSettings=so,e.RenderStage=L,e.SKY_PRESETS=je,e.StageExecutionMode=I,e.TEXTURE_CONSTANTS=U,e.TRIANGLE_DATA_LAYOUT=H,e.TransformManager=Po,e.VideoRenderManager=Ro});
697
697
  //# sourceMappingURL=rayzee.umd.js.map