rayzee 8.2.0 → 8.3.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.
package/dist/rayzee.umd.js
CHANGED
|
@@ -519,7 +519,7 @@
|
|
|
519
519
|
let p = o + xu * x + yv * y + z0 * z;
|
|
520
520
|
return vec4f( p, 1.0f / S );
|
|
521
521
|
}
|
|
522
|
-
`),za=It(`shader`),Ba=class{constructor(){this.prevColorTexNode=null,this.prevAlbedoTexNode=null,this.prevNormalDepthTexNode=null,this._sceneTextureNodes=null}updateSceneTextures(e){let t=this._sceneTextureNodes,n=e.environment;n.environmentTexture&&t.envTex&&(t.envTex.value=n.environmentTexture),e.goboMaps&&t.goboMapsTex&&(t.goboMapsTex.value=e.goboMaps),e.iesProfiles&&t.iesProfilesTex&&(t.iesProfilesTex.value=e.iesProfiles),za.debug(`scene textures updated in-place`)}updateGoboMaps(e){let t=this._sceneTextureNodes;!t||!t.goboMapsTex||e&&(t.goboMapsTex.value=e)}updateIESProfiles(e){let t=this._sceneTextureNodes;!t||!t.iesProfilesTex||e&&(t.iesProfilesTex.value=e)}getSceneTextureNodes(){return this._sceneTextureNodes}createSceneTextureNodes(e,t){let i=e.triangleStorageNode,a=e.bvhStorageNode,o=e.materialData.materialStorageNode,s=e.lightStorageNode;wr(e.uniforms.get(`enableAlphaShadows`));let c=(0,n.texture)(e.environment.environmentTexture),l=t.getReadTextures();this.prevColorTexNode=(0,n.texture)(l.color),this.prevAlbedoTexNode=(0,n.texture)(l.albedo),this.prevNormalDepthTexNode=(0,n.texture)(l.normalDepth);let u=()=>{let e=new r.DataArrayTexture(new Uint8Array([255,255,255,255]),1,1,1);return e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e.generateMipmaps=!1,e.needsUpdate=!0,(0,n.texture)(e)},d=e.goboMaps?(0,n.texture)(e.goboMaps):u();ka(d);let f=e.iesProfiles?(0,n.texture)(e.iesProfiles):u();Na(f);let p={triStorage:i,bvhStorage:a,matStorage:o,lightBufferStorage:s,envTex:c,goboMapsTex:d,iesProfilesTex:f};return this._sceneTextureNodes=p,p}dispose(){this.prevColorTexNode=null,this.prevAlbedoTexNode=null,this.prevNormalDepthTexNode=null,this._sceneTextureNodes=null}},Va=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,t,n){if(typeof e==`number`){let r=t[n[e]],i=new Ha;return i.minX=r.minX,i.minY=r.minY,i.minZ=r.minZ,i.maxX=r.maxX,i.maxY=r.maxY,i.maxZ=r.maxZ,i.triangleOffset=r.triangleOffset,i.triangleCount=r.triangleCount,i}let r=this.buildSubtree(e[0],t,n),i=this.buildSubtree(e[1],t,n),a=new Ha;return a.leftChild=r,a.rightChild=i,a.minX=Math.min(r.minX,i.minX),a.minY=Math.min(r.minY,i.minY),a.minZ=Math.min(r.minZ,i.minZ),a.maxX=Math.max(r.maxX,i.maxX),a.maxY=Math.max(r.maxY,i.maxY),a.maxZ=Math.max(r.maxZ,i.maxZ),a}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},Ha=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},Ua=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}},Wa=It(`bvh`),Ga=1073741824,Ka=1073741826,qa=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),Ja=1073741824;function Ya(e,t){if(e>=Ja)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${Ja}`);return e}var Xa=null;function Za(e){Xa=e}var Qa={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},$a=Qa.FLOATS_PER_TRIANGLE,eo=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),to=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},no=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=eo(this.triangles),n=Qa.POSITION_A_OFFSET,r=Qa.POSITION_B_OFFSET,i=Qa.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*$a,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){return this.totalTriangles=e.byteLength/($a*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),this.useWorker&&Xa&&typeof Worker<`u`?new Promise((r,i)=>{let a=a=>{let o=this.totalTriangles,s=typeof SharedArrayBuffer<`u`;Wa.debug(`SharedArrayBuffer ${s?`enabled`:`unavailable (using transfer fallback)`}`);let c=s?new SharedArrayBuffer(o*$a*4):null;a.onmessage=e=>{let{bvhData:t,triangles:o,originalToBvh:s,error:l,progress:u,treeletStats:d}=e.data;if(l){a.terminate(),i(Error(l));return}if(u!==void 0&&n){n(u);return}d&&(this.splitStats=d),a.terminate(),r({bvhData:t,bvhRoot:!0,reorderedTriangles:c?new Float32Array(c):o,originalToBvh:s||null})},a.onerror=e=>{a.terminate(),i(e)};let l=e.buffer,u={triangleData:l,triangleByteOffset:e.byteOffset,triangleByteLength:e.byteLength,triangleCount:o,depth:t,reportProgress:!!n,sharedReorderBuffer:c,treeletOptimization:{enabled:this.enableTreeletOptimization,size:this.treeletSize,passes:this.treeletOptimizationPasses,minImprovement:this.treeletMinImprovement},reinsertionOptimization:{enabled:this.enableReinsertionOptimization,batchSizeRatio:this.reinsertionBatchSizeRatio,maxIterations:this.reinsertionMaxIterations}};a.postMessage(u,[l])};try{a(Xa())}catch(i){Wa.warn(`worker creation failed, falling back to synchronous build:`,i),r(this._buildSyncAndFlatten(e,t,n))}}):new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(e,t=30,n=null,r=null){let i=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=e,this.totalTriangles=e.byteLength/($a*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let a=this.totalTriangles,o=performance.now();this.centroids=new Float32Array(a*3),this.bMin=new Float32Array(a*3),this.bMax=new Float32Array(a*3),this.indices=new Uint32Array(a),this.mortonCodes=new Uint32Array(a),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-o,this.sortTrianglesByMortonCode();let s=performance.now(),c=this.buildNodeRecursive(0,a,t,n);if(this.splitStats.sahBuildTime=performance.now()-s,this.enableTreeletOptimization&&this.totalTriangles>1e3){let e=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,t=new Va(this.traversalCost,this.intersectionCost);t.setTreeletSize(e),t.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let i=n?t=>{n(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{t.optimizeBVH(c,i)}catch(t){Wa.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=t.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let i=performance.now()-r;this.splitStats.treeletOptimizationTime=i;let a=t.getStatistics();this.splitStats.treeletsProcessed=a.treeletsProcessed,this.splitStats.treeletsImproved=a.treeletsImproved,this.splitStats.averageSAHImprovement=a.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new Ua(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=n?e=>{n(e)}:null;try{e.optimizeBVH(c,t)}catch(e){Wa.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let l=performance.now();this.applySAOrdering(c),this.splitStats.saOrderTime=performance.now()-l;let u=performance.now(),d=this.triangles,f=r||new d.constructor(a*$a);for(let e=0;e<a;e++){let t=this.indices[e]*$a,n=e*$a;f.set(d.subarray(t,t+$a),n)}this.reorderedTriangleData=f;let p=new Uint32Array(a);for(let e=0;e<a;e++)p[this.indices[e]]=e;this.originalToBvhMap=p,this.splitStats.reorderTime=performance.now()-u,this.splitStats.totalBuildTime=performance.now()-i;let m=this.splitStats.totalBuildTime,h=this.splitStats;return Wa.debug(`${Y.n(a)} tris → ${Y.n(this.totalNodes)} nodes in ${Y.ms(m)} | SAH ${h.sahSplits} objMed ${h.objectMedianSplits} spatMed ${h.spatialMedianSplits} failed ${h.failedSplits}`+(h.treeletsProcessed?` | treelets ${h.treeletsImproved}/${h.treeletsProcessed} improved`:``)+(h.reinsertionsApplied?` | reinsertions ${h.reinsertionsApplied}`:``)),n&&n(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,c}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new to;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new to;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}Ya(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=qa(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=Ga}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}Ya(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=qa(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=Ka,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=Ga}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;Ya(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=qa(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<Ga&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}},ro={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11},io=ro.FLOATS_PER_TRIANGLE,ao=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),oo=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),so=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):oo(e)}},co=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,lo=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,uo=(e,t)=>e.chunked?e.chunked.baseOf(t):t*mo,fo=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):ao(e),u:t?e:oo(e)}};function po(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}var mo=16,ho=1073741824,go=1073741825,_o=1e-12;function vo(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=_o*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,ee=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>ee&&(ee=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=ee}var yo=class{constructor(){this._bounds=null,this._boundsNodeCount=0}updateTrianglePositions(e,t,n){let r=n.length,i=fo(e);for(let e=0;e<r;e++){let r=n[e],a=i.chunked?i.f.chunkFor(e):i.f,o=i.chunked?i.u.chunkFor(e):i.u,s=i.chunked?i.chunked.baseOf(e):e*io,c=r*9,l=t[c],u=t[c+1],d=t[c+2],f=t[c+3],p=t[c+4],m=t[c+5],h=t[c+6],g=t[c+7],_=t[c+8];a[s+ro.POSITION_A_OFFSET]=l,a[s+ro.POSITION_A_OFFSET+1]=u,a[s+ro.POSITION_A_OFFSET+2]=d,a[s+ro.POSITION_B_OFFSET]=f,a[s+ro.POSITION_B_OFFSET+1]=p,a[s+ro.POSITION_B_OFFSET+2]=m,a[s+ro.POSITION_C_OFFSET]=h,a[s+ro.POSITION_C_OFFSET+1]=g,a[s+ro.POSITION_C_OFFSET+2]=_;let v=f-l,y=p-u,b=m-d,x=h-l,S=g-u,C=_-d,w=po(y*C-b*S,b*x-v*C,v*S-y*x);o[s+ro.NORMAL_A_PACKED_OFFSET]=w,o[s+ro.NORMAL_B_PACKED_OFFSET]=w,o[s+ro.NORMAL_C_PACKED_OFFSET]=w}}refitRange(e,t,n,r){let i=fo(t);r>this._boundsNodeCount&&(this._bounds=new Float32Array(r*6),this._boundsNodeCount=r);let a=this._bounds,o=n+r,s=so(e);for(let e=o-1;e>=n;e--){let t=co(s,e),r=lo(s,e),o=uo(s,e),c=(e-n)*6;if(r[o+3]===ho){let e=r[o],t=r[o+1],n=1/0,s=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0;for(let r=0;r<t;r++){let t=e+r,a=i.chunked?i.f.chunkFor(t):i.f,o=i.chunked?i.chunked.baseOf(t):t*io,c=a[o+ro.POSITION_A_OFFSET],p=a[o+ro.POSITION_A_OFFSET+1],m=a[o+ro.POSITION_A_OFFSET+2],h=a[o+ro.POSITION_B_OFFSET],g=a[o+ro.POSITION_B_OFFSET+1],_=a[o+ro.POSITION_B_OFFSET+2],v=a[o+ro.POSITION_C_OFFSET],y=a[o+ro.POSITION_C_OFFSET+1],b=a[o+ro.POSITION_C_OFFSET+2];n=Math.min(n,c,h,v),s=Math.min(s,p,g,y),l=Math.min(l,m,_,b),u=Math.max(u,c,h,v),d=Math.max(d,p,g,y),f=Math.max(f,m,_,b)}a[c]=n,a[c+1]=s,a[c+2]=l,a[c+3]=u,a[c+4]=d,a[c+5]=f}else{let e=r[o+3],i=r[o+7],s=(e-n)*6,l=(i-n)*6,u=a[s],d=a[s+1],f=a[s+2],p=a[s+3],m=a[s+4],h=a[s+5],g=a[l],_=a[l+1],v=a[l+2],y=a[l+3],b=a[l+4],x=a[l+5];t[o]=u,t[o+1]=d,t[o+2]=f,t[o+4]=p,t[o+5]=m,t[o+6]=h,t[o+8]=g,t[o+9]=_,t[o+10]=v,t[o+12]=y,t[o+13]=b,t[o+14]=x,a[c]=Math.min(u,g),a[c+1]=Math.min(d,_),a[c+2]=Math.min(f,v),a[c+3]=Math.max(p,y),a[c+4]=Math.max(m,b),a[c+5]=Math.max(h,x)}}}refit(e,t,n){let r=fo(t);n!==this._boundsNodeCount&&(this._bounds=new Float32Array(n*6),this._boundsNodeCount=n);let i=this._bounds,a=so(e);for(let e=n-1;e>=0;e--){let t=co(a,e),n=lo(a,e),o=uo(a,e),s=e*6,c=n[o+3];if(c===ho){let e=n[o],t=n[o+1],a=1/0,c=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0;for(let n=0;n<t;n++){let t=e+n,i=r.chunked?r.f.chunkFor(t):r.f,o=r.chunked?r.chunked.baseOf(t):t*io,s=i[o+ro.POSITION_A_OFFSET],p=i[o+ro.POSITION_A_OFFSET+1],m=i[o+ro.POSITION_A_OFFSET+2],h=i[o+ro.POSITION_B_OFFSET],g=i[o+ro.POSITION_B_OFFSET+1],_=i[o+ro.POSITION_B_OFFSET+2],v=i[o+ro.POSITION_C_OFFSET],y=i[o+ro.POSITION_C_OFFSET+1],b=i[o+ro.POSITION_C_OFFSET+2];a=Math.min(a,s,h,v),c=Math.min(c,p,g,y),l=Math.min(l,m,_,b),u=Math.max(u,s,h,v),d=Math.max(d,p,g,y),f=Math.max(f,m,_,b)}i[s]=a,i[s+1]=c,i[s+2]=l,i[s+3]=u,i[s+4]=d,i[s+5]=f}else if(c===go)vo(t,o,i,n[o]*6,i,s);else{let e=n[o+3],r=n[o+7],a=e*6,c=r*6,l=i[a],u=i[a+1],d=i[a+2],f=i[a+3],p=i[a+4],m=i[a+5],h=i[c],g=i[c+1],_=i[c+2],v=i[c+3],y=i[c+4],b=i[c+5];t[o]=l,t[o+1]=u,t[o+2]=d,t[o+4]=f,t[o+5]=p,t[o+6]=m,t[o+8]=h,t[o+9]=g,t[o+10]=_,t[o+12]=v,t[o+13]=y,t[o+14]=b,i[s]=Math.min(l,h),i[s+1]=Math.min(u,g),i[s+2]=Math.min(d,_),i[s+3]=Math.max(f,v),i[s+4]=Math.max(p,y),i[s+5]=Math.max(m,b)}}}},bo="var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}function b(e){e&&e in r&&(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e])}const x=y(`bvh`),S=1073741824,C=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),w=1073741824;function T(e,t){if(e>=w)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${w}`);return e}const E={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},D=E.FLOATS_PER_TRIANGLE,O=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var k=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},A=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=O(this.triangles),n=E.POSITION_A_OFFSET,r=E.POSITION_B_OFFSET,i=E.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*D,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(D*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),!(this.useWorker&&null))return new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(D*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){x.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){x.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*D);for(let e=0;e<s;e++){let t=this.indices[e]*D,n=e*D;m.set(p.subarray(t,t+D),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return x.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new k;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new k;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}T(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=C(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=S}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}T(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=C(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=S}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;T(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=C(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<S&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const j=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?M(t):n===`assemble`?N(t):P(t)};function M(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u,treeletOptimization:d}=e;try{let e=new A;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let p=performance.now(),m=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-m,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let h=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,f);e.splitStats.sahBuildTime=performance.now()-h,e.applySAOrdering(g);let v=performance.now(),{flatData:y,frontierMap:b,nodeCount:x}=e.flattenBVHWithFrontier(g),S=performance.now()-v,C=performance.now()-p;j.debug(`phase 1 ${_.ms(C)} (init ${_.ms(e.splitStats.initTime)} · morton ${_.ms(e.splitStats.mortonSortTime)} · SAH ${_.ms(e.splitStats.sahBuildTime)} · flatten ${_.ms(S)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:y,topNodeCount:x,frontierTasks:e.frontierTasks,frontierMap:b,splitStats:e.splitStats},[y.buffer])}catch(e){j.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function N(e){let{topFlatData:t,topNodeCount:n,frontierMap:r,subtreeResults:i,sharedTriangleData:a,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c}=e;try{let e=performance.now(),l=new A().assembleParallelBVH(t,n,r,i),u=new Uint32Array(o),d=new Uint32Array(a),f=new Uint32Array(s);for(let e=0;e<c;e++){let t=u[e]*20,n=e*20;f.set(d.subarray(t,t+20),n)}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[u[e]]=e;let m=performance.now()-e;j.debug(`phase 3 assemble + reorder ${_.ms(m)} (${_.mb(l.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:l,originalToBvh:p,triangleCount:c},[l.buffer,p.buffer])}catch(e){j.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function P(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,treeletOptimization:o,reinsertionOptimization:s,sharedReorderBuffer:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f}=e,p=new A;l!==void 0&&(p.maxLeafSize=l),u!==void 0&&(p.numBins=u),d!==void 0&&(p.maxBins=d),f!==void 0&&(p.minBins=f);try{o&&p.setTreeletConfig(o),s&&p.setReinsertionConfig(s);let e=a?e=>{self.postMessage({progress:e})}:null,l=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),u=c?new Uint32Array(c):null,d=p.buildSync(l,i,e,u),f=performance.now(),m=p.flattenBVH(d),h=performance.now()-f;j.debug(`flatten ${_.ms(h)} (${_.mb(m.byteLength)})`);let g=p.originalToBvhMap||null;if(c){let e=[m.buffer];g&&e.push(g.buffer),self.postMessage({bvhData:m,originalToBvh:g,triangleCount:l.length/20,treeletStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/80,n=[m.buffer,e.buffer];g&&n.push(g.buffer),self.postMessage({bvhData:m,triangles:e,originalToBvh:g,triangleCount:t,treeletStats:p.splitStats},n)}}catch(e){j.error(`build failed:`,e),self.postMessage({error:e.message})}}",xo=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,bo],{type:`text/javascript;charset=utf-8`});function So(e){let t;try{if(t=xo&&(self.URL||self.webkitURL).createObjectURL(xo),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(bo),{type:`module`,name:e?.name})}}var Co="var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}const b=y(`bvh`),x=1073741824,S=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),C=1073741824;function w(e,t){if(e>=C)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${C}`);return e}const T={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},E=T.FLOATS_PER_TRIANGLE,D=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var O=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},k=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=D(this.triangles),n=T.POSITION_A_OFFSET,r=T.POSITION_B_OFFSET,i=T.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*E,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(E*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),!(this.useWorker&&null))return new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(E*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){b.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){b.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*E);for(let e=0;e<s;e++){let t=this.indices[e]*E,n=e*E;m.set(p.subarray(t,t+E),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return b.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new O;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new O;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}w(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=S(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=x}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}w(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=S(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=x}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;w(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=S(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<x&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:r,sharedTriangleData:i,sharedCentroids:a,sharedBMin:o,sharedBMax:s,sharedIndices:c,triangleCount:l,maxLeafSize:u,numBins:d,maxBins:f,minBins:p,treeletConfig:m,reinsertionConfig:h,reportProgress:g}=t.data;for(let t=0;t<r.length;t++){let _=r[t];try{let t=new k;t.maxLeafSize=u,t.numBins=d,t.maxBins=f,t.minBins=p,t.triangles=new Float32Array(i),t.centroids=new Float32Array(a),t.bMin=new Float32Array(o),t.bMax=new Float32Array(s),t.indices=new Uint32Array(c),t.totalTriangles=l,t.totalNodes=0,t.processedTriangles=0,t.lastProgressUpdate=performance.now(),t.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let r=g?e=>{self.postMessage({type:`progress`,taskId:_.taskId,progress:e})}:null,v=performance.now(),y=t.buildNodeRecursive(_.start,_.end,_.depth,r,_.preMinX,_.preMinY,_.preMinZ,_.preMaxX,_.preMaxY,_.preMaxZ);if(m&&m.enabled&&_.end-_.start>1e3){let n=_.end-_.start>5e4,r=n?3:m.size||5,i=n?10:20,a=new e(t.traversalCost,t.intersectionCost);a.setTreeletSize(r),a.setMinImprovement(m.minImprovement||.02),a.setMaxTreelets(i);let o=m.passes||1;for(let e=0;e<o;e++)try{a.optimizeBVH(y,null)}catch(t){console.error(`[BVHSubtreeWorker] Treelet pass ${e+1} error:`,t);break}}if(h&&h.enabled&&_.end-_.start>1e3){let e=new n(t.traversalCost,t.intersectionCost);h.batchSizeRatio&&e.setBatchSizeRatio(h.batchSizeRatio),h.maxIterations&&e.setMaxIterations(h.maxIterations);try{e.optimizeBVH(y,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(y);let b=t.flattenBVH(y),x=b.length/16,S=performance.now()-v;console.log(`[BVHSubtreeWorker] Task ${_.taskId}: ${(_.end-_.start).toLocaleString()} triangles, ${x} nodes, ${Math.round(S)}ms`),self.postMessage({type:`subtreeResult`,taskId:_.taskId,flatData:b,nodeCount:x},[b.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${_.taskId} error:`,e),self.postMessage({type:`error`,taskId:_.taskId,error:e.message})}}};",wo=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,Co],{type:`text/javascript;charset=utf-8`});function To(e){let t;try{if(t=wo&&(self.URL||self.webkitURL).createObjectURL(wo),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(Co),{type:`module`,name:e?.name})}}Za(()=>new So);var Eo=It(`bvh`),Do=20,Oo=5e4,ko=8;function Ao(e,t,n,r){let i=e.byteLength/(Do*4),a=Math.min(navigator.hardwareConcurrency||4,ko),o=Math.ceil(Math.log2(a*2.5+1));return Eo.debug(`parallel build ${Y.n(i)} triangles · ${a} workers · parallelDepth ${o}`),new Promise((s,c)=>{(async()=>{let c=new SharedArrayBuffer(e.byteLength);new Uint32Array(c).set(e),e=null;let l=new SharedArrayBuffer(i*3*4),u=new SharedArrayBuffer(i*3*4),d=new SharedArrayBuffer(i*3*4),f=new SharedArrayBuffer(i*4),p=new SharedArrayBuffer(i*4),m=new SharedArrayBuffer(i*Do*4),h=new So,g=null,_=[h],v={id:null},y=!1,b=()=>{v.id&&=(clearTimeout(v.id),null);for(let e of _)try{e.terminate()}catch{}},x=e=>{if(y)return;y=!0,Eo.warn(`parallel build failed (${e}), falling back to single worker`),b();let i=new ArrayBuffer(c.byteLength);new Uint32Array(i).set(new Uint32Array(c)),s(Mo(new Uint32Array(i),t,n,r))};h.onerror=e=>{x(`coordinator error: ${e.message}`)},h.onmessage=e=>{let t=e.data;if(t.error||t.type===`error`){x(t.error);return}if(t.type===`progress`&&n){n(Math.floor(t.progress*.3));return}if(t.type===`phase1Result`){g=t.splitStats,jo(t,a,c,l,u,d,f,m,i,n,h,_,b,x,s,v,r).catch(e=>x(e.message));return}if(t.type===`assembleResult`){y=!0,b();let e=new Uint32Array(m);s({bvhData:t.bvhData,bvhRoot:!0,reorderedTriangles:e,originalToBvh:t.originalToBvh||null,splitStats:g||{}});return}},n&&n(0),h.postMessage({type:`buildPhase1`,sharedTriangleData:c,sharedCentroids:l,sharedBMin:u,sharedBMax:d,sharedIndices:f,sharedMortonCodes:p,triangleCount:i,depth:t,parallelDepth:o,reportProgress:!!n,treeletOptimization:r.treeletOptimization})})().catch(e=>{Eo.warn(`parallel build setup failed:`,e),c(e)})})}async function jo(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g){let{topFlatData:_,topNodeCount:v,frontierTasks:y,frontierMap:b}=e;if(!y||y.length===0){Eo.debug(`no frontier tasks, assembling with top-level tree only`),u.postMessage({type:`assemble`,topFlatData:_,topNodeCount:v,frontierMap:[],subtreeResults:[],sharedTriangleData:n,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c},[_.buffer]);return}Eo.debug(`phase 2 distributing ${y.length} tasks across ${t} workers`);let x=[...y].sort((e,t)=>t.end-t.start-(e.end-e.start)),S=Array.from({length:Math.min(t,x.length)},()=>[]),C=Array(S.length).fill(0);for(let e of x){let t=0;for(let e=1;e<C.length;e++)C[e]<C[t]&&(t=e);S[t].push(e),C[t]+=e.end-e.start}let w=[],T=0,E=y.length,D=y.reduce((e,t)=>e+(t.end-t.start),0),O=0;h.id=setTimeout(()=>{p(`Phase 2 timeout (30s)`)},3e4);let k=()=>{clearTimeout(h.id),h.id=null,l&&l(85);let t=[];e.topFlatData&&e.topFlatData.buffer&&t.push(e.topFlatData.buffer);for(let e of w)e.flatData&&e.flatData.buffer&&t.push(e.flatData.buffer);u.postMessage({type:`assemble`,topFlatData:e.topFlatData,topNodeCount:v,frontierMap:b,subtreeResults:w,sharedTriangleData:n,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c},t)},A=S.length;for(let e=0;e<A;e++){let t=S[e];if(t.length===0)continue;let s=new To;d.push(s),s.onerror=e=>{p(`subtree worker error: ${e.message}`)},s.onmessage=e=>{let t=e.data;if(t.type===`error`){p(`subtree task ${t.taskId} error: ${t.error}`);return}if(t.type===`progress`&&l){let e=30+Math.floor(O/D*55);l(Math.min(e,85));return}if(t.type===`subtreeResult`){w.push({taskId:t.taskId,flatData:t.flatData,nodeCount:t.nodeCount});let e=y.find(e=>e.taskId===t.taskId);if(e&&(O+=e.end-e.start),T++,l){let e=30+Math.floor(O/D*55);l(Math.min(e,85))}if(T===E){for(let e of d)if(e!==u)try{e.terminate()}catch{}k()}}},s.postMessage({tasks:t,sharedTriangleData:n,sharedCentroids:r,sharedBMin:i,sharedBMax:a,sharedIndices:o,triangleCount:c,maxLeafSize:g.maxLeafSize,numBins:g.numBins,maxBins:g.maxBins,minBins:g.minBins,treeletConfig:g.treeletOptimization,reinsertionConfig:g.reinsertionOptimization,reportProgress:!!l})}}function Mo(e,t,n,r){return new Promise((i,a)=>{(async()=>{let o=new So,s=e.byteLength/(Do*4),c=typeof SharedArrayBuffer<`u`?new SharedArrayBuffer(s*Do*4):null;o.onmessage=e=>{let{bvhData:t,triangles:r,originalToBvh:s,error:l,progress:u,treeletStats:d}=e.data;if(l){o.terminate(),a(Error(l));return}if(u!==void 0&&n){n(u);return}o.terminate(),i({bvhData:t,bvhRoot:!0,reorderedTriangles:c?new Uint32Array(c):r,originalToBvh:s||null,splitStats:d||{}})},o.onerror=e=>{o.terminate(),a(e)};let l=e.buffer;o.postMessage({triangleData:l,triangleByteOffset:e.byteOffset,triangleByteLength:e.byteLength,triangleCount:s,depth:t,reportProgress:!!n,sharedReorderBuffer:c,treeletOptimization:r.treeletOptimization,reinsertionOptimization:r.reinsertionOptimization},[l])})().catch(e=>{Eo.warn(`single worker fallback failed:`,e),a(e)})})}function No(e){return typeof Worker<`u`&&typeof SharedArrayBuffer<`u`&&e>=Oo}var Po=Float64Array.from([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function Fo(e,t){return e[t]*(e[t+5]*e[t+10]-e[t+6]*e[t+9])-e[t+4]*(e[t+1]*e[t+10]-e[t+2]*e[t+9])+e[t+8]*(e[t+1]*e[t+6]-e[t+2]*e[t+5])}function Io(e,t,n){let r=Fo(e,t);if(!Number.isFinite(r)||Math.abs(r)<1e-20)return n.set(Po),n;let i=1/r;return n[0]=(e[t+5]*e[t+10]-e[t+6]*e[t+9])*i,n[1]=(e[t+2]*e[t+9]-e[t+1]*e[t+10])*i,n[2]=(e[t+1]*e[t+6]-e[t+2]*e[t+5])*i,n[3]=0,n[4]=(e[t+6]*e[t+8]-e[t+4]*e[t+10])*i,n[5]=(e[t]*e[t+10]-e[t+2]*e[t+8])*i,n[6]=(e[t+2]*e[t+4]-e[t]*e[t+6])*i,n[7]=0,n[8]=(e[t+4]*e[t+9]-e[t+5]*e[t+8])*i,n[9]=(e[t+1]*e[t+8]-e[t]*e[t+9])*i,n[10]=(e[t]*e[t+5]-e[t+1]*e[t+4])*i,n[11]=0,n[12]=-(n[0]*e[t+12]+n[4]*e[t+13]+n[8]*e[t+14]),n[13]=-(n[1]*e[t+12]+n[5]*e[t+13]+n[9]*e[t+14]),n[14]=-(n[2]*e[t+12]+n[6]*e[t+13]+n[10]*e[t+14]),n[15]=1,n}function Lo(e,t,n,r){for(let i=0;i<4;i++){let a=n+i*4,o=t[a],s=t[a+1],c=t[a+2],l=t[a+3];for(let t=0;t<4;t++)r[i*4+t]=e[t]*o+e[4+t]*s+e[8+t]*c+e[12+t]*l}return r}function Ro(e){for(let t=0;t<16;t++)if(e[t]!==Po[t])return!1;return!0}function zo(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=0;i<8;i++){let a=e[t+(i&1?3:0)],f=e[t+(i&2?4:1)],p=e[t+(i&4?5:2)],m=n[r]*a+n[r+4]*f+n[r+8]*p+n[r+12],h=n[r+1]*a+n[r+5]*f+n[r+9]*p+n[r+13],g=n[r+2]*a+n[r+6]*f+n[r+10]*p+n[r+14];m<o&&(o=m),m>l&&(l=m),h<s&&(s=h),h>u&&(u=h),g<c&&(c=g),g>d&&(d=g)}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}function Bo(e,t){for(let n=0;n<16;n++)if(e[t+n]!==Po[n])return!1;return!0}var Vo=class{constructor(){this.count=0,this.templateCount=0,this.totalBLASNodes=0,this.tlasNodeCount=0,this.allocate(0)}allocate(e,t=e,n=null,r=null){this.count=e,this.templateCount=t,this.isSet=new Uint8Array(e),this.sourceMesh=r&&r.length>=e?r:new Int32Array(e),this.tlasLeafIndex=new Int32Array(e).fill(-1),this.visible=new Uint8Array(e).fill(1),this.flipWinding=new Uint8Array(e),this.tplBakeInverse=null,n&&n.length>=e*16?(this.world=n,this.worldPooled=!0):(this.world=new Float32Array(e*16),this.worldPooled=!1),this.tplTriOffset=new Int32Array(t),this.tplTriCount=new Int32Array(t),this.tplExpandedStart=new Int32Array(t),this.tplNodeCount=new Int32Array(t),this.tplBlasOffset=new Int32Array(t),this.tplOwner=new Int32Array(t).fill(-1),this.tplObjectAABB=new Float32Array(t*6),this._placementRuns=null,this.originalToBvhMap=new Map,this.bvhToOriginal=new Map,this.blasData=new Map}_place(e,t,n,r){this.isSet[e]=1,this.sourceMesh[e]=t;let i=e*16;if(!n){this.world.set(Po,i),this.flipWinding[e]=0;return}if(n!==this.world)for(let e=0;e<16;e++)this.world[i+e]=n[r+e];this.flipWinding[e]=+(Fo(this.world,i)<0)}setEntry({meshIndex:e,blasNodeCount:t,triOffset:n,triCount:r,originalToBvhMap:i,bvhData:a,matrixWorld:o=null,matrixOffset:s=0,expandedStart:c=null,sourceMesh:l=null}){let u=l??e;this._place(e,u,o,s),this.tplTriOffset[u]=n,this.tplTriCount[u]=r,this.tplExpandedStart[u]=c??n,this.tplNodeCount[u]=t,this.tplOwner[u]=e,i&&this.originalToBvhMap.set(u,i),a&&this.blasData.set(u,a)}setAlias(e,t,n=null,r=null,i=null,a=0){if(!this.isSet[t])throw Error(`InstanceTable.setAlias: owner ${t} not built`);let o=i??e,s=this.sourceMesh[t];this._place(e,o,n,a),o!==s&&(this.tplTriOffset[o]=this.tplTriOffset[s],this.tplTriCount[o]=this.tplTriCount[s],this.tplNodeCount[o]=this.tplNodeCount[s],this.tplExpandedStart[o]=r??this.tplExpandedStart[s],this.tplOwner[o]=this.tplOwner[s])}get setCount(){let e=0;for(let t=0;t<this.count;t++)e+=this.isSet[t];return e}setPlacementMatrix(e,t,n=0){this._place(e,this.sourceMesh[e],t,n)}placementRunOf(e){if(!this._placementRuns){let e=this._placementRuns=new Map;for(let t=0;t<this.count;t++){let n=this.sourceMesh[t],r=e.get(n);r?r.count++:e.set(n,{start:t,count:1})}}return this._placementRuns.get(e)??null}isOwner(e){return this.tplOwner[this.sourceMesh[e]]===e}triOffsetOf(e){return this.tplTriOffset[this.sourceMesh[e]]}triCountOf(e){return this.tplTriCount[this.sourceMesh[e]]}expandedStartOf(e){return this.tplExpandedStart[this.sourceMesh[e]]}blasOffsetOf(e){return this.tplBlasOffset[this.sourceMesh[e]]}blasNodeCountOf(e){return this.tplNodeCount[this.sourceMesh[e]]}setBlasNodeCount(e,t){this.tplNodeCount[this.sourceMesh[e]]=t}setBvhToOriginal(e,t){this.bvhToOriginal.set(this.sourceMesh[e],t)}bvhToOriginalOf(e){let t=this.sourceMesh[e],n=this.bvhToOriginal.get(t);if(n)return n;let r=this.tplOwner[t];return(r>=0?this.bvhToOriginal.get(this.sourceMesh[r]):null)||null}matrixWorldOf(e){return this.world.subarray(e*16,e*16+16)}matrixInverseOf(e){return Io(this.world,e*16,new Float64Array(16))}writeWorldAABB(e,t,n){if(!this.isSet[e]){for(let e=0;e<6;e++)t[n+e]=0;return}zo(this.tplObjectAABB,this.sourceMesh[e]*6,this.world,e*16,t,n)}writeWorldAABBs(e){let t=this.tplObjectAABB,n=this.world,r=this.sourceMesh,i=this.isSet;for(let a=0;a<this.count;a++){let o=a*6;if(!i[a]){e[o]=0,e[o+1]=0,e[o+2]=0,e[o+3]=0,e[o+4]=0,e[o+5]=0;continue}zo(t,r[a]*6,n,a*16,e,o)}}entryAt(e){if(!this.isSet[e])return null;let t=this.sourceMesh[e],n=this.tplOwner[t];return{meshIndex:e,blasOffset:this.tplBlasOffset[t],blasNodeCount:this.tplNodeCount[t],triOffset:this.tplTriOffset[t],triCount:this.tplTriCount[t],expandedStart:this.tplExpandedStart[t],sourceMesh:t,sharedFrom:n===e?null:n,matrixWorld:this.matrixWorldOf(e),matrixInverse:this.matrixInverseOf(e),flipWinding:!!this.flipWinding[e],bvhToOriginal:this.bvhToOriginal.get(t)||null,visible:!!this.visible[e],tlasLeafIndex:this.tlasLeafIndex[e]}}setVisibility(e,t){this.isSet[e]&&(this.visible[e]=+!!t)}computeAABBs(e){for(let t=0;t<this.templateCount;t++){if(this.tplOwner[t]<0)continue;let n=this.blasData.get(t);n&&this._readRootAABB(n,t,e,this.tplObjectAABB,t*6)}for(let e=0;e<this.templateCount;e++){let t=this.tplOwner[e];if(t<0||this.blasData.has(e))continue;let n=this.sourceMesh[t];n!==e&&this.tplObjectAABB.copyWithin(e*6,n*6,n*6+6)}}recomputeAABB(e,t,n){let r=this.sourceMesh[e],i=this.tplBlasOffset[r],a=t.chunks?t.chunkFor(i).subarray(t.baseOf(i),t.baseOf(i)+16):t.subarray(i*16,i*16+16);this._readRootAABB(a,r,n,this.tplObjectAABB,r*6)}_readRootAABB(e,t,n,r,i){if(!e||rt(e)[3]===nt.TRIANGLE_LEAF){this._computeAABBFromTriangles(t,n,r,i);return}r[i]=Math.min(e[0],e[8]),r[i+1]=Math.min(e[1],e[9]),r[i+2]=Math.min(e[2],e[10]),r[i+3]=Math.max(e[4],e[12]),r[i+4]=Math.max(e[5],e[13]),r[i+5]=Math.max(e[6],e[14])}_computeAABBFromTriangles(e,t,n,r){let i=K.FLOATS_PER_TRIANGLE,a=t&&t.chunks?t.viewAs(Float32Array):null,o=a?null:t instanceof Float32Array?t:new Float32Array(t.buffer,t.byteOffset,t.length),s=1/0,c=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0,p=this.tplTriOffset[e],m=this.tplTriCount[e];for(let e=0;e<m;e++){let t=p+e,n=a?a.chunkFor(t):o,r=a?a.baseOf(t):t*i;for(let e=0;e<=8;e+=4){let t=n[r+e],i=n[r+e+1],a=n[r+e+2];t<s&&(s=t),i<c&&(c=i),a<l&&(l=a),t>u&&(u=t),i>d&&(d=i),a>f&&(f=a)}}n[r]=s,n[r+1]=c,n[r+2]=l,n[r+3]=u,n[r+4]=d,n[r+5]=f}assignOffsets(e){this.tlasNodeCount=e;let t=e;for(let e=0;e<this.templateCount;e++){let n=this.tplOwner[e];n<0||this.sourceMesh[n]!==e||(this.tplBlasOffset[e]=t,t+=this.tplNodeCount[e])}for(let e=0;e<this.templateCount;e++){let t=this.tplOwner[e];if(t<0)continue;let n=this.sourceMesh[t];n!==e&&(this.tplBlasOffset[e]=this.tplBlasOffset[n])}this.totalBLASNodes=t-e,it(t,`combined TLAS + BLAS node count`)}get totalNodeCount(){return this.tlasNodeCount+this.totalBLASNodes}clear(){this.allocate(0),this.totalBLASNodes=0,this.tlasNodeCount=0}},Ho=16,Uo=32,Wo=e=>e<Uo?e:Uo,Go=8,Ko=64,qo=new Float64Array(16),Jo=class e{constructor(){this._flatBuffer=null,this._flatBufferCapacity=0,this._binCounts=new Int32Array(Uo*3),this._binBounds=new Float64Array(Uo*6*3),this._binSuffix=new Float64Array(Uo),this._binSuffixCount=new Int32Array(Uo),this._order=null,this._stackI=null,this._stackB=null,this._stackFrames=0,this._sortScratch=[],this._suffix=null,this._bounds=new Float64Array(12),this._extent=new Float64Array(3),this._cMin=new Float64Array(3)}static nodeCountFor(e){return e>0?e*2-1:0}releaseFlattenBuffer(){this._flatBuffer=null,this._flatBufferCapacity=0}build(t){let n=new Float64Array(t.count*6);t.writeWorldAABBs(n);let r=this.buildStructure(n,t.count);return e.fillLeaves(r.data,r.nodeCount,t),r}buildStructure(t,n){let r=e.nodeCountFor(n);if(n===0)return{data:new Float32Array,nodeCount:0};it(r,`TLAS node count`);let i=r*Ho;i>this._flatBufferCapacity&&(this._flatBuffer=new Float32Array(i),this._flatBufferCapacity=i);let a=this._flatBuffer,o=rt(a);(!this._order||this._order.length<n)&&(this._order=new Int32Array(n));let s=this._order;for(let e=0;e<n;e++)s[e]=e;this._ensureStack(Ko);let c=0,l=0,u=0,d=n,f=this._bounds;this._rangeBounds(t,s,u,d,f,0);let p=f[0],m=f[1],h=f[2],g=f[3],_=f[4],v=f[5];for(;;){if(d-u===1){let e=l*Ho;o[e]=0,o[e+1]=s[u],a[e+2]=0,o[e+3]=nt.BLAS_POINTER_LEAF}else{let e=this._partition(t,s,u,d,p,m,h,g,_,v),n=e-u,r=l+1,i=r+(n*2-1),y=l*Ho;a[y]=f[0],a[y+1]=f[1],a[y+2]=f[2],o[y+3]=r,a[y+4]=f[3],a[y+5]=f[4],a[y+6]=f[5],o[y+7]=i,a[y+8]=f[6],a[y+9]=f[7],a[y+10]=f[8],a[y+11]=0,a[y+12]=f[9],a[y+13]=f[10],a[y+14]=f[11],a[y+15]=0;let b=n<=d-e,x=b?0:6,S=b?6:0;c=this._push(c,b?i:r,b?e:u,b?d:e,f,S),l=b?r:i,b?d=e:u=e,p=f[x],m=f[x+1],h=f[x+2],g=f[x+3],_=f[x+4],v=f[x+5];continue}if(c===0)break;c--;let e=c*3,n=c*6;l=this._stackI[e],u=this._stackI[e+1],d=this._stackI[e+2],p=this._stackB[n],m=this._stackB[n+1],h=this._stackB[n+2],g=this._stackB[n+3],_=this._stackB[n+4],v=this._stackB[n+5]}return{data:a.subarray(0,i),nodeCount:r}}_push(e,t,n,r,i,a){e>=this._stackFrames&&this._ensureStack(this._stackFrames*2);let o=e*3,s=e*6;this._stackI[o]=t,this._stackI[o+1]=n,this._stackI[o+2]=r;for(let e=0;e<6;e++)this._stackB[s+e]=i[a+e];return e+1}_ensureStack(e){if(this._stackFrames>=e)return;let t=new Int32Array(e*3),n=new Float64Array(e*6);this._stackI&&(t.set(this._stackI),n.set(this._stackB)),this._stackI=t,this._stackB=n,this._stackFrames=e}static fillLeaves(t,n,r){let i=r.world,a=r.sourceMesh,o=r.tplBlasOffset,s=r.visible,c=r.tlasLeafIndex,l=rt(t);for(let r=0;r<n;r++){let n=r*Ho;if(l[n+3]!==nt.BLAS_POINTER_LEAF)continue;let u=l[n+1]&tt;l[n]=o[a[u]],t[n+2]=+!!s[u],e.writeLeafMatrix(t,l,n,i,u),c[u]=r}}static writeLeafMatrix(e,t,n,r,i){let a=qo;Io(r,i*16,a),e[n+4]=a[0],e[n+5]=a[4],e[n+6]=a[8],e[n+7]=a[12],e[n+8]=a[1],e[n+9]=a[5],e[n+10]=a[9],e[n+11]=a[13],e[n+12]=a[2],e[n+13]=a[6],e[n+14]=a[10],e[n+15]=a[14],t[n+1]=(i|(Bo(r,i*16)?et:0))>>>0}_partition(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=0;if(u===2)d=n+1;else if(u<=Go)d=n+(u>>1),this._insertionSortRange(e,t,n,r,this._widestCentroidAxis(e,t,n,r));else{if(d=this._binnedSplit(e,t,n,r,i,a,o,s,c,l),d>n&&d<r)return d;if(d=this._sweepSplit(e,t,n,r,i,a,o,s,c,l),!(d>n&&d<r)){let f=s-i,p=c-a,m=l-o,h=p>f&&p>m?1:m>f?2:0;this._sortRange(e,t,n,r,h),d=n+(u>>1)}}let f=this._bounds;return this._rangeBounds(e,t,n,d,f,0),this._rangeBounds(e,t,d,r,f,6),d}_binnedSplit(e,t,n,r,i,a,o,s,c,l){let u=this._surfaceArea(i,a,o,s,c,l);if(!(u>0)||!isFinite(u))return n;let d=1/0,f=1/0,p=1/0,m=-1/0,h=-1/0,g=-1/0;for(let i=n;i<r;i++){let n=t[i]*6,r=(e[n]+e[n+3])*.5,a=(e[n+1]+e[n+4])*.5,o=(e[n+2]+e[n+5])*.5;r<d&&(d=r),r>m&&(m=r),a<f&&(f=a),a>h&&(h=a),o<p&&(p=o),o>g&&(g=o)}let _=this._extent,v=this._cMin;_[0]=m-d,_[1]=h-f,_[2]=g-p,v[0]=d,v[1]=f,v[2]=p;let y=1/0,b=-1,x=-1,S=this._binCounts,C=this._binBounds,w=_[0]>1e-12,T=_[1]>1e-12,E=_[2]>1e-12;if(!w&&!T&&!E)return n;let D=Wo(r-n),O=w?D/_[0]:0,k=T?D/_[1]:0,A=E?D/_[2]:0;S.fill(0,0,D*3);for(let e=0;e<D*3;e++){let t=e*6;C[t]=C[t+1]=C[t+2]=1/0,C[t+3]=C[t+4]=C[t+5]=-1/0}for(let i=n;i<r;i++){let n=t[i]*6,r=e[n],a=e[n+1],o=e[n+2],s=e[n+3],c=e[n+4],l=e[n+5];for(let e=0;e<3;e++){let t=e===0?O:e===1?k:A;if(t===0)continue;let n=((e===0?(r+s)*.5:e===1?(a+c)*.5:(o+l)*.5)-v[e])*t|0;n<0?n=0:n>=D&&(n=D-1),n+=e*D,S[n]++;let i=n*6;r<C[i]&&(C[i]=r),a<C[i+1]&&(C[i+1]=a),o<C[i+2]&&(C[i+2]=o),s>C[i+3]&&(C[i+3]=s),c>C[i+4]&&(C[i+4]=c),l>C[i+5]&&(C[i+5]=l)}}for(let e=0;e<3;e++){if(!(_[e]>1e-12))continue;let t=e*D,n=this._binSuffix,r=this._binSuffixCount,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0,d=0;for(let e=D-1;e>=1;e--){let u=(t+e)*6;C[u]<i&&(i=C[u]),C[u+1]<a&&(a=C[u+1]),C[u+2]<o&&(o=C[u+2]),C[u+3]>s&&(s=C[u+3]),C[u+4]>c&&(c=C[u+4]),C[u+5]>l&&(l=C[u+5]),d+=S[t+e],n[e]=d?this._surfaceArea(i,a,o,s,c,l):0,r[e]=d}let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,v=-1/0,w=0;for(let i=1;i<D;i++){let a=(t+i-1)*6;if(C[a]<f&&(f=C[a]),C[a+1]<p&&(p=C[a+1]),C[a+2]<m&&(m=C[a+2]),C[a+3]>h&&(h=C[a+3]),C[a+4]>g&&(g=C[a+4]),C[a+5]>v&&(v=C[a+5]),w+=S[t+i-1],w===0||r[i]===0)continue;let o=1+(this._surfaceArea(f,p,m,h,g,v)*w+n[i]*r[i])/u;o<y&&(y=o,b=e,x=i)}}if(b<0)return n;let j=D/_[b],M=v[b],N=this._bounds;N[0]=N[1]=N[2]=N[6]=N[7]=N[8]=1/0,N[3]=N[4]=N[5]=N[9]=N[10]=N[11]=-1/0;let P=n,F=r-1;for(;P<=F;){let n=t[P]*6,r=((e[n+b]+e[n+3+b])*.5-M)*j|0;r<0?r=0:r>=D&&(r=D-1);let i=r<x?0:6;if(e[n]<N[i]&&(N[i]=e[n]),e[n+1]<N[i+1]&&(N[i+1]=e[n+1]),e[n+2]<N[i+2]&&(N[i+2]=e[n+2]),e[n+3]>N[i+3]&&(N[i+3]=e[n+3]),e[n+4]>N[i+4]&&(N[i+4]=e[n+4]),e[n+5]>N[i+5]&&(N[i+5]=e[n+5]),i===0)P++;else{let e=t[P];t[P]=t[F],t[F]=e,F--}}return P}_sweepSplit(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=this._surfaceArea(i,a,o,s,c,l);if(!(d>0)||!isFinite(d))return n;let f=this._suffixBuffer(u),p=1/0,m=-1,h=-1;for(let i=0;i<3;i++){this._sortRange(e,t,n,r,i);let a=1/0,o=1/0,s=1/0,c=-1/0,l=-1/0,g=-1/0;for(let r=u-1;r>=1;r--){let i=t[n+r]*6;e[i]<a&&(a=e[i]),e[i+1]<o&&(o=e[i+1]),e[i+2]<s&&(s=e[i+2]),e[i+3]>c&&(c=e[i+3]),e[i+4]>l&&(l=e[i+4]),e[i+5]>g&&(g=e[i+5]);let u=r*6;f[u]=a,f[u+1]=o,f[u+2]=s,f[u+3]=c,f[u+4]=l,f[u+5]=g}let _=1/0,v=1/0,y=1/0,b=-1/0,x=-1/0,S=-1/0;for(let r=1;r<u;r++){let a=t[n+r-1]*6;e[a]<_&&(_=e[a]),e[a+1]<v&&(v=e[a+1]),e[a+2]<y&&(y=e[a+2]),e[a+3]>b&&(b=e[a+3]),e[a+4]>x&&(x=e[a+4]),e[a+5]>S&&(S=e[a+5]);let o=r*6,s=this._surfaceArea(_,v,y,b,x,S),c=this._surfaceArea(f[o],f[o+1],f[o+2],f[o+3],f[o+4],f[o+5]),l=1+(s*r+c*(u-r))/d;l<p&&(p=l,m=i,h=r)}}return m<0||h<=0?n:(m!==2&&this._sortRange(e,t,n,r,m),n+h)}_widestCentroidAxis(e,t,n,r){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let u=n;u<r;u++){let n=t[u]*6,r=(e[n]+e[n+3])*.5,d=(e[n+1]+e[n+4])*.5,f=(e[n+2]+e[n+5])*.5;r<i&&(i=r),r>s&&(s=r),d<a&&(a=d),d>c&&(c=d),f<o&&(o=f),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o;return d>u&&d>f?1:f>u?2:0}_insertionSortRange(e,t,n,r,i){let a=i,o=3+i;for(let i=n+1;i<r;i++){let r=t[i],s=e[r*6+a]+e[r*6+o],c=i-1;for(;c>=n&&e[t[c]*6+a]+e[t[c]*6+o]>s;)t[c+1]=t[c],c--;t[c+1]=r}}_sortRange(e,t,n,r,i){let a=r-n,o=this._sortScratch;o.length=a;for(let e=0;e<a;e++)o[e]=t[n+e];let s=i,c=3+i;o.sort((t,n)=>e[t*6+s]+e[t*6+c]-(e[n*6+s]+e[n*6+c]));for(let e=0;e<a;e++)t[n+e]=o[e]}_suffixBuffer(e){let t=e*6;return(!this._suffix||this._suffix.length<t)&&(this._suffix=new Float64Array(t)),this._suffix}_rangeBounds(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=n;i<r;i++){let n=t[i]*6;e[n]<o&&(o=e[n]),e[n+1]<s&&(s=e[n+1]),e[n+2]<c&&(c=e[n+2]),e[n+3]>l&&(l=e[n+3]),e[n+4]>u&&(u=e[n+4]),e[n+5]>d&&(d=e[n+5])}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}_surfaceArea(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}},Yo=64*1024*1024,Xo=typeof SharedArrayBuffer<`u`,Zo=null;function Qo(e){Zo=e}function $o(e,t,n){let r=n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t);return Zo&&r.byteLength>0&&Zo(r.byteLength,n),r}var es=class e{constructor(e,t,n,r=Yo,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push($o(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push($o(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=Yo,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=$o(this.LaneType,n,this.shared);for(let t of this._views)t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)this.chunks[e]||this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0;return this.chunks[t]??this._materialize(t)}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,this._views&&(r._owner=this,this._views.push(r)),r}},ts=K.FLOATS_PER_TRIANGLE*4,ns=64,rs=.9,is=64,as=4,os=7040*1024*1024,ss=9216*1024*1024,cs=1.15,ls=12*1024*1024*1024;function us({triangles:e,placements:t,geometryBytes:n=0}){let r={triangles:e*ts,bvh:Math.ceil(e*rs)*ns,geometry:n,placements:t*is,orderMaps:e*as};return r.total=r.triangles+r.bvh+r.geometry+r.placements+r.orderMaps,r}function ds(e,{chunkBytes:t=Yo,shared:n=!1,allocate:r=null}={}){let i=Math.min(e,ls),a=r??(n?e=>new SharedArrayBuffer(e):e=>new ArrayBuffer(e)),o=[],s=0;try{for(;s<i;){let e=Math.min(t,i-s);o.push(a(e)),s+=e}}catch{}for(let e=o.length-1;e>=0;e--)o[e]=null;return o.length=0,{placed:s,want:i,exhausted:s<i,capped:e>i}}var fs=class{constructor(){this.reset()}reset(){this.phase=`idle`,this.events=[],this.samples=[],this.allocatedBytes=0,this.peakLiveBytes=0,this.byPhase=Object.create(null)}mark(e){return this.phase=e,this.byPhase[e]??={allocated:0,chunks:0},this}alloc(e,t=`chunk`){if(!(e>0))return;let n=this.byPhase[this.phase]??={allocated:0,chunks:0};n.allocated+=e,n.chunks++,this.allocatedBytes+=e,this.events.push({phase:this.phase,bytes:e,what:t,at:performance.now()})}sample(e,t){let n=0;for(let e in t)n+=t[e]||0;return n>this.peakLiveBytes&&(this.peakLiveBytes=n),this.samples.push({label:e,phase:this.phase,total:n,parts:t,at:performance.now()}),n}get report(){return{allocatedBytes:this.allocatedBytes,peakLiveBytes:this.peakLiveBytes,byPhase:{...this.byPhase},samples:this.samples.slice()}}},ps="let e,t;const n={MAX_BYTES_PER_TEXTURE:256*1024*1024,MAX_TEXTURE_DIMENSION:8192,CHUNK_SIZE:8,ADAPTIVE_CHUNK_SIZE:!0,MEMORY_SAFETY_FACTOR:.8};self.onmessage=async function(t){let{textures:n,maxTextureSize:a,method:o=`direct-transfer`}=t.data;try{e||r(a);let t=await i(n,a,o);self.postMessage(t,[t.data])}catch(e){console.error(`Worker processing failed:`,e),self.postMessage({error:e.message})}};function r(r){let i=Math.min(r,n.MAX_TEXTURE_DIMENSION);e=new OffscreenCanvas(i,i),t=e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0})}async function i(e,t,r){let i=h(e,t),o=i.maxWidth*i.maxHeight*e.length*4;if(o>n.MAX_BYTES_PER_TEXTURE)return console.log(`Large texture array detected (${(o/1024/1024).toFixed(2)}MB), using chunked processing`),await a(e,t,r);switch(r){case`direct-transfer`:return await d(e,t);case`offscreen-optimized`:return await p(e,t);case`imageBitmap-batch`:return await m(e,t);default:return await d(e,t)}}async function a(e,t,n){let{maxWidth:r,maxHeight:i}=h(e,t),a=e.length,c=o(r,i,a),l=Math.ceil(a/c);console.log(`Processing ${a} textures in ${l} chunks of up to ${c} textures each`),console.log(`Texture dimensions: ${r}x${i}, Est. memory per chunk: ${(r*i*c*4/1024/1024).toFixed(2)}MB`);let u;try{u=new Uint8Array(r*i*a*4)}catch{return console.warn(`Failed to allocate full texture array, reducing dimensions`),await f(e,g(e,t),n)}let d=r*i*c*4,p;try{p=new Uint8Array(d)}catch{return console.warn(`Failed to allocate chunk buffer, reducing dimensions`),await f(e,g(e,t),n)}for(let t=0;t<l;t++){let n=t*c,o=Math.min(n+c,a),l=o-n,d=await s(e.slice(n,o),r,i,p.subarray(0,r*i*l*4)),f=n*r*i*4,m=l*r*i*4;u.set(new Uint8Array(d.data.slice(0,m)),f),t%2==1&&await new Promise(e=>setTimeout(e,0))}return{data:u.buffer,width:r,height:i,depth:a}}function o(e,t,r){if(!n.ADAPTIVE_CHUNK_SIZE)return Math.min(n.CHUNK_SIZE,r);let i=e*t*4/(1024*1024),a;return a=i<=1?16:i<=4?8:i<=16?4:2,Math.min(a,r,n.CHUNK_SIZE*2)}async function s(n,r,i,a){(e.width!==r||e.height!==i)&&(e.width=r,e.height=i);let o=r*i*4;t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await c(t,a,e*o,r,i)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=e*o;a.fill(0,n,n+o)}}return{data:a.buffer,width:r,height:i,depth:n.length}}async function c(e,n,r,i,a){let o;if(e.isDirect&&e.bitmap)o=e.bitmap;else if(e.isImageData&&e.data){let t=new ImageData(new Uint8ClampedArray(e.data),e.width,e.height);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else if(e.isBlob){let t=new Blob([e.data]);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else throw Error(`Unknown texture data format`);t.clearRect(0,0,i,a),t.drawImage(o,0,0,i,a);let s=t.getImageData(0,0,i,a);n.set(s.data,r),(e.isImageData||e.isBlob)&&o.close()}async function l(e,t,n){let r;try{r=new Uint8Array(t*n*e.length*4)}catch(r){console.warn(`Failed to allocate texture array in processTextureChunk, reducing dimensions`);let i=Math.max(1,Math.floor(t/2)),a=Math.max(1,Math.floor(n/2));if(i===t&&a===n)throw r;return await l(e,i,a)}return await s(e,t,n,r)}async function u(e,t,n,r,i){await c(e,n,r*i*4*t,r,i)}async function d(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`direct-transfer`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await u(t,e,c,i,o)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function f(e,t,n){let{maxWidth:r,maxHeight:i}=t;return console.log(`Using reduced dimensions: ${r}x${i}`),await l(e,r,i,n)}async function p(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`offscreen-optimized`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let r=n[e];try{let n;if(r.isBlob){let e=new Blob([r.data]);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(r.data),r.width,r.height);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}t.clearRect(0,0,i,o),t.drawImage(n,0,0);let a=t.getImageData(0,0,i,o),s=i*o*4*e;c.set(a.data,s),n.close()}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function m(n,r){let{maxWidth:i,maxHeight:s}=h(n,r),c=n.length,l;try{l=new Uint8Array(i*s*c*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`imageBitmap-batch`)}let u=Math.min(o(i,s,n.length),n.length);for(let r=0;r<n.length;r+=u){let a=Math.min(r+u,n.length),o=[];for(let e=r;e<a;e++){let t=n[e],r;if(t.isBlob){let e=new Blob([t.data]);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(t.data),t.width,t.height);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}o.push(r.then(t=>({bitmap:t,index:e})))}let c=await Promise.all(o);e.width=i,e.height=s,t.imageSmoothingEnabled=!1;for(let{bitmap:e,index:n}of c){t.clearRect(0,0,i,s),t.drawImage(e,0,0);let r=t.getImageData(0,0,i,s),a=i*s*4*n;l.set(r.data,a),e.close()}}return{data:l.buffer,width:i,height:s,depth:c}}function h(e,t){let r=0,i=0;for(let t of e)r=Math.max(r,t.width||0),i=Math.max(i,t.height||0);let a=Math.min(t,n.MAX_TEXTURE_DIMENSION),o=Math.max(r,i);if(o>a){let e=a/o;r=Math.round(r*e),i=Math.round(i*e)}return r=Math.min(a,Math.max(4,Math.ceil(Math.max(1,r)/64)*64)),{maxWidth:r,maxHeight:Math.max(1,i)}}function g(e,t){let n=h(e,t);return{maxWidth:Math.max(64,Math.ceil(n.maxWidth/128)*64),maxHeight:Math.max(1,Math.floor(n.maxHeight/2))}}",ms=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,ps],{type:`text/javascript;charset=utf-8`});function hs(e){let t;try{if(t=ms&&(self.URL||self.webkitURL).createObjectURL(ms),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(ps),{type:`module`,name:e?.name})}}var gs=Object.freeze({ADAPTER_SOFTWARE:`adapter.software`,ASSET_UNREACHABLE:`asset.unreachable`,ASSET_AMBIGUOUS_ENTRY:`asset.ambiguous_entry`,ASSET_ARCHIVE_TOO_LARGE:`asset.archive_too_large`,ASSET_ENTRY_TOO_LARGE:`asset.entry_too_large`,TEXTURE_BUILD_FAILED:`texture.build_failed`,TEXTURE_PROCESSING_FALLBACK:`texture.processing_fallback`,TEXTURE_LIMIT_EXCEEDED:`texture.limit_exceeded`,ENVIRONMENT_LOAD_FAILED:`environment.load_failed`,SETTING_UNKNOWN_KEY:`setting.unknown_key`,RENDER_SIZE_DECLINED:`render.size_declined`,STAGE_RENDER_FAILED:`stage.render_failed`,RENDER_RESERVE_CAPPED:`render.reserve_capped`,SCENE_MEMORY_BUDGET:`scene.memory_budget`,EMISSIVE_INSTANCES_COLLAPSED:`emissive.instances_collapsed`,REFIT_SHARED_GEOMETRY:`refit.shared_geometry`}),_s=Object.freeze({ERROR:`error`,WARNING:`warning`}),vs=class extends Error{constructor(e){super(`[${e.code}] ${e.message}`),this.name=`EngineIssueError`,this.code=e.code,this.detail=e.detail}},ys=class{constructor({strict:e=!1,onIssue:t=null}={}){this.strict=e===!0,this._onIssue=t,this._entries=[]}record(e,t,n={},r=_s.ERROR){let i=Object.freeze({code:e,message:t,detail:n,severity:r,at:Date.now()});if(this._entries.push(i),this._onIssue?.(i),this.strict&&r===_s.ERROR)throw new vs(i);return i}warn(e,t,n){return this.record(e,t,n,_s.WARNING)}get list(){return this._entries.slice()}get errors(){return this._entries.filter(e=>e.severity===_s.ERROR)}clear(){this._entries.length=0}detach(){this._onIssue=null,this.strict=!1}},bs=e=>Math.min(Math.max(e,0),1);function xs(e,t,n,r,i){i[0]=bs(e),i[1]=bs(t),i[2]=bs(n)}function Ss(e,t,n,r,i){i[0]=bs(e*r),i[1]=bs(t*r),i[2]=bs(n*r)}function Cs(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=bs(e/(e+1)),i[1]=bs(t/(t+1)),i[2]=bs(n/(n+1))}function ws(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 Ts(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]=bs(1.60475*a-.53108*o-.07367*s),i[1]=bs(-.10208*a+1.10813*o-.00605*s),i[2]=bs(-.00327*a-.07276*o+1.07602*s)}function Es(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=bs((Math.log2(Math.max(c,1e-10))-d)/f),l=bs((Math.log2(Math.max(l,1e-10))-d)/f),u=bs((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]=bs(1.6605*m-.5876*h-.0728*g),i[1]=bs(-.1246*m+1.1329*h-.0083*g),i[2]=bs(-.0182*m-.1006*h+1.1187*g)}function Ds(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 Os=e=>(t,n,r,i,a)=>e(t>0?t:0,n>0?n:0,r>0?r:0,i,a),ks=new Map([[r.NoToneMapping,Os(xs)],[r.LinearToneMapping,Os(Ss)],[r.ReinhardToneMapping,Os(Cs)],[r.CineonToneMapping,Os(ws)],[r.ACESFilmicToneMapping,Os(Ts)],[r.AgXToneMapping,Os(Es)],[r.NeutralToneMapping,Os(Ds)]]),As=1/2.2;function js(e){return e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055}function Ms(e,t){return t===r.NoToneMapping?1:e}var Ns=.2126,Ps=.7152,Fs=.0722;function Is(e,t){if(t===1)return;let n=e[0]*Ns+e[1]*Ps+e[2]*Fs;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}function Ls(e,{exposure:t,toneMapping:n,saturation:i=1,preserveAlpha:a=!1}){let o=ks.get(n)??ks.get(r.NoToneMapping),s=Ms(t,n),c=new Uint8ClampedArray(e.length),l=[0,0,0];for(let t=0;t<e.length;t+=4)l[0]=e[t]*s,l[1]=e[t+1]*s,l[2]=e[t+2]*s,Is(l,i),o(l[0],l[1],l[2],1,l),c[t]=js(l[0])*255+.5,c[t+1]=js(l[1])*255+.5,c[t+2]=js(l[2])*255+.5,c[t+3]=a?e[t+3]*255+.5:255;return c}var Rs=It(`textures`),zs={toSRGB:null,toLinear:null};function Bs(e){if(!zs[e]){let t=new Uint8Array(256);for(let n=0;n<256;n++){let r=n/255,i=e===`toSRGB`?js(r):r<=.04045?r/12.92:((r+.055)/1.055)**2.4;t[n]=Math.max(0,Math.min(255,Math.round(i*255)))}zs[e]=t}return zs[e]}var Vs=class{constructor(){this.canvasContextPairs=[],this.maxPoolSize=at.CANVAS_POOL_SIZE}getCanvasWithContext(e,t,n=!1,r={}){let i={willReadFrequently:!0,alpha:!0,desynchronized:!0,...r},a=this.canvasContextPairs.pop();if(!a){let r;r=n&&typeof OffscreenCanvas<`u`?new OffscreenCanvas(e,t):document.createElement(`canvas`);let o=r.getContext(`2d`,i);a={canvas:r,context:o}}return a.canvas.width=e,a.canvas.height=t,a}releaseCanvasWithContext(e){this.canvasContextPairs.length<this.maxPoolSize&&(e.context.globalAlpha=1,e.context.globalCompositeOperation=`source-over`,e.context.imageSmoothingEnabled=!0,e.context.clearRect(0,0,e.canvas.width,e.canvas.height),e.canvas.width=1,e.canvas.height=1,this.canvasContextPairs.push(e))}getCanvas(e,t,n=!1){return this.getCanvasWithContext(e,t,n).canvas}getContext(e,t={}){let n=this.canvasContextPairs.find(t=>t.canvas===e);return n?n.context:e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0,...t})}dispose(){this.canvasContextPairs=[]}},Hs=class{constructor(e={}){this.pools=new Map,this.memoryUsage=0,this.maxMemoryUsage=e.maxMemory||bt.MAX_BUFFER_MEMORY,this.allocatedBuffers=new WeakMap,this.sizeStrategy=e.sizeStrategy||`adaptive`}getOptimalSize(e){switch(this.sizeStrategy){case`exact`:return e;case`power2`:return 2**Math.ceil(Math.log2(e));default:return e<1024?e:e<1024*1024?Math.ceil(e/1024)*1024:2**Math.ceil(Math.log2(e))}}getBuffer(e,t=Float32Array){let n=this.getOptimalSize(e),r=`${t.name}-${n}`,i=(this.pools.get(r)||[]).pop();if(!i)try{i=new t(n),this.memoryUsage+=i.byteLength,this.allocatedBuffers.set(i,!0)}catch{this.cleanup();try{i=new t(n),this.memoryUsage+=i.byteLength,this.allocatedBuffers.set(i,!0)}catch(e){let r=n*t.BYTES_PER_ELEMENT/(1024*1024),i=this.memoryUsage/(1024*1024);throw Error(`Buffer allocation failed: requested ${r.toFixed(1)}MB, current usage: ${i.toFixed(1)}MB, max: ${(this.maxMemoryUsage/(1024*1024)).toFixed(1)}MB. Original error: ${e.message}`)}}return this.memoryUsage>this.maxMemoryUsage*bt.CLEANUP_THRESHOLD&&this.cleanup(),this.checkMemoryHealth(),i.byteOffset+e*t.BYTES_PER_ELEMENT>i.buffer.byteLength&&(i=new t(e),this.memoryUsage+=i.byteLength),new t(i.buffer,i.byteOffset,e)}releaseBuffer(e,t=Float32Array){let n=(e.buffer.byteLength-e.byteOffset)/t.BYTES_PER_ELEMENT,r=this.getOptimalSize(n),i=`${t.name}-${r}`,a=this.pools.get(i)||[];a.length<at.BUFFER_POOL_SIZE?(a.push(new t(e.buffer,e.byteOffset,n)),this.pools.set(i,a)):this.allocatedBuffers.has(e)&&(this.memoryUsage-=e.byteLength,this.allocatedBuffers.delete(e))}cleanup(){let e=Array.from(this.pools.entries());e.slice(0,Math.floor(e.length/2)).forEach(([e,t])=>{t.forEach(e=>{this.allocatedBuffers.has(e)&&(this.memoryUsage-=e.byteLength,this.allocatedBuffers.delete(e))}),this.pools.delete(e)})}dispose(){this.pools.forEach(e=>{e.forEach(e=>{this.allocatedBuffers.has(e)&&this.allocatedBuffers.delete(e)})}),this.pools.clear(),this.memoryUsage=0}getMemoryStats(){return{currentUsage:this.memoryUsage,maxUsage:this.maxMemoryUsage,utilizationPercentage:this.memoryUsage/this.maxMemoryUsage*100,poolCount:this.pools.size,allocatedBufferCount:this.allocatedBuffers&&this.allocatedBuffers.size||0}}checkMemoryHealth(){let e=this.getMemoryStats();return e.utilizationPercentage>90?(console.warn(`Memory pool critical: ${e.utilizationPercentage.toFixed(1)}% used (${(e.currentUsage/(1024*1024)).toFixed(1)}MB / ${(e.maxUsage/(1024*1024)).toFixed(1)}MB)`),`critical`):e.utilizationPercentage>70?(console.warn(`Memory pool high: ${e.utilizationPercentage.toFixed(1)}% used (${(e.currentUsage/(1024*1024)).toFixed(1)}MB / ${(e.maxUsage/(1024*1024)).toFixed(1)}MB)`),`high`):`normal`}},Us=class{constructor(e=at.CACHE_SIZE_LIMIT){this.cache=new Map,this.accessOrder=[],this.maxSize=e}generateHash(e){let t=``;for(let n of e)if(n?.image){let e=n.image.width||0,r=n.image.height||0,i=n.image.src||n.uuid||``,a=n.flipY===!1?`n`:`f`;t+=`${e}x${r}_${i.slice(-8)}_${a}_`}return t+e.length}get(e){if(this.cache.has(e)){let t=this.cache.get(e);if(t?.userData&&t.userData.buffer===null){this.cache.delete(e);let t=this.accessOrder.indexOf(e);return t>-1&&this.accessOrder.splice(t,1),null}let n=this.accessOrder.indexOf(e);return n>-1&&this.accessOrder.splice(n,1),this.accessOrder.push(e),t}return null}set(e,t){if(this.cache.has(e)){let t=this.accessOrder.indexOf(e);t>-1&&this.accessOrder.splice(t,1)}else this.cache.size>=this.maxSize&&this.evictLRU();this.cache.set(e,t),this.accessOrder.push(e)}evictLRU(){if(this.accessOrder.length>0){let e=this.accessOrder.shift(),t=this.cache.get(e);t&&t.dispose&&t.dispose(),this.cache.delete(e)}}dispose(){this.cache.forEach(e=>{e&&e.dispose&&e.dispose()}),this.cache.clear(),this.accessOrder=[]}},Ws=class{constructor(e={}){this.useWorkers=typeof Worker<`u`,this.maxConcurrentWorkers=at.MAX_CONCURRENT_WORKERS,this.activeWorkers=0,this._issues=e.issues??null,this.maxTextureSize=this._clampTextureSize(e.maxTextureSize??at.DEFAULT_MAX_TEXTURE_SIZE),this.canvasPool=new Vs,this.bufferPool=new Hs({maxMemory:e.maxBufferMemory||bt.MAX_BUFFER_MEMORY,sizeStrategy:e.bufferSizeStrategy||`adaptive`}),this.textureCache=new Us,this.capabilities=this.detectCapabilities(),this.optimalMethod=this.selectOptimalMethod()}_reportTextureFailure(e,t){this._issues?.record(gs.TEXTURE_BUILD_FAILED,`${e} texture array failed to build — those surfaces render untextured`,{map:e,cause:String(t?.message??t)})}_clampTextureSize(e){let t=Math.floor(Number(e)||at.DEFAULT_MAX_TEXTURE_SIZE);return Math.max(at.MIN_TEXTURE_WIDTH,Math.min(t,at.MAX_TEXTURE_SIZE))}setMaxTextureSize(e){let t=this._clampTextureSize(e);return t===this.maxTextureSize?t:(this.maxTextureSize=t,this.textureCache?.dispose(),this.textureCache=new Us,this.maxTextureSize)}detectCapabilities(){return{offscreenCanvas:typeof OffscreenCanvas<`u`,imageBitmap:typeof createImageBitmap<`u`,workers:typeof Worker<`u`,hardwareConcurrency:navigator.hardwareConcurrency||4}}selectOptimalMethod(){return this.capabilities.workers&&this.capabilities.offscreenCanvas?`worker-offscreen`:this.capabilities.imageBitmap?`imageBitmap`:`canvas`}_harmonizeTransfer(e,t,n){let i=e?.image?.data;if(!i)return;let a=t.filter(e=>e?.image),o=n?r.SRGBColorSpace:r.LinearSRGBColorSpace,s=e.image.width*e.image.height*4,c=[];for(let e=0;e<a.length;e++){let t=a[e].colorSpace;if(t!==r.SRGBColorSpace&&t!==r.LinearSRGBColorSpace||t===o)continue;let l=Bs(n?`toSRGB`:`toLinear`),u=e*s,d=Math.min(u+s,i.length);for(let e=u;e<d;e+=4)i[e]=l[i[e]],i[e+1]=l[i[e+1]],i[e+2]=l[i[e+2]];c.push(a[e].name||a[e].source?.uuid?.slice(0,8)||`layer ${e}`)}if(c.length===0)return;e.needsUpdate=!0;let l=c.slice(0,4).join(`, `)+(c.length>4?`, +${c.length-4} more`:``);n?Rs.info(`re-encoded ${c.length}/${a.length} linear-declared colour map(s) to sRGB so the GPU decode round-trips: ${l}`):Rs.warn(`decoded ${c.length}/${a.length} sRGB-declared data map(s) to linear — precision is lost in the darks, check the asset: ${l}`)}async createTexturesToDataTexture(e,{srgbPool:t=!1}={}){if(!e||e.length===0)return null;let n=`${t?`s`:`l`}:${this.textureCache.generateHash(e)}`,r=this.textureCache.get(n);if(r)return r;let{normalized:i,bitmapsToClose:a}=await this._normalizeTexturesForProcessing(e),o=this.selectProcessingStrategy(i),s;try{switch(o.method){case`worker-direct`:s=await this.processWithWorkerDirect(i);break;case`main-batch`:s=await this.processOnMainThreadBatch(i,o.batchSize);break;case`main-streaming`:s=await this.processOnMainThreadStreaming(i);break;default:s=await this.processOnMainThreadSync(i)}return s&&(this._harmonizeTransfer(s,e,t),this.textureCache.set(n,s)),s}catch(n){this._issues?.warn(gs.TEXTURE_PROCESSING_FALLBACK,`worker texture processing failed — retrying on the main thread`,{cause:String(n?.message??n)});let r=await this.processOnMainThreadSync(i);return this._harmonizeTransfer(r,e,t),r}finally{for(let e of a)e.close()}}selectProcessingStrategy(e){let t=e.reduce((e,t)=>e+(t.image?.width||0)*(t.image?.height||0),0),n=t*4;return this.capabilities.workers&&n>bt.MAX_TEXTURE_MEMORY?{method:`main-streaming`}:this.capabilities.workers&&t>2097152?{method:`worker-direct`}:t>524288?{method:`main-batch`,batchSize:Math.min(4,e.length)}:e.length>8?{method:`main-streaming`}:{method:`main-sync`}}async processWithWorkerDirect(e){for(;this.activeWorkers>=this.maxConcurrentWorkers;)await new Promise(e=>setTimeout(e,10));this.activeWorkers++;try{let t=new hs,n=await this.prepareTexturesForWorkerDirect(e),r=await new Promise((e,r)=>{t.onmessage=t=>{t.data.error?r(Error(t.data.error)):e(t.data)},t.onerror=r;let i=[];n.forEach(e=>{e.data instanceof ArrayBuffer?i.push(e.data):e.bitmap&&i.push(e.bitmap)}),t.postMessage({textures:n,maxTextureSize:this.maxTextureSize,method:`direct-transfer`},i)});return t.terminate(),this.createDataArrayTextureFromResult(r)}finally{this.activeWorkers--}}async prepareTexturesForWorkerDirect(e){let t=[];for(let n of e){if(!n?.image)continue;let e=n.flipY!==!1;try{let r=n.image;if(typeof createImageBitmap<`u`&&(r instanceof HTMLImageElement||typeof ImageBitmap<`u`&&r instanceof ImageBitmap||typeof HTMLCanvasElement<`u`&&r instanceof HTMLCanvasElement||typeof OffscreenCanvas<`u`&&r instanceof OffscreenCanvas)){let r=await createImageBitmap(n.image,{imageOrientation:e?`flipY`:`none`});t.push({bitmap:r,width:n.image.width,height:n.image.height,isDirect:!0})}else{let r=n.image.width,i=n.image.height,a=await createImageBitmap(n.image,{imageOrientation:e?`flipY`:`none`}),o=this.canvasPool.getCanvasWithContext(r,i);o.context.drawImage(a,0,0),a.close();let s=o.context.getImageData(0,0,r,i);t.push({data:s.data.buffer,width:r,height:i,isImageData:!0}),this.canvasPool.releaseCanvasWithContext(o)}}catch(e){console.warn(`Failed to prepare texture for worker:`,e)}}return t}async processOnMainThreadBatch(e,t){let n=e.filter(e=>e?.image);if(n.length===0)return this.createFallbackTexture();let{maxWidth:r,maxHeight:i}=this.calculateOptimalDimensions(n),a=n.length,o=this.bufferPool.getBuffer(r*i*a*4,Uint8Array);for(let e=0;e<n.length;e+=t){let a=Math.min(e+t,n.length),s=[];for(let t=e;t<a;t++){let e=n[t],a=e.flipY!==!1,o=createImageBitmap(e.image,{resizeWidth:r,resizeHeight:i,resizeQuality:`high`,imageOrientation:a?`flipY`:`none`});s.push(o.then(e=>({bitmap:e,index:t})))}let c=await Promise.all(s),l=this.canvasPool.getCanvasWithContext(r,i);l.context.imageSmoothingEnabled=!1;for(let{bitmap:e,index:t}of c){l.context.clearRect(0,0,r,i),l.context.drawImage(e,0,0);let n=l.context.getImageData(0,0,r,i),a=r*i*4*t;o.set(n.data,a),e.close()}this.canvasPool.releaseCanvasWithContext(l)}return this.createDataArrayTextureFromBuffer(o,r,i,a)}async processOnMainThreadStreaming(e){let t=e.filter(e=>e?.image);if(t.length===0)return this.createFallbackTexture();let{maxWidth:n,maxHeight:r}=this.calculateOptimalDimensions(t),i=t.length,a=this.bufferPool.getBuffer(n*r*i*4,Uint8Array),o=this.canvasPool.getCanvasWithContext(n,r);o.context.imageSmoothingEnabled=!0,o.context.imageSmoothingQuality=`high`;for(let e=0;e<t.length;e++){let i=t[e],s=await createImageBitmap(i.image,{resizeWidth:n,resizeHeight:r,resizeQuality:`high`,imageOrientation:i.flipY===!1?`none`:`flipY`});o.context.clearRect(0,0,n,r),o.context.drawImage(s,0,0),s.close();let c=o.context.getImageData(0,0,n,r),l=n*r*4*e;a.set(c.data,l),e%bt.STREAM_BATCH_SIZE===0&&await new Promise(e=>setTimeout(e,0))}return this.canvasPool.releaseCanvasWithContext(o),this.createDataArrayTextureFromBuffer(a,n,r,i)}async processOnMainThreadSync(e){let t=e.filter(e=>e?.image);if(t.length===0)return this.createFallbackTexture();let{maxWidth:n,maxHeight:r}=this.calculateOptimalDimensions(t),i=t.length,a=this.bufferPool.getBuffer(n*r*i*4,Uint8Array),o=this.canvasPool.getCanvasWithContext(n,r);o.context.imageSmoothingEnabled=!0,o.context.imageSmoothingQuality=`high`;for(let e=0;e<t.length;e++){let i=t[e],s=await createImageBitmap(i.image,{resizeWidth:n,resizeHeight:r,resizeQuality:`high`,imageOrientation:i.flipY===!1?`none`:`flipY`});o.context.clearRect(0,0,n,r),o.context.drawImage(s,0,0),s.close();let c=o.context.getImageData(0,0,n,r),l=n*r*4*e;a.set(c.data,l)}return this.canvasPool.releaseCanvasWithContext(o),this.createDataArrayTextureFromBuffer(a,n,r,i)}createMaterialRawData(e){let t=q.FLOATS_PER_MATERIAL,n=e.length,r=n*t,i=new Float32Array(r);for(let r=0;r<n;r++){let n=e[r],a=r*t,o=n.mapMatrix??_t,s=n.normalMapMatrices??_t,c=n.roughnessMapMatrices??_t,l=n.metalnessMapMatrices??_t,u=n.emissiveMapMatrices??_t,d=n.bumpMapMatrices??_t,f=n.displacementMapMatrices??_t,p=[n.ior,n.transmission,n.thickness,n.emissiveIntensity,n.attenuationColor.r,n.attenuationColor.g,n.attenuationColor.b,J(n.attenuationDistance),n.opacity,n.side,n.transparent,n.alphaTest,n.alphaMode,n.depthWrite,n.normalScale?.x??1,n.normalScale?.y??1,n.color.r,n.color.g,n.color.b,n.metalness,n.emissive.r,n.emissive.g,n.emissive.b,n.roughness,n.map,n.normalMap,n.roughnessMap,n.metalnessMap,n.emissiveMap,n.bumpMap,n.clearcoat,n.clearcoatRoughness,n.dispersion,n.visible,n.sheen,n.sheenRoughness,n.sheenColor.r,n.sheenColor.g,n.sheenColor.b,1,n.specularIntensity,n.specularColor.r,n.specularColor.g,n.specularColor.b,n.iridescence,n.iridescenceIOR,n.iridescenceThicknessRange[0],n.iridescenceThicknessRange[1],n.bumpScale,n.displacementScale,n.displacementMap,0,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],n.subsurfaceColor?.r??1,n.subsurfaceColor?.g??1,n.subsurfaceColor?.b??1,n.subsurface??0,n.subsurfaceRadius?.[0]??1,n.subsurfaceRadius?.[1]??.2,n.subsurfaceRadius?.[2]??.1,n.subsurfaceRadiusScale??1,n.subsurfaceAnisotropy??0,n.anisotropy??0,n.anisotropyRotation??0,n.anisotropyMap??-1,n.transmissionMap??-1,n.clearcoatMap??-1,n.clearcoatRoughnessMap??-1,n.sheenColorMap??-1,n.sheenRoughnessMap??-1,n.iridescenceMap??-1,n.iridescenceThicknessMap??-1,n.specularIntensityMap??-1,n.specularColorMap??-1,0,0,0];i.set(p,a)}return i}createBVHRawData(e){let t=[],n=e=>{let r=t.length;if(t.push(e),e.leftChild){let t=n(e.leftChild),r=n(e.rightChild);e.leftChild=t,e.rightChild=r}return r};n(e);let r=at.VEC4_PER_BVH_NODE*at.FLOATS_PER_VEC4;it(t.length,`BVH node count`);let i=t.length*r,a=new Float32Array(i),o=rt(a);for(let e=0;e<t.length;e++){let n=e*r,i=t[e];if(i.leftChild!==null){let e=i.leftChild,r=i.rightChild,s=t[e],c=t[r];a[n]=s.boundsMin.x,a[n+1]=s.boundsMin.y,a[n+2]=s.boundsMin.z,o[n+3]=e,a[n+4]=s.boundsMax.x,a[n+5]=s.boundsMax.y,a[n+6]=s.boundsMax.z,o[n+7]=r,a[n+8]=c.boundsMin.x,a[n+9]=c.boundsMin.y,a[n+10]=c.boundsMin.z,a[n+12]=c.boundsMax.x,a[n+13]=c.boundsMax.y,a[n+14]=c.boundsMax.z}else o[n]=i.triangleOffset,o[n+1]=i.triangleCount,o[n+3]=nt.TRIANGLE_LEAF}return a}async createMaterialTextures(e){let{materials:t,maps:n,normalMaps:i,bumpMaps:a,roughnessMaps:o,metalnessMaps:s,emissiveMaps:c,displacementMaps:l}=e;console.log(`[TextureCreator] Creating material textures only`);let u=performance.now();try{if(!t||t.length===0)throw Error(`No materials provided for texture creation`);this.textureCache.dispose(),this.textureCache=new Us;let e=[];for(let[t,r]of[[`albedo`,n],[`normal`,i],[`bump`,a],[`roughness`,o],[`metalness`,s],[`emissive`,c],[`displacement`,l]])!r||r.length===0||e.push(this.createTexturesToDataTexture(r).then(e=>({type:t,texture:e})).catch(e=>(this._reportTextureFailure(t,e),{type:t,texture:null})));let d=await Promise.allSettled(e),f=d.find(e=>e.status===`rejected`);if(f)throw f.reason;let p={};d.forEach(e=>{if(e.status===`fulfilled`&&e.value){let{type:t,texture:n}=e.value;if(n)switch(t){case`albedo`:n.colorSpace=r.SRGBColorSpace,p.albedoTexture=n;break;case`normal`:p.normalTexture=n;break;case`bump`:p.bumpTexture=n;break;case`roughness`:p.roughnessTexture=n;break;case`metalness`:p.metalnessTexture=n;break;case`emissive`:n.colorSpace=r.SRGBColorSpace,p.emissiveTexture=n;break;case`displacement`:p.displacementTexture=n;break}}});let m=performance.now()-u;return console.log(`[TextureCreator] Material texture creation complete (${m.toFixed(2)}ms)`),p}catch(e){throw console.error(`[TextureCreator] Material texture creation error:`,e),Error(`Material texture creation failed: ${e.message}`)}}calculateOptimalDimensions(e){let t=0,n=0;for(let r of e)t=Math.max(t,r.image.width),n=Math.max(n,r.image.height);let r=Math.max(t,n);if(r>this.maxTextureSize){let e=this.maxTextureSize/r;t=Math.round(t*e),n=Math.round(n*e)}return{maxWidth:st(t,this.maxTextureSize),maxHeight:Math.max(1,n)}}createDataArrayTextureFromResult(e){let t=(e.data instanceof ArrayBuffer,new Uint8Array(e.data));return this.createDataArrayTextureFromBuffer(t,e.width,e.height,e.depth)}createDataArrayTextureFromBuffer(e,t,n,i){let a=new r.DataArrayTexture(e,t,n,i);a.minFilter=r.LinearFilter,a.magFilter=r.LinearFilter,a.wrapS=r.RepeatWrapping,a.wrapT=r.RepeatWrapping,a.format=r.RGBAFormat,a.type=r.UnsignedByteType,a.needsUpdate=!0,a.generateMipmaps=!1,a.userData={buffer:e,bufferType:Uint8Array};let o=a.dispose.bind(a);return a.dispose=()=>{a.userData.buffer&&(this.bufferPool.releaseBuffer(a.userData.buffer,a.userData.bufferType),a.userData.buffer=null),o()},a}async _normalizeTexturesForProcessing(e){let t=[],n=[],i=[];for(let n of e)if(n?.image){if(n.isCompressedTexture&&n.format===r.RGBAFormat&&n.mipmaps?.[0]?.data){let e=n.mipmaps[0],r=t.length;t.push(null),i.push({index:r,flipY:n.flipY,promise:Gs(e.data,e.width,e.height)});continue}if(n.isCompressedTexture){console.warn(`[TextureCreator] GPU-compressed texture in mixed group — using placeholder`),t.push(null);continue}if(n.image.data&&!(n.image instanceof HTMLImageElement)&&!(n.image instanceof HTMLCanvasElement)&&!(typeof ImageBitmap<`u`&&n.image instanceof ImageBitmap)){let e=t.length;t.push(null),i.push({index:e,flipY:n.flipY,promise:Gs(n.image.data,n.image.width,n.image.height)});continue}t.push(n)}if(i.length>0){let e=await Promise.allSettled(i.map(e=>e.promise));for(let r=0;r<i.length;r++){let{index:a,flipY:o}=i[r],s=e[r];if(s.status===`fulfilled`){let e=s.value;n.push(e),t[a]={image:e,flipY:o}}else console.warn(`[TextureCreator] Failed to create ImageBitmap:`,s.reason)}}for(let e=0;e<t.length;e++)if(t[e]===null){let r=new Uint8ClampedArray([255,255,255,255]),i=await createImageBitmap(new ImageData(r,1,1));n.push(i),t[e]={image:i,flipY:!1}}return{normalized:t,bitmapsToClose:n}}createFallbackTexture(){let e=new r.DataArrayTexture(new Uint8Array([255,255,255,255]),1,1,1);return e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e.format=r.RGBAFormat,e.type=r.UnsignedByteType,e.needsUpdate=!0,e.generateMipmaps=!1,e}dispose(){this.canvasPool.dispose(),this.bufferPool.dispose(),this.textureCache.dispose()}};function Gs(e,t,n){let r=new Uint8ClampedArray(e.buffer,e.byteOffset,e.byteLength);return createImageBitmap(new ImageData(r,t,n))}var Ks=It(`geometry`),qs=at.MAX_TEXTURES_LIMIT,Js=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function Ys(e){for(let t=0;t<16;t++)if(e[t]!==Js[t])return!1;return!0}function Xs(e){if(e.userData?.gltfExtensions?.KHR_materials_unlit?.alphaMode){let t=e.userData.gltfExtensions.KHR_materials_unlit.alphaMode;return t===`BLEND`?2:+(t===`MASK`)}return e.alphaTest>0?1:e.transparent&&e.opacity<1||e.map&&e.map.format===r.RGBAFormat&&e.transparent?2:0}function Zs(e){let t=0,n=new Set,r=e=>{let i=e.isMesh&&e.material?e.geometry:null;if(i&&!n.has(i.uuid)){n.add(i.uuid);for(let e in i.attributes)t+=i.attributes[e].array?.byteLength??0;t+=i.index?.array?.byteLength??0}if(e.children)for(let t of e.children)r(t)};return r(e),t}function Qs(e,t){let n=e.x,r=e.y,i=e.z;e.x=t[0]*n+t[4]*r+t[8]*i+t[12],e.y=t[1]*n+t[5]*r+t[9]*i+t[13],e.z=t[2]*n+t[6]*r+t[10]*i+t[14]}function $s(e,t){let n=e.x,r=e.y,i=e.z;e.x=t[0]*n+t[3]*r+t[6]*i,e.y=t[1]*n+t[4]*r+t[7]*i,e.z=t[2]*n+t[5]*r+t[8]*i}var ec=1<<21;function tc(e){return!!(e.isSkinnedMesh||Object.keys(e.geometry?.morphAttributes??{}).length)}function nc(e){return e[0]*(e[5]*e[10]-e[9]*e[6])-e[4]*(e[1]*e[10]-e[9]*e[2])+e[8]*(e[1]*e[6]-e[5]*e[2])}var rc=class{constructor({issues:e=null}={}){this._issues=e,this._droppedTextures=0,this._vectorPool={vec3:Array(9).fill().map(()=>new r.Vector3),vec2:[,,,,,,].fill().map(()=>new r.Vector2)},this._geometryRanges=new Map,this.expandedTriangleCount=0,this._allocatePlacements(0),this._matrixPool={mat3:new r.Matrix3,mat4:new r.Matrix4},this.resetArrays(),this.triangleCount=0,this.currentTriangleIndex=0}_getVec3(e=0){return this._vectorPool.vec3[e%this._vectorPool.vec3.length]}_getVec2(e=0){return this._vectorPool.vec2[e%this._vectorPool.vec2.length]}extract(e){this.resetArrays();let t=this._countTriangles(e);return this._triangleCapacity=Math.max(1024,t),this._allocateTriangles(this._triangleCapacity),this.currentTriangleIndex=0,this._allocatePlacements(this._countPlacements(e)),this._geometryUses=this._countGeometryUses(e),this.bakeInverse=new Map,this.traverseObject(e),this._shareInstanceMatrices(),this._compressAttributes(e),this.logStats(),this.getExtractedData()}surveyScene(e){let t=0,n=e=>{if(e.isMesh&&e.geometry&&e.material&&t++,e.children)for(let t of e.children)n(t)};return n(e),{triangles:this._countTriangles(e),placements:this._countPlacements(e),meshes:t,geometryBytes:Zs(e)}}_countGeometryUses(e){let t=new Map;return e.traverse(e=>{if(!e.isMesh||!e.geometry||!e.material)return;let n=`${e.geometry.uuid}|${e.material.uuid}`;t.set(n,(t.get(n)??0)+1)}),t}_countPlacements(e){let t=0;if(e.isMesh&&e.geometry&&e.material&&(t+=e.isInstancedMesh&&e.instanceMatrix?e.count??e.instanceMatrix.array.length/16:1),e.children)for(let n of e.children)t+=this._countPlacements(n);return t}_allocatePlacements(e){this.instanceCount=0,this.instanceCapacity=e,this.instanceSource=new Int32Array(e),this.instanceMatrices=new Float32Array(e*16),this._shareable=[],this._compressed=new Set}_compressAttributes(e){let t=this._compressed,n=(e,t)=>{if(!e.userData?.__rayzeeExternal){t(e);for(let r of e.children)n(r,t)}};n(e,e=>{let n=e.geometry;if(!(!e.isMesh||!n||t.has(n.uuid))){t.add(n.uuid);for(let e of[`normal`,`tangent`,`color`]){let t=n.getAttribute(e);if(!t||t.normalized||!(t.array instanceof Float32Array)||n.morphAttributes?.[e]?.length)continue;let i=t.array,a=!0;for(let e=0;e<i.length;e++){let t=i[e];if(!(t>=-1.0001&&t<=1.0001)){a=!1;break}}if(!a)continue;let o=new Int16Array(i.length);for(let e=0;e<i.length;e++)o[e]=Math.round(Math.max(-1,Math.min(1,i[e]))*32767);n.setAttribute(e,new r.BufferAttribute(o,t.itemSize,!0))}}})}_shareInstanceMatrices(){for(let{mesh:e,start:t,count:n}of this._shareable){let r=e.instanceMatrix;!r||r.array.length!==n*16||(r.array=this.instanceMatrices.subarray(t*16,(t+n)*16))}this._shareable=[]}_countTriangles(e){let t=0;if(e.isMesh&&e.geometry&&e.material){let n=e.geometry.index,r=e.geometry.attributes.position;n?t+=Math.ceil(n.count/3):r&&(t+=Math.ceil(r.count/3))}if(e.children)for(let n of e.children)t+=this._countTriangles(n);return t}_ensureCapacity(e){if(e<=this._triangleCapacity)return;let t=this.triangles,n=this.currentTriangleIndex;this._allocateTriangles(e);for(let e=0;e<n;e++)this.triangles.chunkFor(e).set(t.chunkFor(e).subarray(t.baseOf(e),t.baseOf(e)+t.lanesPerRecord),this.triangles.baseOf(e));this._triangleCapacity=e}_allocateTriangles(e){this.triangles=new es(e,K.FLOATS_PER_TRIANGLE,Uint32Array,void 0,Xo),this.triangleFloatChunks=this.triangles.viewAs(Float32Array),this.triangleData=this.triangles.single,this.triangleFloats=this.triangleFloatChunks.single}traverseObject(e){if(e.isMesh?this.processMesh(e):e.isDirectionalLight?this.directionalLights.push(e):e.isCamera&&this.cameras.push(e),e.children)for(let t of e.children)this.traverseObject(t)}processMesh(e){if(!e.geometry||!e.material){console.warn(`Skipping mesh with missing geometry or material:`,e);return}let t=this.processMaterial(e.material);e.userData.materialIndex=t;let n=this.meshes.length;this.meshes.push(e),e.userData.meshIndex=n;let r=`${e.geometry.uuid}|${t}`,i=tc(e),a=!this._emissiveMaterial(t)&&!i,o=a?this._geometryRanges.get(r):null;if(o){let t={start:o.start,count:o.count,expandedStart:this.expandedTriangleCount,sharedFrom:o.meshIndex};this.expandedTriangleCount+=o.count,this.meshTriangleRanges.push(t),this._recordPlacements(e,n);return}let s=this.currentTriangleIndex,c=e.isInstancedMesh&&!i&&this._emissiveMaterial(t)&&this._canExpand(e),l=c||!e.isInstancedMesh&&!i&&(this._geometryUses.get(`${e.geometry.uuid}|${e.material?.uuid}`)===1||this._emissiveMaterial(t));this.extractGeometry(e,t,n,l,c);let u={start:s,count:this.currentTriangleIndex-s,expandedStart:this.expandedTriangleCount};this.expandedTriangleCount+=u.count,this.meshTriangleRanges.push(u),u.count>0&&!l&&a&&this._geometryRanges.set(r,{...u,meshIndex:n}),this._recordPlacements(e,n,l,c)}_recordPlacements(e,t,n=!1,r=!1){let i=e.matrixWorld.elements,a=this.instanceMatrices,o=this.instanceSource;if(!e.isInstancedMesh||!e.instanceMatrix||r){let r=this._nextPlacement();if(o[r]=t,n){for(let e=0;e<16;e++)a[r*16+e]=+(e%5==0);this.bakeInverse.set(t,Float32Array.from(this._matrixPool.mat4.copy(e.matrixWorld).invert().elements))}else for(let e=0;e<16;e++)a[r*16+e]=i[e];return}let s=e.instanceMatrix.array,c=e.count??s.length/16,l=Ys(i);l&&s.length===c*16&&this._shareable.push({mesh:e,start:this.instanceCount,count:c});for(let e=0;e<c;e++){let n=e*16,r=this._nextPlacement(),c=r*16;if(o[r]=t,l){for(let e=0;e<16;e++)a[c+e]=s[n+e];continue}for(let e=0;e<4;e++)for(let t=0;t<4;t++)a[c+e*4+t]=i[t]*s[n+e*4]+i[4+t]*s[n+e*4+1]+i[8+t]*s[n+e*4+2]+i[12+t]*s[n+e*4+3]}}_nextPlacement(){if(this.instanceCount>=this.instanceCapacity){let e=Math.max(16,this.instanceCapacity*2),t=new Int32Array(e),n=new Float32Array(e*16);t.set(this.instanceSource),n.set(this.instanceMatrices),this.instanceSource=t,this.instanceMatrices=n,this.instanceCapacity=e}return this.instanceCount++}_canExpand(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3,r=e.count??(e.instanceMatrix?.array.length??0)/16;return n*r<=ec?!0:(this._issues?.record(gs.EMISSIVE_INSTANCES_COLLAPSED,`"${e.name||`instanced mesh`}" would need ${Math.round(n*r).toLocaleString()} triangles to light every instance; lighting the first one only`,{instances:r,trianglesPerInstance:n,limit:ec}),!1)}_emissiveMaterial(e){let t=this.materials[e];if(!t||!(t.emissiveIntensity>0))return!1;let n=t.emissive;return!!n&&(n.r>0||n.g>0||n.b>0)}processMaterial(e){let t=this._materialUuidMap.get(e.uuid)??-1;if(t===-1){e.depthWrite===!1&&(e.depthWrite=!0,Rt(Ks,`depthWrite`,`material had depthWrite disabled — enabled for rastered rendering`));let n=this.createMaterialObject(e);this.materials.push(n),t=this.materials.length-1,this._materialUuidMap.set(e.uuid,t)}return t}getMaterialType(e){return e.isMeshPhysicalMaterial?`physical`:e.isMeshStandardMaterial?`standard`:e.isMeshPhongMaterial?`phong`:e.isMeshLambertMaterial?`lambert`:e.isMeshBasicMaterial?`basic`:e.isMeshToonMaterial?`toon`:`unknown`}getPhysicalDefaults(){return{emissive:new r.Color(0,0,0),emissiveIntensity:1,roughness:1,metalness:0,ior:1.5,opacity:1,transmission:0,thickness:.1,attenuationColor:new r.Color(16777215),attenuationDistance:1/0,dispersion:0,sheen:0,sheenRoughness:1,sheenColor:new r.Color(0),specularIntensity:1,specularColor:new r.Color(16777215),clearcoat:0,clearcoatRoughness:0,iridescence:0,iridescenceIOR:1.3,iridescenceThicknessRange:[100,400],normalScale:{x:1,y:1},bumpScale:1,displacementScale:1,alphaTest:0,subsurface:0,subsurfaceColor:new r.Color(16777215),subsurfaceRadius:[1,.2,.1],subsurfaceRadiusScale:1,subsurfaceAnisotropy:0,anisotropy:0,anisotropyRotation:0}}mapLegacyMaterialToPhysical(e,t){let n={};switch(t){case`basic`:n.emissive=e.color.clone(),n.emissiveIntensity=1,n.color=new r.Color(0),n.roughness=1,n.metalness=0;break;case`lambert`:n.roughness=1,n.metalness=0,n.specularIntensity=0;break;case`phong`:{let t=e.shininess||30;n.roughness=Math.sqrt(2/(t+2)),n.metalness=0}if(e.specular){let t=e.specular.r*.299+e.specular.g*.587+e.specular.b*.114;n.specularIntensity=Math.min(t*2,1),n.specularColor=e.specular.clone()}break;case`toon`:n.roughness=.9,n.metalness=0;break;case`standard`:case`physical`:break}return n}createMaterialObject(e){let t=this.getPhysicalDefaults(),n=this.getMaterialType(e),i=this.mapLegacyMaterialToPhysical(e,n),a=(e.transmission??0)>0,o=(e.metalness??i.metalness??0)>.1&&!a?2.5:t.ior,s=e.color||new r.Color(16777215);return n===`basic`&&!e.map&&(s=new r.Color(0)),{uuid:e.uuid,color:s,emissive:i.emissive??e.emissive??t.emissive,emissiveIntensity:i.emissiveIntensity??e.emissiveIntensity??t.emissiveIntensity,roughness:Math.max(.02,i.roughness??e.roughness??t.roughness),metalness:i.metalness??e.metalness??t.metalness,ior:e.ior??o,opacity:e.opacity??t.opacity,transmission:e.transmission??t.transmission,thickness:e.thickness??t.thickness,attenuationColor:e.attenuationColor??t.attenuationColor,attenuationDistance:e.attenuationDistance??t.attenuationDistance,dispersion:e.dispersion??t.dispersion,sheen:e.sheen??t.sheen,sheenRoughness:e.sheenRoughness??t.sheenRoughness,sheenColor:e.sheenColor??t.sheenColor,clearcoat:e.clearcoat??t.clearcoat,clearcoatRoughness:e.clearcoatRoughness??t.clearcoatRoughness,iridescence:e.iridescence??t.iridescence,iridescenceIOR:e.iridescenceIOR??t.iridescenceIOR,iridescenceThicknessRange:e.iridescenceThicknessRange??t.iridescenceThicknessRange,subsurface:e.subsurface??t.subsurface,subsurfaceColor:e.subsurfaceColor??t.subsurfaceColor,subsurfaceRadius:e.subsurfaceRadius??t.subsurfaceRadius,subsurfaceRadiusScale:e.subsurfaceRadiusScale??t.subsurfaceRadiusScale,subsurfaceAnisotropy:e.subsurfaceAnisotropy??t.subsurfaceAnisotropy,anisotropy:e.anisotropy??t.anisotropy,anisotropyRotation:e.anisotropyRotation??t.anisotropyRotation,specularIntensity:i.specularIntensity??e.specularIntensity??t.specularIntensity,specularColor:i.specularColor??e.specularColor??t.specularColor,normalScale:e.normalScale??t.normalScale,bumpScale:e.bumpScale??t.bumpScale,displacementScale:e.displacementScale??t.displacementScale,transparent:+!!e.transparent,alphaTest:e.alphaTest??t.alphaTest,alphaMode:Xs(e),side:this.getMaterialSide(e),depthWrite:e.depthWrite??!0?1:0,map:this.processTexture(e.map,this.maps),normalMap:this.processTexture(e.normalMap,this.normalMaps),bumpMap:this.processTexture(e.bumpMap,this.bumpMaps),roughnessMap:this.processTexture(e.roughnessMap,this.roughnessMaps),metalnessMap:this.processTexture(e.metalnessMap,this.metalnessMaps),emissiveMap:this.processTexture(e.emissiveMap,this.emissiveMaps),displacementMap:this.processTexture(e.displacementMap,this.displacementMaps),anisotropyMap:this.processTexture(e.anisotropyMap,this.anisotropyMaps),clearcoatMap:this.processTexture(e.clearcoatMap,this.clearcoatMaps),clearcoatRoughnessMap:this.processTexture(e.clearcoatRoughnessMap,this.clearcoatRoughnessMaps),transmissionMap:this.processTexture(e.transmissionMap,this.transmissionMaps),thicknessMap:this.processTexture(e.thicknessMap,[]),sheenColorMap:this.processTexture(e.sheenColorMap,this.sheenColorMaps),sheenRoughnessMap:this.processTexture(e.sheenRoughnessMap,this.sheenRoughnessMaps),specularIntensityMap:this.processTexture(e.specularIntensityMap,this.specularIntensityMaps),specularColorMap:this.processTexture(e.specularColorMap,this.specularColorMaps),iridescenceMap:this.processTexture(e.iridescenceMap,this.iridescenceMaps),iridescenceThicknessMap:this.processTexture(e.iridescenceThicknessMap,this.iridescenceThicknessMaps),mapMatrix:this.getTextureMatrix(e.map),normalMapMatrices:this.getTextureMatrix(e.normalMap),bumpMapMatrices:this.getTextureMatrix(e.bumpMap),roughnessMapMatrices:this.getTextureMatrix(e.roughnessMap),metalnessMapMatrices:this.getTextureMatrix(e.metalnessMap),emissiveMapMatrices:this.getTextureMatrix(e.emissiveMap),displacementMapMatrices:this.getTextureMatrix(e.displacementMap),originalType:n}}getTextureMatrix(e){return e?(e.matrixAutoUpdate&&e.updateMatrix(),e.matrix.elements):new r.Matrix3().elements}getMaterialSide(e){if(e.transmission>0)return 2;switch(e.side){case r.FrontSide:return 0;case r.BackSide:return 1;case r.DoubleSide:return 2;default:return 0}}processTexture(e,t){if(!e)return-1;let n=this._textureIndexCache.get(t);n||(n=new Map,this._textureIndexCache.set(t,n));let r=e.source.uuid,i=n.get(r);if(i!==void 0)return i;if(t.length<qs){t.push(e);let i=t.length-1;return n.set(r,i),i}return this._droppedTextures++,this._droppedTextures===1&&this._issues?.record(gs.TEXTURE_LIMIT_EXCEEDED,`scene needs more than ${qs} distinct textures for one map type; the rest render untextured`,{limit:qs,firstDropped:e.name||e.source?.uuid}),-1}extractGeometry(e,t,n,i=!1,a=!1){e.updateMatrix(),e.updateMatrixWorld();let o=e.geometry;o.attributes.normal||o.computeVertexNormals();let s=o.attributes.position,c=o.attributes.normal,l=o.attributes.uv,u=o.index?o.index.array:null,d=u?u.length/3:s.count/3;if(a){let i=e.count??e.instanceMatrix.array.length/16,a=this._matrixPool.mat4,o=new r.Matrix4;for(let f=0;f<i;f++){a.fromArray(e.instanceMatrix.array,f*16),o.multiplyMatrices(e.matrixWorld,a);let i=new r.Matrix3().getNormalMatrix(o);this.extractTrianglesInBatch(s,c,l,u,d,t,n,o,i,nc(o.elements)<0)}return}let f=i?this._matrixPool.mat4.copy(e.matrixWorld):null,p=i?this._matrixPool.mat3.getNormalMatrix(e.matrixWorld):null,m=i&&nc(f.elements)<0;this.extractTrianglesInBatch(s,c,l,u,d,t,n,f,p,m)}extractTrianglesInBatch(e,t,n,r,i,a,o,s=null,c=null,l=!1){for(;this.materialTriangleCounts.length<=a;)this.materialTriangleCounts.push(0);this.materialTriangleCounts[a]+=i;let u=this._getVec3(0),d=this._getVec3(1),f=this._getVec3(2),p=this._getVec3(3),m=this._getVec3(4),h=this._getVec3(5),g=this._getVec2(0),_=this._getVec2(1),v=this._getVec2(2);this._ensureCapacity(this.currentTriangleIndex+i);let y=s?.elements,b=c?.elements;for(let c=0;c<i;c++){let i=c*3,x=r?r[i+0]:i+0,S=l?2:1,C=l?1:2,w=r?r[i+S]:i+S,T=r?r[i+C]:i+C;this.getVertex(e,x,u),this.getVertex(e,w,d),this.getVertex(e,T,f),this.getVertex(t,x,p),this.getVertex(t,w,m),this.getVertex(t,T,h),n?(this.getVertex(n,x,g),this.getVertex(n,w,_),this.getVertex(n,T,v)):(g.set(0,0),_.set(0,0),v.set(0,0)),s&&(Qs(u,y),Qs(d,y),Qs(f,y),$s(p,b),$s(m,b),$s(h,b)),p.normalize(),m.normalize(),h.normalize(),this.packTriangleDataTextureFormat(this.currentTriangleIndex,u,d,f,p,m,h,g,_,v,a,o),this.currentTriangleIndex++}}packTriangleDataTextureFormat(e,t,n,r,i,a,o,s,c,l,u,d){let f=K,p=this.triangles.baseOf(e),m=this.triangleFloatChunks.chunkFor(e),h=this.triangles.chunkFor(e);m[p+f.POSITION_A_OFFSET+0]=t.x,m[p+f.POSITION_A_OFFSET+1]=t.y,m[p+f.POSITION_A_OFFSET+2]=t.z,h[p+f.NORMAL_A_PACKED_OFFSET]=Qe(i.x,i.y,i.z),m[p+f.POSITION_B_OFFSET+0]=n.x,m[p+f.POSITION_B_OFFSET+1]=n.y,m[p+f.POSITION_B_OFFSET+2]=n.z,h[p+f.NORMAL_B_PACKED_OFFSET]=Qe(a.x,a.y,a.z),m[p+f.POSITION_C_OFFSET+0]=r.x,m[p+f.POSITION_C_OFFSET+1]=r.y,m[p+f.POSITION_C_OFFSET+2]=r.z,h[p+f.NORMAL_C_PACKED_OFFSET]=Qe(o.x,o.y,o.z),m[p+f.UV_AB_OFFSET+0]=s.x,m[p+f.UV_AB_OFFSET+1]=s.y,m[p+f.UV_AB_OFFSET+2]=c.x,m[p+f.UV_AB_OFFSET+3]=c.y,m[p+f.UV_C_OFFSET+0]=l.x,m[p+f.UV_C_OFFSET+1]=l.y,h[p+f.MATERIAL_FLAGS_OFFSET]=Ze(u,this.materials[u]),h[p+f.MESH_INDEX_OFFSET]=d}getTriangleData(){return this.triangles?this.triangles.trimTo(this.currentTriangleIndex):null}getTriangleCount(){return this.currentTriangleIndex}getVertex(e,t,n){return e.itemSize===2?(n.x=e.getX(t),n.y=e.getY(t)):e.itemSize>=3&&(n.x=e.getX(t),n.y=e.getY(t),n.z=e.getZ(t)),n}logStats(){let e=this.currentTriangleIndex*K.FLOATS_PER_TRIANGLE*4;Ks.debug(Y.list([`${Y.count(this.currentTriangleIndex,`tri`)} (${Y.mb(e)})`,Y.count(this.materials.length,`material`),Y.count(this.maps.length,`map`)]))}extractMaterialsOnly(e){return this.resetArrays(),this._traverseMaterialsOnly(e),this.getExtractedData()}_traverseMaterialsOnly(e){if(e.isMesh&&e.geometry&&e.material){let t=this.processMaterial(e.material);e.userData.materialIndex=t;let n=this.meshes.length;this.meshes.push(e),e.userData.meshIndex=n}else e.isDirectionalLight?this.directionalLights.push(e):e.isCamera&&this.cameras.push(e);if(e.children)for(let t of e.children)this._traverseMaterialsOnly(t)}resetArrays(){this._droppedTextures=0,this.triangles=null,this.triangleData=null,this.triangleFloatChunks=null,this.triangleFloats=null,this.triangleCount=0,this.currentTriangleIndex=0,this.materials=[],this.materialTriangleCounts=[],this.meshes=[],this.meshTriangleRanges=[],this._geometryRanges=new Map,this.expandedTriangleCount=0,this._allocatePlacements(0),this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.roughnessMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this._materialUuidMap=new Map,this._textureIndexCache=new WeakMap}getExtractedData(){return{triangleData:this.getTriangleData(),triangleCount:this.getTriangleCount(),materials:this.materials,materialTriangleCounts:this.materialTriangleCounts,meshes:this.meshes,meshTriangleRanges:this.meshTriangleRanges,expandedTriangleCount:this.expandedTriangleCount,instanceSource:this.instanceSource.subarray(0,this.instanceCount),instanceMatrices:this.instanceMatrices.subarray(0,this.instanceCount*16),instanceCount:this.instanceCount,bakeInverse:this.bakeInverse,maps:this.maps,normalMaps:this.normalMaps,bumpMaps:this.bumpMaps,metalnessMaps:this.metalnessMaps,emissiveMaps:this.emissiveMaps,roughnessMaps:this.roughnessMaps,displacementMaps:this.displacementMaps,anisotropyMaps:this.anisotropyMaps,transmissionMaps:this.transmissionMaps,clearcoatMaps:this.clearcoatMaps,clearcoatRoughnessMaps:this.clearcoatRoughnessMaps,sheenColorMaps:this.sheenColorMaps,sheenRoughnessMaps:this.sheenRoughnessMaps,iridescenceMaps:this.iridescenceMaps,iridescenceThicknessMaps:this.iridescenceThicknessMaps,specularIntensityMaps:this.specularIntensityMaps,specularColorMaps:this.specularColorMaps,directionalLights:this.directionalLights,cameras:this.cameras}}},ic=class{constructor(){this.maxLeafSize=8}build(e){let t=e.length;if(t===0){let e=new Float32Array(16);return e[7]=1,e[14]=1,e[15]=-1,{nodeData:e,nodeCount:1,sortedPerm:new Int32Array,bitTrails:new Float32Array}}let n=new Int32Array(t);for(let e=0;e<t;e++)n[e]=e;let r=2*t+4,i=new Float32Array(r*16),a=0,o=new Float32Array(t),s=(t,r,c,l)=>{let u=a++,d=u*16,f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0,v=0,y=1/0,b=1/0,x=1/0,S=-1/0,C=-1/0,w=-1/0;for(let i=t;i<r;i++){let t=e[n[i]];f=Math.min(f,t.bMinX),p=Math.min(p,t.bMinY),m=Math.min(m,t.bMinZ),h=Math.max(h,t.bMaxX),g=Math.max(g,t.bMaxY),_=Math.max(_,t.bMaxZ),v+=t.power,y=Math.min(y,t.cx),b=Math.min(b,t.cy),x=Math.min(x,t.cz),S=Math.max(S,t.cx),C=Math.max(C,t.cy),w=Math.max(w,t.cz)}i[d+0]=f,i[d+1]=p,i[d+2]=m,i[d+3]=v,i[d+4]=h,i[d+5]=g,i[d+6]=_;let T=r-t,E;if(T<=this.maxLeafSize){i[d+7]=1,i[d+8]=t,i[d+9]=T,i[d+10]=0,i[d+11]=0,E=null;for(let i=t;i<r;i++){let t=e[n[i]];E=oc(E,ac(t)),o[i]=c}E||={ax:0,ay:0,az:1,cosO:-1}}else{let a=S-y,o=C-b,u=w-x,f;f=a>=o&&a>=u?0:o>=u?1:2;let p=[`cx`,`cy`,`cz`][f],m=t+r>>1;this._nthElement(n,e,t,r,m,p),i[d+7]=0;let h=s(t,m,c,l+1),g=s(m,r,c+2**l,l+1);i[d+8]=h.nodeIndex,i[d+9]=g.nodeIndex,i[d+10]=0,i[d+11]=0,E=oc(h.cone,g.cone)}return i[d+12]=E.ax,i[d+13]=E.ay,i[d+14]=E.az,i[d+15]=E.cosO,{nodeIndex:u,cone:E}};s(0,t,0,0);let c=new Int32Array(t);for(let e=0;e<t;e++)c[e]=n[e];let l=new Float32Array(a*16);return l.set(i.subarray(0,a*16)),console.log(`[LightBVHBuilder] Built BVH: ${a} nodes for ${t} emissive triangles`),{nodeData:l,nodeCount:a,sortedPerm:c,bitTrails:o}}_nthElement(e,t,n,r,i,a){for(;n<r-1;){let o=n+r>>1,s=t[e[o]][a],c=e[o];e[o]=e[r-1],e[r-1]=c;let l=n;for(let i=n;i<r-1;i++)t[e[i]][a]<s&&(c=e[i],e[i]=e[l],e[l]=c,l++);if(c=e[l],e[l]=e[r-1],e[r-1]=c,l===i)return;l<i?n=l+1:r=l}}};function ac(e){return e.twoSided?{ax:e.nx,ay:e.ny,az:e.nz,cosO:-1}:{ax:e.nx,ay:e.ny,az:e.nz,cosO:1}}function oc(e,t){if(!e)return t;if(!t||e.cosO<=-1)return e;if(t.cosO<=-1)return t;let n=Math.min(Math.max(e.cosO,-1),1),r=Math.min(Math.max(t.cosO,-1),1),i=Math.acos(n),a=Math.acos(r),o=Math.min(Math.max(e.ax*t.ax+e.ay*t.ay+e.az*t.az,-1),1),s=Math.acos(o);if(Math.min(s+a,Math.PI)<=i)return e;if(Math.min(s+i,Math.PI)<=a)return t;let c=(i+a+s)*.5;if(c>=Math.PI)return{ax:e.ax,ay:e.ay,az:e.az,cosO:-1};let l=c-i,u=e.ay*t.az-e.az*t.ay,d=e.az*t.ax-e.ax*t.az,f=e.ax*t.ay-e.ay*t.ax,p=Math.sqrt(u*u+d*d+f*f);if(p<1e-8)return{ax:e.ax,ay:e.ay,az:e.az,cosO:-1};u/=p,d/=p,f/=p;let m=Math.cos(l),h=Math.sin(l),g=u*e.ax+d*e.ay+f*e.az,_=d*e.az-f*e.ay,v=f*e.ax-u*e.az,y=u*e.ay-d*e.ax,b=e.ax*m+_*h+u*g*(1-m),x=e.ay*m+v*h+d*g*(1-m),S=e.az*m+y*h+f*g*(1-m),C=Math.sqrt(b*b+x*x+S*S)||1;return{ax:b/C,ay:x/C,az:S/C,cosO:Math.cos(c)}}var sc=It(`emissive`),cc=class{constructor(){this.emissiveTriangles=[],this.emissiveCount=0,this.totalEmissivePower=0,this.emissiveIndicesArray=null,this.emissivePowerArray=null,this.cdfArray=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._totalTriangleCount=0,this._hiddenMeshes=new Set}extractEmissiveTriangles(e,t,n,r=null){this.emissiveTriangles=[],this.totalEmissivePower=0,this._totalTriangleCount=n;let i=K.FLOATS_PER_TRIANGLE,a=K.MATERIAL_FLAGS_OFFSET,o=K.MESH_INDEX_OFFSET,s=e&&e.chunks?e:null,c=s?s.viewAs(Float32Array):null,l=s?null:e,u=s?null:new Float32Array(e.buffer,e.byteOffset,e.length);for(let e=0;e<n;e++){let n=s?s.chunkFor(e):l,d=s?c.chunkFor(e):u,f=s?s.baseOf(e):e*i,p=n[f+a]&Ye,m=n[f+o],h=t[p];if(!h)continue;let g=h.emissive||{r:0,g:0,b:0},_=h.emissiveIntensity||0;if(_>0&&(g.r>0||g.g>0||g.b>0)){let t=r?.placementRunOf?.(m)?.start??-1,n=t>=0&&r.isSet[t],i=n?r.world:null,a=n?t*16:0,o=(e,t,n)=>i?i[a]*e+i[a+4]*t+i[a+8]*n+i[a+12]:e,s=(e,t,n)=>i?i[a+1]*e+i[a+5]*t+i[a+9]*n+i[a+13]:t,c=(e,t,n)=>i?i[a+2]*e+i[a+6]*t+i[a+10]*n+i[a+14]:n,l=d[f+0],u=d[f+1],v=d[f+2],y=d[f+4],b=d[f+5],x=d[f+6],S=d[f+8],C=d[f+9],w=d[f+10],T=o(l,u,v),E=s(l,u,v),D=c(l,u,v),O=o(y,b,x),k=s(y,b,x),A=c(y,b,x),j=o(S,C,w),M=s(S,C,w),N=c(S,C,w),P=this._calculateTriangleArea(T,E,D,O,k,A,j,M,N),F=(.2126*g.r+.7152*g.g+.0722*g.b)*_*P,I=(k-E)*(N-D)-(A-D)*(M-E),L=(A-D)*(j-T)-(O-T)*(N-D),R=(O-T)*(M-E)-(k-E)*(j-T),ee=Math.sqrt(I*I+L*L+R*R)||1,z=h.side===1?-1:1;I=I/ee*z,L=L/ee*z,R=R/ee*z;let te=h.side===2,ne=(T+O+j)/3,B=(E+k+M)/3,re=(D+A+N)/3,ie=Math.min(T,O,j),ae=Math.min(E,k,M),oe=Math.min(D,A,N),se=Math.max(T,O,j),ce=Math.max(E,k,M),le=Math.max(D,A,N);this.emissiveTriangles.push({triangleIndex:e,materialIndex:p,meshIndex:m,instanceLeaf:n?r.tlasLeafIndex[t]:-1,power:F,area:P,emissive:{r:g.r,g:g.g,b:g.b},emissiveIntensity:_,cx:ne,cy:B,cz:re,bMinX:ie,bMinY:ae,bMinZ:oe,bMaxX:se,bMaxY:ce,bMaxZ:le,nx:I,ny:L,nz:R,twoSided:te}),this.totalEmissivePower+=F}}return this.emissiveCount=this.emissiveTriangles.length,this.emissiveCount>0&&sc.debug(`${Y.n(this.emissiveCount)} emissive tris (${(this.emissiveCount/n*100).toFixed(2)}%) · total power ${this.totalEmissivePower.toFixed(2)}`),this._buildDataArrays(),this.emissiveCount}_calculateTriangleArea(e,t,n,r,i,a,o,s,c){let l=r-e,u=i-t,d=a-n,f=o-e,p=s-t,m=c-n,h=u*m-d*p,g=d*f-l*m,_=l*p-u*f;return Math.sqrt(h*h+g*g+_*_)*.5}_buildDataArrays(){this.emissiveIndicesArray=new Int32Array(this.emissiveCount),this.emissivePowerArray=new Float32Array(this.emissiveCount);for(let e=0;e<this.emissiveCount;e++)this.emissiveIndicesArray[e]=this.emissiveTriangles[e].triangleIndex,this.emissivePowerArray[e]=this.emissiveTriangles[e].power;this._buildCDF()}_buildCDF(){if(this.emissiveCount===0){this.cdfArray=new Float32Array(1),this.cdfArray[0]=0;return}this.cdfArray=new Float32Array(this.emissiveCount);let e=0;for(let t=0;t<this.emissiveCount;t++)e+=this.emissivePowerArray[t],this.cdfArray[t]=e;if(e>0)for(let t=0;t<this.emissiveCount;t++)this.cdfArray[t]/=e}sampleCDF(e){if(this.emissiveCount===0)return-1;if(this.emissiveCount===1)return 0;let t=0,n=this.emissiveCount-1;for(;t<n;){let r=Math.floor((t+n)/2);this.cdfArray[r]<e?t=r+1:n=r}return t}getGPUData(){return{emissiveIndices:this.emissiveIndicesArray,emissivePower:this.emissivePowerArray,emissiveCDF:this.cdfArray,emissiveCount:this.emissiveCount,totalPower:this.totalEmissivePower}}createEmissiveTexture(){if(this.emissiveCount===0)return new r.DataTexture(new Float32Array(4),1,1,r.RGBAFormat,r.FloatType);let e=new Float32Array(this.emissiveCount*4);for(let t=0;t<this.emissiveCount;t++){let n=t*4;e[n+0]=this.emissiveIndicesArray[t],e[n+1]=this.emissivePowerArray[t],e[n+2]=this.cdfArray[t],e[n+3]=0}let t=Math.ceil(Math.sqrt(this.emissiveCount)),n=Math.ceil(this.emissiveCount/t),i=t*n*4,a=new Float32Array(i);a.set(e);let o=new r.DataTexture(a,t,n,r.RGBAFormat,r.FloatType);return o.needsUpdate=!0,o.generateMipmaps=!1,o.minFilter=r.NearestFilter,o.magFilter=r.NearestFilter,sc.debug(`emissive texture ${Y.px(t,n)} · ${Y.n(this.emissiveCount)} entries`),o}createEmissiveRawData(){if(this.emissiveCount===0)return new Float32Array(8);let e=new Float32Array(this.emissiveCount*8);for(let t=0;t<this.emissiveCount;t++){let n=this.emissiveTriangles[t],r=t*8;e[r+0]=n.triangleIndex,e[r+1]=n.power,e[r+2]=this.cdfArray[t],e[r+3]=n.instanceLeaf,e[r+4]=n.emissive.r*n.emissiveIntensity,e[r+5]=n.emissive.g*n.emissiveIntensity,e[r+6]=n.emissive.b*n.emissiveIntensity,e[r+7]=n.area}return sc.debug(`emissive raw data ${Y.n(this.emissiveCount)} entries (${Y.mb(e.byteLength)})`),e}getStats(){if(this.emissiveCount===0)return{count:0,totalPower:0,averagePower:0,minPower:0,maxPower:0};let e=1/0,t=-1/0;for(let n=0;n<this.emissiveCount;n++){let r=this.emissivePowerArray[n];e=Math.min(e,r),t=Math.max(t,r)}return{count:this.emissiveCount,totalPower:this.totalEmissivePower,averagePower:this.totalEmissivePower/this.emissiveCount,minPower:e,maxPower:t}}updateMaterialEmissive(e,t,n,r,i){let a=t.emissive||{r:0,g:0,b:0},o=t.emissiveIntensity||0,s=o>0&&(a.r>0||a.g>0||a.b>0);if(s!==this.emissiveTriangles.some(t=>t.materialIndex===e))return this.extractEmissiveTriangles(n,r,i),!0;if(!s)return!1;let c=.2126*a.r+.7152*a.g+.0722*a.b;for(let t of this.emissiveTriangles)t.materialIndex===e&&(t.power=c*o*t.area,t.emissive={r:a.r,g:a.g,b:a.b},t.emissiveIntensity=o);return!0}setHiddenMeshes(e){let t=new Set;for(let e of this.emissiveTriangles)t.add(e.meshIndex);let n=new Set;for(let r of e)t.has(r)&&n.add(r);let r=this._hiddenMeshes,i=n.size!==r.size;if(!i){for(let e of n)if(!r.has(e)){i=!0;break}}return this._hiddenMeshes=n,i}buildLightBVH(){let e=this._hiddenMeshes.size===0?this.emissiveTriangles:this.emissiveTriangles.filter(e=>!this._hiddenMeshes.has(e.meshIndex));this.emissiveCount=e.length,this.totalEmissivePower=0;for(let t of e)this.totalEmissivePower+=t.power;if(e.length===0)return this.lightBVHNodeData=new Float32Array(16),this.lightBVHNodeData[7]=1,this.lightBVHNodeData[14]=1,this.lightBVHNodeData[15]=-1,this.lightBVHNodeCount=1,this.emissiveBitTrailMap=new Float32Array(Math.max(this._totalTriangleCount,1)).fill(-1),this.emissiveIndicesArray=new Int32Array,this.emissivePowerArray=new Float32Array,this._buildCDF(),this.emissiveTriangleData=new Float32Array(8),1;let{nodeData:t,nodeCount:n,sortedPerm:r,bitTrails:i}=new ic().build(e);this.lightBVHNodeData=t,this.lightBVHNodeCount=n,this._rebuildSortedEmissiveData(r,e),this.emissiveBitTrailMap=new Float32Array(Math.max(this._totalTriangleCount,1)).fill(-1);for(let t=0;t<r.length;t++){let n=e[r[t]].triangleIndex;this.emissiveBitTrailMap[n]=i[t]}return n}_rebuildSortedEmissiveData(e,t){let n=e.length;this.emissiveIndicesArray=new Int32Array(n),this.emissivePowerArray=new Float32Array(n);for(let r=0;r<n;r++){let n=e[r];this.emissiveIndicesArray[r]=t[n].triangleIndex,this.emissivePowerArray[r]=t[n].power}this._buildCDF();let r=new Float32Array(n*8);for(let i=0;i<n;i++){let n=t[e[i]],a=i*8;r[a+0]=n.triangleIndex,r[a+1]=n.power,r[a+2]=this.cdfArray[i],r[a+3]=n.instanceLeaf,r[a+4]=n.emissive.r*n.emissiveIntensity,r[a+5]=n.emissive.g*n.emissiveIntensity,r[a+6]=n.emissive.b*n.emissiveIntensity,r[a+7]=n.area}this.emissiveTriangleData=r,sc.debug(`rebuilt sorted emissive data · ${Y.n(n)} entries`)}clear(){this.emissiveTriangles=[],this.emissiveCount=0,this.totalEmissivePower=0,this.emissiveIndicesArray=null,this.emissivePowerArray=null,this.cdfArray=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._totalTriangleCount=0,this._hiddenMeshes=new Set}},lc=class{constructor(e=`Build`,{namespace:t=`build`,level:n=`debug`}={}){this.label=e,this.level=n,this.logger=It(t),this.entries=new Map,this.order=[],this.totalStart=performance.now()}start(e){return this.entries.set(e,{start:performance.now(),end:null}),this.order.includes(e)||this.order.push(e),this}end(e){let t=this.entries.get(e);return t&&(t.end=performance.now(),t.duration=t.end-t.start),this}getDuration(e){return this.entries.get(e)?.duration??0}print(e=[]){let t=performance.now()-this.totalStart,n=this.order.map(e=>{let t=this.entries.get(e)?.duration??0;return t>=1?`${e} ${Math.round(t)}ms`:null}).filter(Boolean),r=Y.list([this.label,...e,Y.ms(t)]);return this.level===`info`?this.logger.summary(r,n):this.logger.debug(Y.list([r,n.join(` · `)])),{steps:Object.fromEntries(this.order.map(e=>[e,Math.round(this.entries.get(e)?.duration??0)])),total:Math.round(t)}}},uc="const e={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11},t=e.FLOATS_PER_TRIANGLE,n=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),r=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),i=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):r(e)}},a=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,o=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,s=(e,t)=>e.chunked?e.chunked.baseOf(t):t*u,c=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):n(e),u:t?e:r(e)}};function l(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}const u=16,d=1073741824;function f(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=1e-12*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>z&&(z=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=z}var p=class{constructor(){this._bounds=null,this._boundsNodeCount=0}updateTrianglePositions(n,r,i){let a=i.length,o=c(n);for(let n=0;n<a;n++){let a=i[n],s=o.chunked?o.f.chunkFor(n):o.f,c=o.chunked?o.u.chunkFor(n):o.u,u=o.chunked?o.chunked.baseOf(n):n*t,d=a*9,f=r[d],p=r[d+1],m=r[d+2],h=r[d+3],g=r[d+4],_=r[d+5],v=r[d+6],y=r[d+7],b=r[d+8];s[u+e.POSITION_A_OFFSET]=f,s[u+e.POSITION_A_OFFSET+1]=p,s[u+e.POSITION_A_OFFSET+2]=m,s[u+e.POSITION_B_OFFSET]=h,s[u+e.POSITION_B_OFFSET+1]=g,s[u+e.POSITION_B_OFFSET+2]=_,s[u+e.POSITION_C_OFFSET]=v,s[u+e.POSITION_C_OFFSET+1]=y,s[u+e.POSITION_C_OFFSET+2]=b;let x=h-f,S=g-p,C=_-m,w=v-f,T=y-p,E=b-m,D=l(S*E-C*T,C*w-x*E,x*T-S*w);c[u+e.NORMAL_A_PACKED_OFFSET]=D,c[u+e.NORMAL_B_PACKED_OFFSET]=D,c[u+e.NORMAL_C_PACKED_OFFSET]=D}}refitRange(n,r,l,u){let f=c(r);u>this._boundsNodeCount&&(this._bounds=new Float32Array(u*6),this._boundsNodeCount=u);let p=this._bounds,m=l+u,h=i(n);for(let n=m-1;n>=l;n--){let r=a(h,n),i=o(h,n),c=s(h,n),u=(n-l)*6;if(i[c+3]===d){let n=i[c],r=i[c+1],a=1/0,o=1/0,s=1/0,l=-1/0,d=-1/0,m=-1/0;for(let i=0;i<r;i++){let r=n+i,c=f.chunked?f.f.chunkFor(r):f.f,u=f.chunked?f.chunked.baseOf(r):r*t,p=c[u+e.POSITION_A_OFFSET],h=c[u+e.POSITION_A_OFFSET+1],g=c[u+e.POSITION_A_OFFSET+2],_=c[u+e.POSITION_B_OFFSET],v=c[u+e.POSITION_B_OFFSET+1],y=c[u+e.POSITION_B_OFFSET+2],b=c[u+e.POSITION_C_OFFSET],x=c[u+e.POSITION_C_OFFSET+1],S=c[u+e.POSITION_C_OFFSET+2];a=Math.min(a,p,_,b),o=Math.min(o,h,v,x),s=Math.min(s,g,y,S),l=Math.max(l,p,_,b),d=Math.max(d,h,v,x),m=Math.max(m,g,y,S)}p[u]=a,p[u+1]=o,p[u+2]=s,p[u+3]=l,p[u+4]=d,p[u+5]=m}else{let e=i[c+3],t=i[c+7],n=(e-l)*6,a=(t-l)*6,o=p[n],s=p[n+1],d=p[n+2],f=p[n+3],m=p[n+4],h=p[n+5],g=p[a],_=p[a+1],v=p[a+2],y=p[a+3],b=p[a+4],x=p[a+5];r[c]=o,r[c+1]=s,r[c+2]=d,r[c+4]=f,r[c+5]=m,r[c+6]=h,r[c+8]=g,r[c+9]=_,r[c+10]=v,r[c+12]=y,r[c+13]=b,r[c+14]=x,p[u]=Math.min(o,g),p[u+1]=Math.min(s,_),p[u+2]=Math.min(d,v),p[u+3]=Math.max(f,y),p[u+4]=Math.max(m,b),p[u+5]=Math.max(h,x)}}}refit(n,r,l){let u=c(r);l!==this._boundsNodeCount&&(this._bounds=new Float32Array(l*6),this._boundsNodeCount=l);let p=this._bounds,m=i(n);for(let n=l-1;n>=0;n--){let r=a(m,n),i=o(m,n),c=s(m,n),l=n*6,h=i[c+3];if(h===d){let n=i[c],r=i[c+1],a=1/0,o=1/0,s=1/0,d=-1/0,f=-1/0,m=-1/0;for(let i=0;i<r;i++){let r=n+i,c=u.chunked?u.f.chunkFor(r):u.f,l=u.chunked?u.chunked.baseOf(r):r*t,p=c[l+e.POSITION_A_OFFSET],h=c[l+e.POSITION_A_OFFSET+1],g=c[l+e.POSITION_A_OFFSET+2],_=c[l+e.POSITION_B_OFFSET],v=c[l+e.POSITION_B_OFFSET+1],y=c[l+e.POSITION_B_OFFSET+2],b=c[l+e.POSITION_C_OFFSET],x=c[l+e.POSITION_C_OFFSET+1],S=c[l+e.POSITION_C_OFFSET+2];a=Math.min(a,p,_,b),o=Math.min(o,h,v,x),s=Math.min(s,g,y,S),d=Math.max(d,p,_,b),f=Math.max(f,h,v,x),m=Math.max(m,g,y,S)}p[l]=a,p[l+1]=o,p[l+2]=s,p[l+3]=d,p[l+4]=f,p[l+5]=m}else if(h===1073741825)f(r,c,p,i[c]*6,p,l);else{let e=i[c+3],t=i[c+7],n=e*6,a=t*6,o=p[n],s=p[n+1],u=p[n+2],d=p[n+3],f=p[n+4],m=p[n+5],h=p[a],g=p[a+1],_=p[a+2],v=p[a+3],y=p[a+4],b=p[a+5];r[c]=o,r[c+1]=s,r[c+2]=u,r[c+4]=d,r[c+5]=f,r[c+6]=m,r[c+8]=h,r[c+9]=g,r[c+10]=_,r[c+12]=v,r[c+13]=y,r[c+14]=b,p[l]=Math.min(o,h),p[l+1]=Math.min(s,g),p[l+2]=Math.min(u,_),p[l+3]=Math.max(d,v),p[l+4]=Math.max(f,y),p[l+5]=Math.max(m,b)}}}};const m=64*1024*1024;function h(e,t,n){return n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t)}var g=class e{constructor(e,t,n,r=m,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push(h(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push(h(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=m,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=h(this.LaneType,n,this.shared);for(let t of this._views)t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)this.chunks[e]||this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0;return this.chunks[t]??this._materialize(t)}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,this._views&&(r._owner=this,this._views.push(r)),r}};const _=new p;let v=null,y=null,b=0;self.onmessage=function(e){let{type:t}=e.data;if(t===`init`){v=g.adopt(e.data.sharedBvhBufs.map(e=>new Float32Array(e)),e.data.bvhRecordCount,16,e.data.bvhRecordsPerChunk),y=g.adopt(e.data.sharedTriBufs.map(e=>new Uint32Array(e)),e.data.triRecordCount,e.data.triLanesPerRecord,e.data.triRecordsPerChunk),b=v.recordCount;return}if(t===`refit`)try{let e=performance.now();_.refit(v,y,b),self.postMessage({type:`refitComplete`,refitTimeMs:performance.now()-e})}catch(e){console.error(`[BVHRefitWorker] Refit error:`,e),self.postMessage({type:`error`,error:e.message})}};",dc=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,uc],{type:`text/javascript;charset=utf-8`});function fc(e){let t;try{if(t=dc&&(self.URL||self.webkitURL).createObjectURL(dc),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(uc),{type:`module`,name:e?.name})}}var pc="const e=Object.freeze({viewer:Object.freeze({areaLightIntensityScale:.1,environmentRotation:270,toneMapping:4,saturation:1.2}),physical:Object.freeze({areaLightIntensityScale:1,environmentRotation:0,toneMapping:6,saturation:1})}),t={resolution:512,canvasWidth:512,canvasHeight:512,maxTextureSize:4096,toneMapping:e.viewer.toneMapping,exposure:1,saturation:e.viewer.saturation,enableEnvironment:!0,showBackground:!0,transparentBackground:!1,environmentIntensity:1,backgroundIntensity:1,backgroundColor:`#000000`,backgroundBlurriness:0,backgroundBlurSamples:8,environmentRotation:e.viewer.environmentRotation,groundProjectionEnabled:!1,groundProjectionRadius:100,groundProjectionHeight:15,groundProjectionLevel:0,enableGroundCatcher:!1,groundCatcherHeight:0,globalIlluminationIntensity:1,environmentMode:`hdri`,gradientZenithColor:`#0077BE`,gradientHorizonColor:`#87CEEB`,gradientGroundColor:`#654321`,solidSkyColor:`#87CEEB`,skySunAzimuth:90,skySunElevation:20,skySunIntensity:15,skyRayleighDensity:.9,skyTurbidity:.8,skyMieAnisotropy:.76,skyPreset:`clearMorning`,cameraProjection:`perspective`,panoramaLonRange:[-180,180],panoramaLatRange:[-90,90],panoramaLevelHorizon:!0,enableDOF:!1,fov:55,focusDistance:.8,aperture:5.6,focalLength:50,apertureScale:1,anamorphicRatio:1,autoFocusMode:`auto`,afScreenPoint:{x:.5,y:.5},afSmoothingFactor:.15,enablePathTracer:!0,enableAccumulation:!0,pauseRendering:!1,maxSamples:60,bounces:3,transmissiveBounces:5,maxSubsurfaceSteps:8,maxTransparentBounces:32,useAdaptiveSampling:!0,noiseThreshold:.1,adaptiveMinSamples:8,adaptiveStopFraction:.9,usePixelFreeze:!0,pixelFreezeThreshold:.02,pixelFreezeStability:8,convergenceOverlay:!1,samplingTechnique:2,enableEmissiveTriangleSampling:!1,emissiveBoost:1,fireflyThreshold:3,wavefrontSortMaterials:!0,renderLimitMode:`frames`,renderTimeLimit:30,renderMode:0,enableAlphaShadows:!1,tilesHelper:!0,showLightHelper:!1,directionalLightIntensity:0,directionalLightColor:`#ffffff`,directionalLightPosition:[1,1,1],directionalLightAngle:0,filterStrength:1,edgeAtrousIterations:5,edgePhiLuminance:4,edgePhiNormal:64,edgePhiDepth:.1,enableOIDN:!1,oidnQuality:`fast`,continuousDenoise:!1,continuousDenoiseInterval:8,enableUpscaler:!1,upscalerScale:2,upscalerQuality:`fast`,upscalerHdr:!0,debugMode:0,debugThreshold:100,debugModel:0,enableBloom:!1,bloomStrength:.2,bloomRadius:.15,bloomThreshold:.85,interactionModeEnabled:!0,debugVisScale:100,denoiserStrategy:`none`,enableASVGF:!1,asvgfTemporalAlpha:.1,asvgfAtrousIterations:8,asvgfPhiColor:10,asvgfPhiNormal:128,asvgfPhiDepth:1,asvgfVarianceBoost:1,asvgfMaxAccumFrames:32,asvgfGradientStrength:1,asvgfGradientSigmaScale:2,asvgfGradientNoiseFloor:0,asvgfDebugMode:0,asvgfQualityPreset:`medium`,showAsvgfHeatmap:!1,nrdQualityPreset:`medium`,nrdDebugMode:0,autoExposure:!1,autoExposureKeyValue:.18,autoExposureMinExposure:.1,autoExposureMaxExposure:20,autoExposureAdaptSpeedBright:3,autoExposureAdaptSpeedDark:.5};t.fov,t.focusDistance,t.aperture,t.focalLength;const n={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826};function r(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function i(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}Math.min(typeof navigator<`u`&&navigator.hardwareConcurrency||4,6),t.maxSamples,t.bounces,t.renderMode,t.enableAlphaShadows,t.transmissiveBounces,t.maxSubsurfaceSteps;const a=Float64Array.from([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function o(e,t){return e[t]*(e[t+5]*e[t+10]-e[t+6]*e[t+9])-e[t+4]*(e[t+1]*e[t+10]-e[t+2]*e[t+9])+e[t+8]*(e[t+1]*e[t+6]-e[t+2]*e[t+5])}function s(e,t,n){let r=o(e,t);if(!Number.isFinite(r)||Math.abs(r)<1e-20)return n.set(a),n;let i=1/r;return n[0]=(e[t+5]*e[t+10]-e[t+6]*e[t+9])*i,n[1]=(e[t+2]*e[t+9]-e[t+1]*e[t+10])*i,n[2]=(e[t+1]*e[t+6]-e[t+2]*e[t+5])*i,n[3]=0,n[4]=(e[t+6]*e[t+8]-e[t+4]*e[t+10])*i,n[5]=(e[t]*e[t+10]-e[t+2]*e[t+8])*i,n[6]=(e[t+2]*e[t+4]-e[t]*e[t+6])*i,n[7]=0,n[8]=(e[t+4]*e[t+9]-e[t+5]*e[t+8])*i,n[9]=(e[t+1]*e[t+8]-e[t]*e[t+9])*i,n[10]=(e[t]*e[t+5]-e[t+1]*e[t+4])*i,n[11]=0,n[12]=-(n[0]*e[t+12]+n[4]*e[t+13]+n[8]*e[t+14]),n[13]=-(n[1]*e[t+12]+n[5]*e[t+13]+n[9]*e[t+14]),n[14]=-(n[2]*e[t+12]+n[6]*e[t+13]+n[10]*e[t+14]),n[15]=1,n}function c(e,t){for(let n=0;n<16;n++)if(e[t+n]!==a[n])return!1;return!0}const l=e=>e<32?e:32,u=new Float64Array(16);var d=class e{constructor(){this._flatBuffer=null,this._flatBufferCapacity=0,this._binCounts=new Int32Array(96),this._binBounds=new Float64Array(576),this._binSuffix=new Float64Array(32),this._binSuffixCount=new Int32Array(32),this._order=null,this._stackI=null,this._stackB=null,this._stackFrames=0,this._sortScratch=[],this._suffix=null,this._bounds=new Float64Array(12),this._extent=new Float64Array(3),this._cMin=new Float64Array(3)}static nodeCountFor(e){return e>0?e*2-1:0}releaseFlattenBuffer(){this._flatBuffer=null,this._flatBufferCapacity=0}build(t){let n=new Float64Array(t.count*6);t.writeWorldAABBs(n);let r=this.buildStructure(n,t.count);return e.fillLeaves(r.data,r.nodeCount,t),r}buildStructure(t,a){let o=e.nodeCountFor(a);if(a===0)return{data:new Float32Array,nodeCount:0};i(o,`TLAS node count`);let s=o*16;s>this._flatBufferCapacity&&(this._flatBuffer=new Float32Array(s),this._flatBufferCapacity=s);let c=this._flatBuffer,l=r(c);(!this._order||this._order.length<a)&&(this._order=new Int32Array(a));let u=this._order;for(let e=0;e<a;e++)u[e]=e;this._ensureStack(64);let d=0,f=0,p=0,m=a,h=this._bounds;this._rangeBounds(t,u,p,m,h,0);let g=h[0],_=h[1],v=h[2],y=h[3],b=h[4],x=h[5];for(;;){if(m-p===1){let e=f*16;l[e]=0,l[e+1]=u[p],c[e+2]=0,l[e+3]=n.BLAS_POINTER_LEAF}else{let e=this._partition(t,u,p,m,g,_,v,y,b,x),n=e-p,r=f+1,i=r+(n*2-1),a=f*16;c[a]=h[0],c[a+1]=h[1],c[a+2]=h[2],l[a+3]=r,c[a+4]=h[3],c[a+5]=h[4],c[a+6]=h[5],l[a+7]=i,c[a+8]=h[6],c[a+9]=h[7],c[a+10]=h[8],c[a+11]=0,c[a+12]=h[9],c[a+13]=h[10],c[a+14]=h[11],c[a+15]=0;let o=n<=m-e,s=o?0:6,S=o?6:0;d=this._push(d,o?i:r,o?e:p,o?m:e,h,S),f=o?r:i,o?m=e:p=e,g=h[s],_=h[s+1],v=h[s+2],y=h[s+3],b=h[s+4],x=h[s+5];continue}if(d===0)break;d--;let e=d*3,r=d*6;f=this._stackI[e],p=this._stackI[e+1],m=this._stackI[e+2],g=this._stackB[r],_=this._stackB[r+1],v=this._stackB[r+2],y=this._stackB[r+3],b=this._stackB[r+4],x=this._stackB[r+5]}return{data:c.subarray(0,s),nodeCount:o}}_push(e,t,n,r,i,a){e>=this._stackFrames&&this._ensureStack(this._stackFrames*2);let o=e*3,s=e*6;this._stackI[o]=t,this._stackI[o+1]=n,this._stackI[o+2]=r;for(let e=0;e<6;e++)this._stackB[s+e]=i[a+e];return e+1}_ensureStack(e){if(this._stackFrames>=e)return;let t=new Int32Array(e*3),n=new Float64Array(e*6);this._stackI&&(t.set(this._stackI),n.set(this._stackB)),this._stackI=t,this._stackB=n,this._stackFrames=e}static fillLeaves(t,i,a){let o=a.world,s=a.sourceMesh,c=a.tplBlasOffset,l=a.visible,u=a.tlasLeafIndex,d=r(t);for(let r=0;r<i;r++){let i=r*16;if(d[i+3]!==n.BLAS_POINTER_LEAF)continue;let a=d[i+1]&1073741823;d[i]=c[s[a]],t[i+2]=+!!l[a],e.writeLeafMatrix(t,d,i,o,a),u[a]=r}}static writeLeafMatrix(e,t,n,r,i){let a=u;s(r,i*16,a),e[n+4]=a[0],e[n+5]=a[4],e[n+6]=a[8],e[n+7]=a[12],e[n+8]=a[1],e[n+9]=a[5],e[n+10]=a[9],e[n+11]=a[13],e[n+12]=a[2],e[n+13]=a[6],e[n+14]=a[10],e[n+15]=a[14],t[n+1]=(i|(c(r,i*16)?1073741824:0))>>>0}_partition(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=0;if(u===2)d=n+1;else if(u<=8)d=n+(u>>1),this._insertionSortRange(e,t,n,r,this._widestCentroidAxis(e,t,n,r));else{if(d=this._binnedSplit(e,t,n,r,i,a,o,s,c,l),d>n&&d<r)return d;if(d=this._sweepSplit(e,t,n,r,i,a,o,s,c,l),!(d>n&&d<r)){let f=s-i,p=c-a,m=l-o,h=p>f&&p>m?1:m>f?2:0;this._sortRange(e,t,n,r,h),d=n+(u>>1)}}let f=this._bounds;return this._rangeBounds(e,t,n,d,f,0),this._rangeBounds(e,t,d,r,f,6),d}_binnedSplit(e,t,n,r,i,a,o,s,c,u){let d=this._surfaceArea(i,a,o,s,c,u);if(!(d>0)||!isFinite(d))return n;let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0;for(let i=n;i<r;i++){let n=t[i]*6,r=(e[n]+e[n+3])*.5,a=(e[n+1]+e[n+4])*.5,o=(e[n+2]+e[n+5])*.5;r<f&&(f=r),r>h&&(h=r),a<p&&(p=a),a>g&&(g=a),o<m&&(m=o),o>_&&(_=o)}let v=this._extent,y=this._cMin;v[0]=h-f,v[1]=g-p,v[2]=_-m,y[0]=f,y[1]=p,y[2]=m;let b=1/0,x=-1,S=-1,C=this._binCounts,w=this._binBounds,T=v[0]>1e-12,E=v[1]>1e-12,D=v[2]>1e-12;if(!T&&!E&&!D)return n;let O=l(r-n),k=T?O/v[0]:0,A=E?O/v[1]:0,j=D?O/v[2]:0;C.fill(0,0,O*3);for(let e=0;e<O*3;e++){let t=e*6;w[t]=w[t+1]=w[t+2]=1/0,w[t+3]=w[t+4]=w[t+5]=-1/0}for(let i=n;i<r;i++){let n=t[i]*6,r=e[n],a=e[n+1],o=e[n+2],s=e[n+3],c=e[n+4],l=e[n+5];for(let e=0;e<3;e++){let t=e===0?k:e===1?A:j;if(t===0)continue;let n=((e===0?(r+s)*.5:e===1?(a+c)*.5:(o+l)*.5)-y[e])*t|0;n<0?n=0:n>=O&&(n=O-1),n+=e*O,C[n]++;let i=n*6;r<w[i]&&(w[i]=r),a<w[i+1]&&(w[i+1]=a),o<w[i+2]&&(w[i+2]=o),s>w[i+3]&&(w[i+3]=s),c>w[i+4]&&(w[i+4]=c),l>w[i+5]&&(w[i+5]=l)}}for(let e=0;e<3;e++){if(!(v[e]>1e-12))continue;let t=e*O,n=this._binSuffix,r=this._binSuffixCount,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0,u=0;for(let e=O-1;e>=1;e--){let d=(t+e)*6;w[d]<i&&(i=w[d]),w[d+1]<a&&(a=w[d+1]),w[d+2]<o&&(o=w[d+2]),w[d+3]>s&&(s=w[d+3]),w[d+4]>c&&(c=w[d+4]),w[d+5]>l&&(l=w[d+5]),u+=C[t+e],n[e]=u?this._surfaceArea(i,a,o,s,c,l):0,r[e]=u}let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0,y=0;for(let i=1;i<O;i++){let a=(t+i-1)*6;if(w[a]<f&&(f=w[a]),w[a+1]<p&&(p=w[a+1]),w[a+2]<m&&(m=w[a+2]),w[a+3]>h&&(h=w[a+3]),w[a+4]>g&&(g=w[a+4]),w[a+5]>_&&(_=w[a+5]),y+=C[t+i-1],y===0||r[i]===0)continue;let o=1+(this._surfaceArea(f,p,m,h,g,_)*y+n[i]*r[i])/d;o<b&&(b=o,x=e,S=i)}}if(x<0)return n;let M=O/v[x],N=y[x],P=this._bounds;P[0]=P[1]=P[2]=P[6]=P[7]=P[8]=1/0,P[3]=P[4]=P[5]=P[9]=P[10]=P[11]=-1/0;let F=n,I=r-1;for(;F<=I;){let n=t[F]*6,r=((e[n+x]+e[n+3+x])*.5-N)*M|0;r<0?r=0:r>=O&&(r=O-1);let i=r<S?0:6;if(e[n]<P[i]&&(P[i]=e[n]),e[n+1]<P[i+1]&&(P[i+1]=e[n+1]),e[n+2]<P[i+2]&&(P[i+2]=e[n+2]),e[n+3]>P[i+3]&&(P[i+3]=e[n+3]),e[n+4]>P[i+4]&&(P[i+4]=e[n+4]),e[n+5]>P[i+5]&&(P[i+5]=e[n+5]),i===0)F++;else{let e=t[F];t[F]=t[I],t[I]=e,I--}}return F}_sweepSplit(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=this._surfaceArea(i,a,o,s,c,l);if(!(d>0)||!isFinite(d))return n;let f=this._suffixBuffer(u),p=1/0,m=-1,h=-1;for(let i=0;i<3;i++){this._sortRange(e,t,n,r,i);let a=1/0,o=1/0,s=1/0,c=-1/0,l=-1/0,g=-1/0;for(let r=u-1;r>=1;r--){let i=t[n+r]*6;e[i]<a&&(a=e[i]),e[i+1]<o&&(o=e[i+1]),e[i+2]<s&&(s=e[i+2]),e[i+3]>c&&(c=e[i+3]),e[i+4]>l&&(l=e[i+4]),e[i+5]>g&&(g=e[i+5]);let u=r*6;f[u]=a,f[u+1]=o,f[u+2]=s,f[u+3]=c,f[u+4]=l,f[u+5]=g}let _=1/0,v=1/0,y=1/0,b=-1/0,x=-1/0,S=-1/0;for(let r=1;r<u;r++){let a=t[n+r-1]*6;e[a]<_&&(_=e[a]),e[a+1]<v&&(v=e[a+1]),e[a+2]<y&&(y=e[a+2]),e[a+3]>b&&(b=e[a+3]),e[a+4]>x&&(x=e[a+4]),e[a+5]>S&&(S=e[a+5]);let o=r*6,s=this._surfaceArea(_,v,y,b,x,S),c=this._surfaceArea(f[o],f[o+1],f[o+2],f[o+3],f[o+4],f[o+5]),l=1+(s*r+c*(u-r))/d;l<p&&(p=l,m=i,h=r)}}return m<0||h<=0?n:(m!==2&&this._sortRange(e,t,n,r,m),n+h)}_widestCentroidAxis(e,t,n,r){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let u=n;u<r;u++){let n=t[u]*6,r=(e[n]+e[n+3])*.5,d=(e[n+1]+e[n+4])*.5,f=(e[n+2]+e[n+5])*.5;r<i&&(i=r),r>s&&(s=r),d<a&&(a=d),d>c&&(c=d),f<o&&(o=f),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o;return d>u&&d>f?1:f>u?2:0}_insertionSortRange(e,t,n,r,i){let a=i,o=3+i;for(let i=n+1;i<r;i++){let r=t[i],s=e[r*6+a]+e[r*6+o],c=i-1;for(;c>=n&&e[t[c]*6+a]+e[t[c]*6+o]>s;)t[c+1]=t[c],c--;t[c+1]=r}}_sortRange(e,t,n,r,i){let a=r-n,o=this._sortScratch;o.length=a;for(let e=0;e<a;e++)o[e]=t[n+e];let s=i,c=3+i;o.sort((t,n)=>e[t*6+s]+e[t*6+c]-(e[n*6+s]+e[n*6+c]));for(let e=0;e<a;e++)t[n+e]=o[e]}_suffixBuffer(e){let t=e*6;return(!this._suffix||this._suffix.length<t)&&(this._suffix=new Float64Array(t)),this._suffix}_rangeBounds(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=n;i<r;i++){let n=t[i]*6;e[n]<o&&(o=e[n]),e[n+1]<s&&(s=e[n+1]),e[n+2]<c&&(c=e[n+2]),e[n+3]>l&&(l=e[n+3]),e[n+4]>u&&(u=e[n+4]),e[n+5]>d&&(d=e[n+5])}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}_surfaceArea(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const f={silent:0,error:1,warn:2,info:3,debug:4},p=`info`,m=`rayzeeLogLevel`,h=`rayzeeLogNamespaces`,g=`color:#7c8494`,_=`color:inherit`;let v=null,y=null;function b(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function x(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function S(){if(v!==null)return v;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in f?(v=f[e],v):(v=f[b(m)]??f[p],v)}function C(){if(y!==null)return y;let e=globalThis.__RAYZEE_LOG_NS__??b(h);return y=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],y}function w(e,t){if(t<f.debug)return!0;let n=C();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function T(e,t,n){if(e>S()||!w(t,e))return;let r=e===f.error?console.error:e===f.warn?console.warn:console.log,i=`[${t}]`;typeof n[0]==`string`?r(`%c${i}%c ${n[0]}`,g,_,...n.slice(1)):r(`%c${i}`,g,...n)}const E={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${E.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},D={levels:f,setLevel(e){return e in f?(globalThis.__RAYZEE_LOG_LEVEL__=e,v=f[e],x(m,e===p?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(f).join(`, `)}`),this.getLevel())},getLevel(){let e=S();return Object.keys(f).find(t=>f[t]===e)},isEnabled(e){return(f[e]??f.debug)<=S()},only(...e){let t=e.flat().filter(Boolean);return y=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),x(h,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return v=null,y=null,this.getLevel()}};function O(e){return{namespace:e,error:(...t)=>T(f.error,e,t),warn:(...t)=>T(f.warn,e,t),info:(...t)=>T(f.info,e,t),debug:(...t)=>T(f.debug,e,t),isEnabled:e=>D.isEnabled(e),summary(t,n=[]){let r=n.filter(Boolean);if(r.length===0||!console.groupCollapsed){T(f.info,e,[t]),r.forEach(t=>T(f.debug,e,[t]));return}f.info>S()||((S()>=f.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,g,_),r.forEach(e=>console.log(e)),console.groupEnd())}}}function k(e){e&&e in f&&(globalThis.__RAYZEE_LOG_LEVEL__=e,v=f[e])}const A=O(`bvh`);self.onmessage=function(e){let{aabbs:t,count:n,logLevel:r}=e.data;k(r);try{let e=performance.now(),{data:r,nodeCount:i}=new d().buildStructure(new Float64Array(t),n);A.debug(`TLAS ${E.n(i)} nodes in ${E.ms(performance.now()-e)}`),self.postMessage({tlasData:r,nodeCount:i},[r.buffer])}catch(e){A.error(`TLAS build failed:`,e),self.postMessage({error:e.message})}};",mc=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,pc],{type:`text/javascript;charset=utf-8`});function hc(e){let t;try{if(t=mc&&(self.URL||self.webkitURL).createObjectURL(mc),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(pc),{type:`module`,name:e?.name})}}var gc=5e4,_c=It(`scene`),vc=class{constructor(e={}){this.config={useWorkers:!0,bvhDepth:30,maxLeafSize:4,verbose:!1,useFloat32Array:!0,textureQuality:`adaptive`,maxTextureSize:at.DEFAULT_MAX_TEXTURE_SIZE,enableTextureCache:!0,maxConcurrentTextureTasks:Math.min(navigator.hardwareConcurrency||4,6),maxSceneBytes:ss,enableTreeletOptimization:!1,treeletSize:7,treeletOptimizationPasses:1,treeletMinImprovement:.01,treeletComplexityThreshold:5e4,...e},this.triangleData=null,this.triangleFloats=null,this.triangleCount=0,this.materials=[],this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.roughnessMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this.spheres=[],this.bvhRoot=null,this.bvh=null,this.bvhData=null,this.bvhIndexChunks=null,this.bvhIndex=null,this.materialData=null,this.instanceTable=null,this._refitWorker=null,this._refitSharedBuffers=null,this._rebuildGeneration=0,this._pendingRebuilds=new Map,this.srgbBucketTextures=null,this.linearBucketTextures=null,this.emissiveTriangleData=null,this.emissiveTriangleCount=0,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._initProcessors(),this.isProcessing=!1,this.processingStage=null,this.memory=new fs,this.memoryPreflight=null,this.performanceMetrics={textureCreationTime:0,geometryExtractionTime:0,bvhBuildTime:0,blasBuildTime:0,tlasBuildTime:0,bvhAssembleTime:0,totalProcessingTime:0}}setMaxTextureSize(e){return this.config.maxTextureSize=e,this.textureCreator?.setMaxTextureSize(e)}_initProcessors(){this.geometryExtractor=new rc({issues:this.config.issues}),this.bvhBuilder=new no,this.bvhBuilder.maxLeafSize=this.config.maxLeafSize,this.bvhBuilder.setTreeletConfig({enabled:this.config.enableTreeletOptimization,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold}),this.textureCreator=new Ws({maxTextureSize:this.config.maxTextureSize,issues:this.config.issues}),this.emissiveTriangleBuilder=new cc,this.tlasBuilder=new Jo,this._tlasWorker=null,this._tlasWorkerFailed=!1}_log(e,t){t===void 0?_c.debug(e):_c.debug(e,t)}_preflightMemory(e){let t=this.config.maxSceneBytes??9663676416,n=this.geometryExtractor.surveyScene(e),r=us(n),i={...n,estimate:r,safeBytes:os,maxBytes:t,fits:r.total<=os};if(this.memoryPreflight=i,r.total<1610612736)return i;if(_c.debug(Y.list([`memory preflight: ${Y.mb(r.total)} estimated`,`triangles ${Y.mb(r.triangles)} · bvh ${Y.mb(r.bvh)} · geometry ${Y.mb(r.geometry)}`,`${Y.n(n.triangles)} tris · ${Y.n(n.placements)} placements`])),r.total>t){let e=`Scene needs about ${Y.mb(r.total)} of CPU memory, past the ${Y.mb(t)} a browser tab can hold — loading it would crash the tab rather than fail. Reduce the scene (it has ${Y.n(n.triangles)} triangles), or raise maxSceneBytes to try anyway.`;throw this.config.issues?.record(gs.SCENE_MEMORY_BUDGET,e,{...n,estimate:r,maxBytes:t}),Error(e)}return i.fits||this.config.issues?.warn(gs.SCENE_MEMORY_BUDGET,`Scene needs about ${Y.mb(r.total)} of CPU memory, above the ${Y.mb(os)} a fresh browser session can usually place. It may still load, but a long-running session will probably fail during BVH assembly; restarting the browser recovers the address space.`,{...n,estimate:r,safeBytes:os}),i}_checkAssemblyHeadroom(e){let t=e*64;if(t<1610612736)return!0;let n=ds(Math.ceil(t*cs),{shared:Xo});return this.memoryPreflight&&(this.memoryPreflight.assemblyProbed=n.placed),n.exhausted&&this.config.issues?.warn(gs.SCENE_MEMORY_BUDGET,`BVH assembly needs ${Y.mb(t)} but only ${Y.mb(n.placed)} could be allocated. Restarting the browser usually recovers the address space.`,{totalNodes:e,need:t,placeable:n.placed}),!n.exhausted}_liveMemoryParts(){let e=this.instanceTable,t={triangles:this.triangles?.byteLength??0,bvh:this.bvh?.byteLength??0,geometry:this._geometryBytes??this.memoryPreflight?.geometryBytes??0,placements:e?.world?.byteLength??0,blasScratch:0,orderMaps:0};if(e){for(let n of e.blasData.values())t.blasScratch+=n?.byteLength??0;for(let n of e.bvhToOriginal.values())t.orderMaps+=n?.byteLength??0;for(let n of e.originalToBvhMap.values())t.orderMaps+=n?.byteLength??0}return t}sceneBounds(){if(!this.bvh||this.bvh.recordCount===0)return null;let e=this.bvh.chunkFor(0),t=this.bvh.baseOf(0),n=[],r=[];for(let i=0;i<3;i++)n.push(Math.min(e[t+i],e[t+8+i])),r.push(Math.max(e[t+4+i],e[t+12+i]));return{min:n,max:r}}_sampleMemory(e){this.memory.sample(e,this._liveMemoryParts())}_logMemoryReport(){let{allocatedBytes:e,peakLiveBytes:t,byPhase:n}=this.memory;if(e===0)return;let r=Object.keys(n).filter(e=>n[e].allocated>0).map(e=>`${e} ${Y.mb(n[e].allocated)}`),i=this.memoryPreflight?.estimate?.total;_c.debug(Y.list([`memory: peak live ${Y.mb(t)}`,`allocated ${Y.mb(e)}`,i?`predicted ${Y.mb(i)}`:null,r.join(` · `)]))}async buildBVH(e){if(this.isProcessing)throw Error(`Already processing a scene. Call dispose() first.`);this.isProcessing=!0,this.processingStage=`init`,this.memory.reset(),this._geometryBytes=0,Qo(e=>this.memory.alloc(e));let t=new lc(e.name??``,{namespace:`scene`});try{this._reset(),this._log(`Starting scene processing`),this.memory.mark(`preflight`),this._preflightMemory(e),this.processingStage=`extraction`,this.memory.mark(`extraction`),t.start(`Geometry extraction`),await this._extractGeometry(e),t.end(`Geometry extraction`),this.performanceMetrics.geometryExtractionTime=t.getDuration(`Geometry extraction`),this._geometryBytes=Zs(e),this._sampleMemory(`after extraction`),this.processingStage=`bvh`,t.start(`BVH construction (worker)`),t.start(`Material textures (parallel)`);let n=!1,r=this._buildBVH().then(()=>t.end(`BVH construction (worker)`)),i=this._createMaterialTextures().then(()=>{t.end(`Material textures (parallel)`),n=!0});return await r,H({status:`Building light data...`,progress:77}),t.start(`Emissive extraction + Light BVH`),this._buildEmissiveData(),t.end(`Emissive extraction + Light BVH`),n||H({status:`Processing material textures...`,progress:80}),await i,this.performanceMetrics.bvhBuildTime=t.getDuration(`BVH construction (worker)`),this.performanceMetrics.textureCreationTime=t.getDuration(`Material textures (parallel)`),this.processingStage=`finalize`,t.start(`BVH data packing`),this.bvhRoot&&!this.bvh&&this._setBVHData(this.textureCreator.createBVHRawData(this.bvhRoot)),t.end(`BVH data packing`),this.spheres=this._createSpheres(),this.performanceMetrics.totalProcessingTime=performance.now()-t.totalStart,t.print(),this.processingStage=`complete`,H({status:`Scene data ready`,progress:85}),this}catch(e){throw this.processingStage=`error`,_c.error(`processing failed:`,e),H({status:`Error: ${e.message}`,failed:!0,progress:100}),e}finally{Qo(null),this._sampleMemory(`at ${this.processingStage}`),this._logMemoryReport(),this.isProcessing=!1}}async _extractGeometry(e){H({isLoading:!0,title:`Processing`,status:`Extracting geometry...`,progress:15}),await new Promise(e=>setTimeout(e,0)),this._log(`Extracting geometry`);let t=performance.now();try{let n=this.geometryExtractor.extract(e);this._setTriangleData(n.triangleData),this.triangleCount=it(n.triangleCount,`triangle count`),this.expandedTriangleCount=n.expandedTriangleCount??n.triangleCount,this.instanceSource=n.instanceSource||null,this.instanceMatrices=n.instanceMatrices||null,this.instanceCount=n.instanceCount||0,this.bakeInverse=n.bakeInverse||null,this._log(`Using Float32Array format: ${this.triangleCount} triangles, ${(this.triangles.byteLength/(1024*1024)).toFixed(2)}MB`),this.materials=n.materials,this.materialTriangleCounts=n.materialTriangleCounts,this.meshes=n.meshes,this.meshTriangleRanges=n.meshTriangleRanges,this.maps=n.maps,this.normalMaps=n.normalMaps,this.bumpMaps=n.bumpMaps,this.roughnessMaps=n.roughnessMaps,this.metalnessMaps=n.metalnessMaps,this.emissiveMaps=n.emissiveMaps,this.displacementMaps=n.displacementMaps,this.anisotropyMaps=n.anisotropyMaps,this.transmissionMaps=n.transmissionMaps,this.clearcoatMaps=n.clearcoatMaps,this.clearcoatRoughnessMaps=n.clearcoatRoughnessMaps,this.sheenColorMaps=n.sheenColorMaps,this.sheenRoughnessMaps=n.sheenRoughnessMaps,this.iridescenceMaps=n.iridescenceMaps,this.iridescenceThicknessMaps=n.iridescenceThicknessMaps,this.specularIntensityMaps=n.specularIntensityMaps,this.specularColorMaps=n.specularColorMaps,this.directionalLights=n.directionalLights,this.cameras=n.cameras;let r=performance.now()-t;this._log(`Geometry extraction complete (${r.toFixed(2)}ms)`,{triangleCount:this.triangleCount,materials:this.materials.length}),H({status:`Extracted ${this.triangleCount.toLocaleString()} triangles`,progress:25})}catch(e){throw _c.error(`geometry extraction failed:`,e),H({status:`Extraction error: ${e.message}`,failed:!0,progress:25}),e}}async _buildBVH(){if(H({status:`Building BVH...`,progress:25}),this.triangleCount===0)throw Error(`No triangles to build BVH from`);this._log(`Building two-level BVH (TLAS/BLAS)`),this.memory.mark(`blas`);let e=performance.now();try{let t=this.meshTriangleRanges;if(!t||t.length===0)throw Error(`No mesh triangle ranges available for TLAS/BLAS build`);let n=this.instanceCount>0,r=n?this.instanceCount:t.length,i=this.instanceSource,a=n?this.instanceMatrices:null,o=e=>n?i[e]:e;this.instanceTable=new Vo,this.instanceTable.allocate(r,t.length,a,n?i:null),this.instanceTable.tplBakeInverse=this.bakeInverse;let s=this.config.enableTreeletOptimization,c=[],l=[],u=new Map,d=new Map;for(let e=0;e<r;e++){let n=t[o(e)];if(!n||n.count===0)continue;let r=d.get(n.start);if(r!==void 0){u.set(e,r);continue}d.set(n.start,e),n.count>=2e5&&No(n.count)?l.push({m:e,range:n}):c.push({m:e,range:n})}let f={depth:this.config.bvhDepth,treeletOptimization:{enabled:s!==!1,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold},reinsertionOptimization:{enabled:this.bvhBuilder.enableReinsertionOptimization,batchSizeRatio:this.bvhBuilder.reinsertionBatchSizeRatio,maxIterations:this.bvhBuilder.reinsertionMaxIterations},maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,logLevel:zt()},p=c.length+l.length,m=0,h=()=>{m++,H({status:`Building BLAS ${m}/${p}...`,progress:25+Math.floor(m/p*45)})},g=this._buildBLASesWithPool(c,f,h),_=[],v=(async()=>{for(let{m:e,range:t}of l){let n=await Ao(this.triangles.copyOf(t.start,t.count),this.config.bvhDepth,null,{maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,...f});n.reorderedTriangles&&(this.triangles.setRecords(t.start,n.reorderedTriangles),delete n.reorderedTriangles),_.push({m:e,range:t,result:n}),h()}})(),[y]=await Promise.all([g,v]),b={sah:0,objMed:0,spatMed:0,failed:0,treeletsImproved:0,treeletsProcessed:0};for(let{m:e,range:t,result:r}of[...y,..._]){let i=r.splitStats;i&&(b.sah+=i.sahSplits??0,b.objMed+=i.objectMedianSplits??0,b.spatMed+=i.spatialMedianSplits??0,b.failed+=i.failedSplits??0,b.treeletsImproved+=i.treeletsImproved??0,b.treeletsProcessed+=i.treeletsProcessed??0),this.instanceTable.setEntry({meshIndex:e,blasNodeCount:r.bvhData.length/16,triOffset:t.start,triCount:t.count,originalToBvhMap:r.originalToBvh||null,bvhData:r.bvhData,matrixWorld:n?a:this.meshes?.[e]?.matrixWorld?.elements??null,matrixOffset:n?e*16:0,expandedStart:t.expandedStart,sourceMesh:o(e)})}for(let[e,r]of u)this.instanceTable.setAlias(e,r,n?a:this.meshes?.[e]?.matrixWorld?.elements??null,t[o(e)].expandedStart,o(e),n?e*16:0);H({status:`Built all BLASes`,progress:70}),this.performanceMetrics.blasBuildTime=performance.now()-e,H({status:`Building TLAS...`,progress:72}),this._sampleMemory(`BLASes built`),this.memory.mark(`tlas`);let x=performance.now(),S=this.instanceTable;this.instanceTable.computeAABBs(this.triangles),this.instanceTable.assignOffsets(Jo.nodeCountFor(S.count));let C=this.instanceTable.totalNodeCount,w=await this._buildTLAS(S);this.performanceMetrics.tlasBuildTime=performance.now()-x,this.memory.mark(`assemble`);let T=performance.now();this._checkAssemblyHeadroom(C),this._setBVHData(es.lazy(C,16,Float32Array,void 0,Xo)),this.bvh.setRecords(0,w),w=null,this.tlasBuilder.releaseFlattenBuffer();let E=Math.max(1,Math.ceil(S.templateCount/32));for(let e=0;e<S.templateCount;e++){let t=S.blasData.get(e);if(!t)continue;let n=S.tplBlasOffset[e];this.bvh.setRecords(n,t),this._offsetBLASInPlace(n,t.length/16,n,S.tplTriOffset[e]),S.blasData.delete(e),e%E===0&&this._sampleMemory(`assembling ${e}/${S.templateCount}`)}this._setBVHData(this.bvh.materializeAll()),this._buildBvhToOriginalMaps(),this.performanceMetrics.bvhAssembleTime=performance.now()-T,S.originalToBvhMap.clear(),S.blasData.clear(),this.bvhRoot=!0,this._disposeRefitWorker();let D=performance.now()-e;_c.debug(Y.list([`${Y.n(S.setCount)} BLASes + TLAS`,`${Y.n(this.bvh.recordCount)} nodes`,`SAH ${Y.n(b.sah)} · objMed ${b.objMed} · spatMed ${b.spatMed} · failed ${b.failed}`,b.treeletsProcessed?`treelets ${b.treeletsImproved}/${b.treeletsProcessed} improved`:null,Y.ms(D)])),H({status:`BVH construction complete`,progress:75})}catch(e){throw _c.error(`BVH build failed:`,e),H({status:`BVH error: ${e.message}`,failed:!0,progress:75}),e}}_offsetBLASInPlace(e,t,n,r){let i=this.bvhIndexChunks;for(let a=0;a<t;a++){let t=e+a,o=i.chunkFor(t),s=i.baseOf(t);o[s+3]===nt.TRIANGLE_LEAF?o[s]+=r:(o[s+3]+=n,o[s+7]+=n)}}_buildBLASesWithPool(e,t,n){if(e.length===0)return Promise.resolve([]);let r=Math.min(e.length,this.config.maxConcurrentTextureTasks||4),i=[],a=0,o=0;return new Promise((s,c)=>{let l=[],u=n=>{if(a>=e.length){n.terminate(),l.splice(l.indexOf(n),1),l.length===0&&s(i);return}let{m:r,range:o}=e[a++],c=this.triangles.copyOf(o.start,o.count),u=o.count,d=u<=500?{...t.treeletOptimization,enabled:!1}:t.treeletOptimization;n._currentTask={m:r,range:o},n.postMessage({triangleData:c.buffer,triangleByteOffset:c.byteOffset,triangleByteLength:c.byteLength,triangleCount:u,depth:t.depth,reportProgress:!1,sharedReorderBuffer:null,treeletOptimization:d,reinsertionOptimization:t.reinsertionOptimization,maxLeafSize:t.maxLeafSize,numBins:t.numBins,maxBins:t.maxBins,minBins:t.minBins,logLevel:t.logLevel},[c.buffer])},d=(e,t)=>{let r=t.data;if(r.error){l.forEach(e=>e.terminate()),c(Error(r.error));return}if(r.progress!==void 0)return;let{m:a,range:s}=e._currentTask;r.triangles&&this.triangles.setRecords(s.start,r.triangles),i.push({m:a,range:s,result:{bvhData:r.bvhData,originalToBvh:r.originalToBvh||null,splitStats:r.treeletStats||null}}),o++,n?.(o),u(e)};(async()=>{for(let e=0;e<r;e++){let e;try{e=new So}catch(e){c(e);return}e.onmessage=t=>d(e,t),e.onerror=e=>{l.forEach(e=>e.terminate()),c(e)},l.push(e),u(e)}})().catch(c)})}_buildBvhToOriginalMaps(){let e=this.instanceTable;for(let t=0;t<e.count;t++){if(!e.isSet[t]||!e.isOwner(t))continue;let n=e.sourceMesh[t],r=e.tplTriCount[n],i=e.originalToBvhMap.get(n),a=new Uint32Array(r);if(i)for(let e=0;e<r;e++)a[i[e]]=e;else for(let e=0;e<r;e++)a[e]=e;e.bvhToOriginal.set(n,a),e.originalToBvhMap.delete(n)}}async _createMaterialTextures(){this._log(`Creating material textures (parallel with BVH)`);try{let{srgbLists:e,linearLists:t,remap:n}=this._bucketTextures();this._remapMaterialTextureIndices(n),this.materials?.length&&(this.materialData=this.textureCreator.createMaterialRawData(this.materials));let i=(e,t)=>e.length===0?Promise.resolve(null):this.textureCreator.createTexturesToDataTexture(e,{srgbPool:t}).then(e=>(e&&t&&(e.colorSpace=r.SRGBColorSpace),e)),[a,o]=await Promise.all([Promise.all(e.map(e=>i(e,!0))),Promise.all(t.map(e=>i(e,!1)))]);this.srgbBucketTextures=a,this.linearBucketTextures=o,this._log(`Material textures complete`,{materialData:!!this.materialData,srgbBuckets:a.map(e=>e?`${e.image.width}x${e.image.height}x${e.image.depth}`:`-`).join(`,`),linearBuckets:o.map(e=>e?`${e.image.width}x${e.image.height}x${e.image.depth}`:`-`).join(`,`)})}catch(e){throw _c.error(`texture creation failed:`,e),e}}_bucketTextures(){let e=this.config.maxTextureSize,t=at.MATERIAL_BUCKET_COUNT,n=at.BUCKET_LAYER_STRIDE,r=e=>{let t=new Set,n=[];for(let r of e)for(let e of r||[]){if(!e?.image)continue;let r=e.source?.uuid??e.uuid;t.has(r)||(t.add(r),n.push({width:e.image.width,height:e.image.height}))}return n},i=[this.maps,this.emissiveMaps,this.sheenColorMaps,this.specularColorMaps],a=[this.normalMaps,this.bumpMaps,this.roughnessMaps,this.metalnessMaps,this.displacementMaps,this.anisotropyMaps,this.transmissionMaps,this.clearcoatMaps,this.clearcoatRoughnessMaps,this.sheenRoughnessMaps,this.iridescenceMaps,this.iridescenceThicknessMaps,this.specularIntensityMaps],o=mt(r(i),e,t),s=mt(r(a),e,t);this._srgbBucketShapes=o,this._linearBucketShapes=s;let c=Array.from({length:t},()=>[]),l=Array.from({length:t},()=>[]),u=Array.from({length:t},()=>new Map),d=Array.from({length:t},()=>new Map);this._srgbTexPacked=new Map,this._linearTexPacked=new Map;let f=!1,p=!1,m=(e,t,r,i,a)=>{if(!e)return-1;if(!e.image)return p||this.config.issues?.record(gs.TEXTURE_BUILD_FAILED,`a material map had not finished decoding when the scene was packed; it renders untextured`,{texture:e.name||e.source?.uuid||e.uuid}),p=!0,-1;let o=ht(e.image.width,e.image.height,a),s=e.source?.uuid??e.uuid,c=r[o].get(s);if(c!==void 0)return gt(o,c);if(t[o].length>=n)return _c.warn(`texture bucket ${o} full (${n}); dropping a map`),f||this.config.issues?.record(gs.TEXTURE_LIMIT_EXCEEDED,`texture bucket ${o} full (${n} layers); the rest render untextured`,{bucket:o,limit:n}),f=!0,-1;t[o].push(e);let l=t[o].length-1;r[o].set(s,l);let u=gt(o,l);return i.set(s,u),u},h=(e,t,n,r,i)=>(e||[]).map(e=>m(e,t,n,r,i));return{srgbLists:c,linearLists:l,remap:{albedo:h(this.maps,c,u,this._srgbTexPacked,o),emissive:h(this.emissiveMaps,c,u,this._srgbTexPacked,o),normal:h(this.normalMaps,l,d,this._linearTexPacked,s),bump:h(this.bumpMaps,l,d,this._linearTexPacked,s),roughness:h(this.roughnessMaps,l,d,this._linearTexPacked,s),metalness:h(this.metalnessMaps,l,d,this._linearTexPacked,s),displacement:h(this.displacementMaps,l,d,this._linearTexPacked,s),anisotropy:h(this.anisotropyMaps,l,d,this._linearTexPacked,s),transmission:h(this.transmissionMaps,l,d,this._linearTexPacked,s),clearcoat:h(this.clearcoatMaps,l,d,this._linearTexPacked,s),clearcoatRoughness:h(this.clearcoatRoughnessMaps,l,d,this._linearTexPacked,s),sheenColor:h(this.sheenColorMaps,c,u,this._srgbTexPacked,o),sheenRoughness:h(this.sheenRoughnessMaps,l,d,this._linearTexPacked,s),iridescence:h(this.iridescenceMaps,l,d,this._linearTexPacked,s),iridescenceThickness:h(this.iridescenceThicknessMaps,l,d,this._linearTexPacked,s),specularIntensity:h(this.specularIntensityMaps,l,d,this._linearTexPacked,s),specularColor:h(this.specularColorMaps,c,u,this._srgbTexPacked,o)}}}_remapMaterialTextureIndices(e){let t=(e,t)=>e>=0&&e<t.length?t[e]:-1;for(let n of this.materials)n.map=t(n.map,e.albedo),n.emissiveMap=t(n.emissiveMap,e.emissive),n.normalMap=t(n.normalMap,e.normal),n.bumpMap=t(n.bumpMap,e.bump),n.roughnessMap=t(n.roughnessMap,e.roughness),n.metalnessMap=t(n.metalnessMap,e.metalness),n.displacementMap=t(n.displacementMap,e.displacement),n.anisotropyMap=t(n.anisotropyMap,e.anisotropy),n.transmissionMap=t(n.transmissionMap,e.transmission),n.clearcoatMap=t(n.clearcoatMap,e.clearcoat),n.clearcoatRoughnessMap=t(n.clearcoatRoughnessMap,e.clearcoatRoughness),n.sheenColorMap=t(n.sheenColorMap,e.sheenColor),n.sheenRoughnessMap=t(n.sheenRoughnessMap,e.sheenRoughness),n.iridescenceMap=t(n.iridescenceMap,e.iridescence),n.iridescenceThicknessMap=t(n.iridescenceThicknessMap,e.iridescenceThickness),n.specularIntensityMap=t(n.specularIntensityMap,e.specularIntensity),n.specularColorMap=t(n.specularColorMap,e.specularColor)}_buildEmissiveData(){this.emissiveTriangleCount=this.emissiveTriangleBuilder.extractEmissiveTriangles(this.triangles,this.materials,this.triangleCount,this.instanceTable??null),this.emissiveTriangleData=this.emissiveTriangleBuilder.createEmissiveRawData(),this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower,this._log(`Emissive triangle extraction complete`,this.emissiveTriangleBuilder.getStats()),this.emissiveTriangleBuilder.buildLightBVH(),this.lightBVHNodeData=this.emissiveTriangleBuilder.lightBVHNodeData,this.lightBVHNodeCount=this.emissiveTriangleBuilder.lightBVHNodeCount,this.emissiveTriangleData=this.emissiveTriangleBuilder.emissiveTriangleData||this.emissiveTriangleData,this.emissiveBitTrailMap=this.emissiveTriangleBuilder.emissiveBitTrailMap,this.emissiveTriangleCount=this.emissiveTriangleBuilder.emissiveCount,this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower}_createSpheres(){return[]}_reset(){this._disposeTextures(),this.triangles=[],this._setTriangleData(null),this.triangleCount=0,this.materials=[],this.meshTriangleRanges=null,this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.roughnessMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this.spheres=[],this.bvhRoot=null,this.bvh=null,this.bvhData=null,this.bvhIndexChunks=null,this.bvhIndex=null,this.instanceTable=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this.performanceMetrics={textureCreationTime:0,geometryExtractionTime:0,bvhBuildTime:0,blasBuildTime:0,tlasBuildTime:0,bvhAssembleTime:0,totalProcessingTime:0}}_disposeTextures(){this._disposeBucketTextures()}_disposeBucketTextures(){for(let e of[`srgbBucketTextures`,`linearBucketTextures`]){let t=this[e];if(t){for(let n of t)if(n&&typeof n.dispose==`function`)try{n.dispose()}catch(t){_c.warn(`error disposing ${e}:`,t)}this[e]=null}}}async rebuildMaterials(e){if(this.isProcessing)throw Error(`Already processing. Cannot rebuild materials during processing.`);this._log(`Rebuilding materials and textures`);let t=performance.now();try{this.isProcessing=!0;let n=this.geometryExtractor.extractMaterialsOnly(e);this._disposeMaterialTextures(),this.materials=n.materials,this.meshes=n.meshes,this.maps=n.maps,this.normalMaps=n.normalMaps,this.bumpMaps=n.bumpMaps,this.roughnessMaps=n.roughnessMaps,this.metalnessMaps=n.metalnessMaps,this.emissiveMaps=n.emissiveMaps,this.displacementMaps=n.displacementMaps,await this._createMaterialTextures();let r=performance.now()-t;return this._log(`Material rebuild complete (${r.toFixed(2)}ms)`,{materials:this.materials.length,textures:this.maps.length}),this}catch(e){throw _c.error(`material rebuild failed:`,e),e}finally{this.isProcessing=!1}}_disposeMaterialTextures(){this._disposeBucketTextures(),this.textureCreator&&this.textureCreator.textureCache&&(this.textureCreator.textureCache.dispose(),this.textureCreator.textureCache=new this.textureCreator.textureCache.constructor)}getStatistics(){let e={triangleCount:this.triangleCount,materialCount:this.materials.length,textureCount:this.maps.length,lightCount:this.directionalLights.length,cameraCount:this.cameras.length,processingComplete:this.processingStage===`complete`,hasBVH:!!this.bvhRoot,hasTextures:!!this.materialData&&!!this.bvh,useFloat32Array:this.config.useFloat32Array,triangleDataSize:this.triangles?(this.triangles.byteLength/(1024*1024)).toFixed(2)+`MB`:`0MB`};return this.performanceMetrics.totalProcessingTime>0&&(e.performance={totalTime:this.performanceMetrics.totalProcessingTime,textureTime:this.performanceMetrics.textureCreationTime,bvhTime:this.performanceMetrics.bvhBuildTime,extractionTime:this.performanceMetrics.geometryExtractionTime,texturePercentage:(this.performanceMetrics.textureCreationTime/this.performanceMetrics.totalProcessingTime*100).toFixed(1)+`%`}),this.textureCreator&&this.textureCreator.capabilities&&(e.textureCapabilities=this.textureCreator.capabilities),e}updateConfig(e){Object.assign(this.config,e),this.bvhBuilder&&(this.bvhBuilder.maxLeafSize=this.config.maxLeafSize,this.bvhBuilder.setTreeletConfig({enabled:this.config.enableTreeletOptimization,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold})),this._log(`Configuration updated`,this.config)}_adoptSharedChunks(e,t){let n=this[e];if(n.shared)return;let r=n.chunks.map(e=>{let n=new t(new SharedArrayBuffer(e.byteLength));return n.set(e),n}),i=es.adopt(r,n.recordCount,n.lanesPerRecord,n.recordsPerChunk);e===`bvh`?this._setBVHData(i):this._setTriangleData(i)}_meshSource(e,t){if(e==null)return null;let n=this.instanceTable;if(typeof e==`function`)return r=>{let i=n.sourceMesh[r],a=e(i,n.triCountOf(r)),o=n.triCountOf(r)*9;if(a&&a.length!==o)throw Error(`SceneProcessor: ${t}s for mesh ${i} must be ${o} floats (${n.triCountOf(r)} triangles × 9), got ${a.length}.`);return a??null};let r=(this.expandedTriangleCount??this.triangleCount)*9;if(e.length!==r)throw Error(`SceneProcessor: expected ${r} ${t} floats (${r/9} triangles × 9, full scene), got ${e.length}. Pass a per-mesh callback instead to avoid building one array for the whole scene.`);return t=>{let r=n.expandedStartOf(t)*9;return e.subarray(r,r+n.triCountOf(t)*9)}}async refitBVH(e,t){if(!this.bvh||!this.triangles||!this.instanceTable)throw Error(`No BVH data available for refit. Run buildBVH() first.`);let n=this._meshSource(e,`position`),r=this._meshSource(t,`normal`);if(!n)throw Error(`SceneProcessor.refitBVH: positions are required.`);if(this._refitWorker||=new fc,!this._refitSharedBuffers){this._adoptSharedChunks(`bvh`,Float32Array),this._adoptSharedChunks(`triangles`,Uint32Array);let e=this.bvh.chunks.map(e=>e.buffer),t=this.triangles.chunks.map(e=>e.buffer);this._refitSharedBuffers={bvhBufs:e,triBufs:t},this._refitWorker.postMessage({type:`init`,sharedBvhBufs:e,bvhRecordCount:this.bvh.recordCount,bvhRecordsPerChunk:this.bvh.recordsPerChunk,sharedTriBufs:t,triRecordCount:this.triangles.recordCount,triLanesPerRecord:this.triangles.lanesPerRecord,triRecordsPerChunk:this.triangles.recordsPerChunk})}let i=this.instanceTable;for(let e=0;e<i.count;e++){if(!i.isSet[e]||!i.isOwner(e))continue;let t=n(e);if(t&&(this._updateMeshTrianglePositions(e,t),r)){let t=r(e);t&&this._patchMeshSmoothNormals(e,t)}}return new Promise((e,t)=>{this._refitWorker.onmessage=n=>{let r=n.data;r.type===`refitComplete`?e({refitTimeMs:r.refitTimeMs}):r.type===`error`&&t(Error(r.error))},this._refitWorker.postMessage({type:`refit`})})}_patchSmoothNormals(e){let t=this.instanceTable;if(t)for(let n=0;n<t.count;n++){if(!t.isSet[n]||!t.isOwner(n))continue;let r=e(n);r&&this._patchMeshSmoothNormals(n,r)}}_placementOf(e){return this.instanceTable?.placementRunOf(e)?.start??-1}refitBLASes(e,t,n){if(!this.instanceTable||!this.bvh||!this.triangles)throw Error(`No TLAS/BLAS data available. Run buildBVH() first.`);let r=this._meshSource(t,`position`),i=this._meshSource(n,`normal`);if(!r)throw Error(`SceneProcessor.refitBLASes: positions are required.`);let a=performance.now();this._blasRefitter||=new yo;let o=this.instanceTable;for(let t of e){let e=this._placementOf(t);if(e<0||!o.isSet[e])continue;if(!o.isOwner(e)){let n=o.tplOwner[o.sourceMesh[e]];this.config.issues?.record(gs.REFIT_SHARED_GEOMETRY,`mesh ${t} shares its triangles with another placement; deforming it would move every copy, so it was skipped`,{meshIndex:t,owner:o.sourceMesh[n]??n});continue}let n=r(e);if(n){if(this._updateMeshTrianglePositions(e,n),i){let t=i(e);t&&this._patchMeshSmoothNormals(e,t)}this._blasRefitter.refitRange(this.bvh,this.triangles,o.blasOffsetOf(e),o.blasNodeCountOf(e)),this.instanceTable.recomputeAABB(e,this.bvh,this.triangles)}}return this._refitTLAS(),{refitTimeMs:performance.now()-a}}updateMeshTransforms(e){if(!this.instanceTable||!this.bvh)throw Error(`No TLAS/BLAS data available. Run buildBVH() first.`);let t=performance.now(),n=this.instanceTable,r=this._transformScratch??=new Float32Array(16),i=0;for(let t of e){let e=this.meshes?.[t],a=n.placementRunOf(t);if(!e||!a)continue;e.updateMatrixWorld(!0);let o=e.matrixWorld.elements,s=e.isInstancedMesh?this._ownInstanceMatrices(e):null,c=n.tplBakeInverse?.get(n.sourceMesh[a.start])??null;for(let e=0;e<a.count;e++){let t=a.start+e;n.isSet[t]&&(s?(Lo(o,s,e*16,r),n.setPlacementMatrix(t,r)):c?(Lo(o,c,0,r),n.setPlacementMatrix(t,r)):n.setPlacementMatrix(t,o),this._writeLeafMatrix(t),i++)}}return this._refitTLAS(),{refitTimeMs:performance.now()-t,placements:i}}_ownInstanceMatrices(e){let t=e.instanceMatrix;return t?.array?(t.array.buffer===this.instanceTable.world.buffer&&(t.array=t.array.slice(),t.needsUpdate=!0),t.array):null}_writeLeafMatrix(e){let t=this.instanceTable.tlasLeafIndex[e];t<0||Jo.writeLeafMatrix(this.bvh.chunkFor(t),this.bvhIndexChunks.chunkFor(t),this.bvh.baseOf(t),this.instanceTable.world,e)}computeTLASDirtyRange(){return{offset:0,count:this.instanceTable.tlasNodeCount*16}}computeBLASDirtyRanges(e){let t=K.FLOATS_PER_TRIANGLE,n=[],r=[];for(let i of e){let e=this.instanceTable,a=this._placementOf(i);a<0||!e.isSet[a]||(n.push({offset:e.triOffsetOf(a)*t,count:e.triCountOf(a)*t}),r.push({offset:e.blasOffsetOf(a)*16,count:e.blasNodeCountOf(a)*16}))}return r.push({offset:0,count:this.instanceTable.tlasNodeCount*16}),{triRanges:n,bvhRanges:r}}uploadToPathTracer(e,t,n,r){return this.triangles?(e.setTriangleData(this.triangles,this.triangleCount),this.bvh?(e.setBVHData(this.bvh),e.setInstanceTable(this.instanceTable),this.materialData?e.materialData.setMaterialData(this.materialData):_c.warn(`no material data, using defaults`),r&&e.environment.setEnvironmentTexture(r),e.materialData.setMaterialTextures({srgbBuckets:this.srgbBucketTextures,linearBuckets:this.linearBucketTextures}),e.materialData.setTexturePackMaps?.(this._srgbTexPacked,this._linearTexPacked),this.emissiveTriangleData&&e.setEmissiveTriangleData(this.emissiveTriangleData,this.emissiveTriangleCount,this.emissiveTotalPower,this.emissiveBitTrailMap),this.lightBVHNodeData&&e.setLightBVHData(this.lightBVHNodeData,this.lightBVHNodeCount),t.transferSceneLights(n),!0):(_c.error(`failed to get BVH data`),!1)):(_c.error(`failed to get triangle data`),!1)}updateMaterialEmissive(e,t,n){if(!this.emissiveTriangleBuilder)return null;let r=this.materials[e];return!r||(t===`emissive`?r.emissive=n:t===`emissiveIntensity`&&(r.emissiveIntensity=n),!this.emissiveTriangleBuilder.updateMaterialEmissive(e,r,this.triangles,this.materials,this.triangleCount))?null:this._collectEmissivePayload()}rebuildEmissiveForVisibility(e,t=!1){return!this.emissiveTriangleBuilder||!this.emissiveTriangleBuilder.setHiddenMeshes(e)&&!t?null:this._collectEmissivePayload()}_collectEmissivePayload(){return this.emissiveTriangleBuilder.buildLightBVH(),this.lightBVHNodeData=this.emissiveTriangleBuilder.lightBVHNodeData,this.lightBVHNodeCount=this.emissiveTriangleBuilder.lightBVHNodeCount,this.emissiveTriangleData=this.emissiveTriangleBuilder.emissiveTriangleData,this.emissiveBitTrailMap=this.emissiveTriangleBuilder.emissiveBitTrailMap,this.emissiveTriangleCount=this.emissiveTriangleBuilder.emissiveCount,this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower,{rawData:this.emissiveTriangleData,emissiveCount:this.emissiveTriangleCount,totalPower:this.emissiveTotalPower,bitTrailMap:this.emissiveBitTrailMap,lightBVHNodeData:this.lightBVHNodeData,lightBVHNodeCount:this.lightBVHNodeCount}}async _buildTLAS(e){let t=e.count;if(t>=gc&&!this._tlasWorkerFailed)try{let n=new Float64Array(t*6);e.writeWorldAABBs(n);let{tlasData:r,nodeCount:i}=await this._runTLASWorker(n,t);return Jo.fillLeaves(r,i,e),r}catch(e){this._tlasWorkerFailed=!0,_c.warn(`TLAS worker unavailable (${e.message}); building on the main thread`)}return this.tlasBuilder.build(e).data}_runTLASWorker(e,t){this._tlasWorker||=new hc;let n=this._tlasWorker;return new Promise((r,i)=>{let a=e=>{n.removeEventListener(`message`,a),n.removeEventListener(`error`,o),e.data?.error?i(Error(e.data.error)):r(e.data)},o=e=>{n.removeEventListener(`message`,a),n.removeEventListener(`error`,o),i(Error(e.message||`worker error`))};n.addEventListener(`message`,a),n.addEventListener(`error`,o),n.postMessage({aabbs:e.buffer,count:t,logLevel:zt()},[e.buffer])})}_setBVHData(e){let t=e?e instanceof es?e:es.adopt([e],e.length/16,16,e.length/16):null;this.bvh=t,this.bvhIndexChunks=t?t.viewAs(Uint32Array):null,this.bvhData=t?t.single:null,this.bvhIndex=this.bvhIndexChunks?this.bvhIndexChunks.single:null}_setTriangleData(e){let t=K.FLOATS_PER_TRIANGLE,n=e?e instanceof es?e:es.adopt([e],e.length/t,t,e.length/t):null;this.triangles=n,this.triangleFloatChunks=n?n.viewAs(Float32Array):null,this.triangleData=n?n.single:null,this.triangleFloats=this.triangleFloatChunks?this.triangleFloatChunks.single:null}_updateMeshTrianglePositions(e,t){let n=K.POSITION_A_OFFSET,r=K.POSITION_B_OFFSET,i=K.POSITION_C_OFFSET,a=K.NORMAL_A_PACKED_OFFSET,o=K.NORMAL_B_PACKED_OFFSET,s=K.NORMAL_C_PACKED_OFFSET,c=this.triangles,l=this.triangleFloatChunks,u=this.instanceTable,d=u.bvhToOriginalOf(e),f=u.triOffsetOf(e),p=u.triCountOf(e),m=u.matrixInverseOf(e),h=Ro(m);for(let e=0;e<p;e++){let u=d?d[e]:e,p=f+e,g=l.chunkFor(p),_=c.chunkFor(p),v=c.baseOf(p),y=u*9,b=t[y],x=t[y+1],S=t[y+2],C=t[y+3],w=t[y+4],T=t[y+5],E=t[y+6],D=t[y+7],O=t[y+8];if(!h){let e=(e,t,n)=>m[0]*e+m[4]*t+m[8]*n+m[12],t=(e,t,n)=>m[1]*e+m[5]*t+m[9]*n+m[13],n=(e,t,n)=>m[2]*e+m[6]*t+m[10]*n+m[14],r=[e(b,x,S),t(b,x,S),n(b,x,S)],i=[e(C,w,T),t(C,w,T),n(C,w,T)],a=[e(E,D,O),t(E,D,O),n(E,D,O)];b=r[0],x=r[1],S=r[2],C=i[0],w=i[1],T=i[2],E=a[0],D=a[1],O=a[2]}g[v+n]=b,g[v+n+1]=x,g[v+n+2]=S,g[v+r]=C,g[v+r+1]=w,g[v+r+2]=T,g[v+i]=E,g[v+i+1]=D,g[v+i+2]=O;let k=C-b,A=w-x,j=T-S,M=E-b,N=D-x,P=O-S,F=Qe(A*P-j*N,j*M-k*P,k*N-A*M);_[v+a]=F,_[v+o]=F,_[v+s]=F}}_patchMeshSmoothNormals(e,t){let n=this.instanceTable;this._patchNormalsRange(t,n.triOffsetOf(e),n.triCountOf(e),n.matrixWorldOf(e),n.bvhToOriginalOf(e))}_patchNormalsRange(e,t,n,r,i){let a=K.NORMAL_A_PACKED_OFFSET,o=K.NORMAL_B_PACKED_OFFSET,s=K.NORMAL_C_PACKED_OFFSET,c=r,l=!c||Ro(c),u=[a,o,s];for(let r=0;r<n;r++){let n=t+r,a=this.triangles.chunkFor(n),o=this.triangles.baseOf(n),s=(i?i[r]:r)*9;for(let t=0;t<3;t++){let n=s+t*3,r=e[n],i=e[n+1],d=e[n+2],f=r,p=i,m=d;if(!l){f=c[0]*r+c[1]*i+c[2]*d,p=c[4]*r+c[5]*i+c[6]*d,m=c[8]*r+c[9]*i+c[10]*d;let e=Math.hypot(f,p,m)||1;f/=e,p/=e,m/=e}a[o+u[t]]=Qe(f,p,m)}}}_refitTLAS(){let e=this.instanceTable.tlasNodeCount;(!this._tlasBounds||this._tlasBounds.length<e*6)&&(this._tlasBounds=new Float32Array(e*6));let t=this.instanceTable;for(let n=e-1;n>=0;n--){let e=this.bvhIndexChunks.chunkFor(n),r=this.bvh.chunkFor(n),i=this.bvh.baseOf(n),a=e[i+3];if(a===nt.BLAS_POINTER_LEAF){let r=e[i+1]&tt;r<t.count&&t.writeWorldAABB(r,this._tlasBounds,n*6)}else if(a<nt.TRIANGLE_LEAF){let t=a,o=e[i+7],s=t*6,c=o*6,l=this._tlasBounds;r[i]=l[s],r[i+1]=l[s+1],r[i+2]=l[s+2],r[i+4]=l[s+3],r[i+5]=l[s+4],r[i+6]=l[s+5],r[i+8]=l[c],r[i+9]=l[c+1],r[i+10]=l[c+2],r[i+12]=l[c+3],r[i+13]=l[c+4],r[i+14]=l[c+5];let u=n*6;l[u]=Math.min(l[s],l[c]),l[u+1]=Math.min(l[s+1],l[c+1]),l[u+2]=Math.min(l[s+2],l[c+2]),l[u+3]=Math.max(l[s+3],l[c+3]),l[u+4]=Math.max(l[s+4],l[c+4]),l[u+5]=Math.max(l[s+5],l[c+5])}}}scheduleBackgroundRebuild(e,t){if(!this.instanceTable||!this.triangles)return;this._rebuildGeneration++;let n=this._rebuildGeneration,r=(e,r,i)=>{let a=this.triangles.copyOf(r.triOffset,r.triCount);this._pendingRebuilds.set(e,i),i.onmessage=a=>{let o=a.data;if(i.terminate(),this._pendingRebuilds.delete(e),o.error){_c.error(`background BLAS rebuild failed (mesh ${e}):`,o.error);return}n===this._rebuildGeneration&&this._swapBLAS(e,r,o,t)},i.onerror=t=>{_c.error(`background BLAS rebuild worker failed (mesh ${e}):`,t),i.terminate(),this._pendingRebuilds.delete(e)};let o=r.triCount>500;i.postMessage({triangleData:a.buffer,triangleByteOffset:a.byteOffset,triangleByteLength:a.byteLength,triangleCount:r.triCount,depth:this.config.bvhDepth,maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,reportProgress:!1,sharedReorderBuffer:null,treeletOptimization:{enabled:o,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold},reinsertionOptimization:{enabled:this.bvhBuilder.enableReinsertionOptimization,batchSizeRatio:this.bvhBuilder.reinsertionBatchSizeRatio,maxIterations:this.bvhBuilder.reinsertionMaxIterations}},[a.buffer])};for(let t of e){let e=this._placementOf(t);if(e<0)continue;let n=this.instanceTable.entryAt(e);if(!n||!this.instanceTable.isOwner(e))continue;let i=this._pendingRebuilds.get(e);i&&i.terminate(),r(e,n,new So)}}_swapBLAS(e,t,n,r){let i=n.bvhData,a=i.length/16;if(a>t.blasNodeCount){_c.warn(`background rebuild does not fit for mesh ${e} (${a} nodes vs ${t.blasNodeCount} reserved), skipping swap`);return}this.bvh.setRecords(t.blasOffset,i),this._offsetBLASInPlace(t.blasOffset,a,t.blasOffset,t.triOffset);let o=n.triangles;o&&this.triangles.setRecords(t.triOffset,o),this.instanceTable.setBlasNodeCount(e,a);let s=n.originalToBvh;if(s){let n=this.instanceTable.bvhToOriginalOf(e),r=new Uint32Array(t.triCount);for(let e=0;e<t.triCount;e++)r[s[e]]=n?n[e]:e;this.instanceTable.setBvhToOriginal(e,r)}this.instanceTable.recomputeAABB(e,this.bvh,this.triangles),this._refitTLAS(),this._log(`Background BLAS rebuild complete for mesh ${e}`),r?.(this.instanceTable.sourceMesh[e]??e)}cancelBackgroundRebuilds(){for(let e of this._pendingRebuilds.values())e.terminate();this._pendingRebuilds.clear()}_disposeRefitWorker(){this._refitWorker&&=(this._refitWorker.terminate(),null),this._refitSharedBuffers=null,this.cancelBackgroundRebuilds()}_disposeTLASWorker(){this._tlasWorker&&=(this._tlasWorker.terminate(),null)}dispose(){this._log(`Disposing resources`),this._disposeRefitWorker(),this._disposeTLASWorker(),this._disposeTextures(),this._reset(),this.textureCreator&&=(this.textureCreator.dispose(),null),this.geometryExtractor=null,this.bvhBuilder=null,this.tlasBuilder=null,this._blasRefitter=null}},yc=[[1619.19106,-.00205010916,5.02995757],[2488.45471,-.00111330907,3.22621544],[3341.43193,-.000486551192,1.76486769],[4094.61742,-.000127446582,.725731635],[4670.28036,291258199e-13,.126703442],[4595.09185,287495649e-13,.15034502],[3787.1745,935907826e-14,.399075871]],bc=[[-488.999748,.000604330754,-.0755807526],[-755.994277,.000316730098,.478306139],[-1023.63977,.00012022347,.936662319],[-1265.71316,487340896e-14,1.27054498],[-1425.29332,-401150431e-13,1.43972784],[-1175.54822,-216378048e-13,1.30408023],[-500.799571,-459832026e-14,1.09098763]],xc=[[596945309e-19,-4.85742887e-8,-970622247e-13,-.00407936148],[240430366e-19,5.55021075e-8,-.000198503712,.0289312858],[-140949732e-19,1.89878968e-7,-.000356632824,.0910767778],[-361460868e-19,2.84822009e-7,-.000493211319,.15672344],[-197075738e-19,1.75359352e-7,-.000250542825,-.0222783266],[-161997957e-21,-1.64216008e-8,.000386216271,-.738077418],[672650283e-21,-2.73078809e-8,.000424098264,-.752335691]];function Sc(e){let t,n,r;if(e>=12e3)t=.8262954810464208,n=.9945080501520986,r=1.566307710274283;else if(e<800)t=5.413294490189271,n=-.20319390035873933,r=-.0822535242887164;else{let i=e>=6365?6:e>=3315?5:e>=1902?4:e>=1449?3:e>=1167?2:+(e>=965),a=yc[i],o=bc[i],s=xc[i],c=1/e;t=a[0]*c+a[1]*e+a[2],n=o[0]*c+o[1]*e+o[2],r=((s[0]*e+s[1])*e+s[2])*e+s[3]}return[Math.max(0,t),Math.max(0,n),Math.max(0,r)]}var Cc=1/(4*Math.PI);function wc(e){let t=e.userData||{},n=Number.isFinite(t.exposure)?t.exposure:0,r=e.intensity*2**n,i=e.color.r,a=e.color.g,o=e.color.b;if(t.useTemperature){let[e,n,r]=Sc(t.temperature??6500);i*=e,a*=n,o*=r}return{r:i,g:a,b:o,intensity:r}}var Tc=class{constructor(){this.lightData={directional:[],rectArea:[],point:[],spot:[]},this.directionalLightCache=[],this.areaLightCache=[],this.pointLightCache=[],this.spotLightCache=[]}clear(){this.lightData.directional=[],this.lightData.rectArea=[],this.lightData.point=[],this.lightData.spot=[],this.directionalLightCache=[],this.areaLightCache=[],this.pointLightCache=[],this.spotLightCache=[]}calculateLightImportance(e,t=`directional`){let n=.2126*e.color.r+.7152*e.color.g+.0722*e.color.b,r=e.intensity*n;if(t===`area`){let t=e.width*e.height;r*=Math.sqrt(t)}else if(t===`point`)r*=Math.sqrt(e.distance||100);else if(t===`spot`){let t=Math.sin(e.angle||Math.PI/4);r*=Math.sqrt(e.distance||100)*t}return r}addDirectionalLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n;if(e.target){e.target.updateMatrixWorld();let i=e.target.getWorldPosition(new r.Vector3);n=t.sub(i).normalize()}else n=t.normalize();let i=this.calculateLightImportance(e,`directional`),a=e.userData.angle||e.angle||0,o=wc(e),s=e.userData?.gobo,c=s&&Number.isInteger(s.index)?s.index:-1,l=s&&typeof s.intensity==`number`?s.intensity:1,u=s&&s.inverted?-Math.abs(l):Math.abs(l),d=s&&typeof s.scale==`number`?s.scale:5;this.directionalLightCache.push({data:[n.x,n.y,n.z,o.r,o.g,o.b,o.intensity,a,c,u,d,0],importance:i,light:e})}addRectAreaLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=e.getWorldQuaternion(new r.Quaternion),i=e.getWorldScale(new r.Vector3),a=e.width*i.x*.5,o=e.height*i.y*.5,s=new r.Vector3(a,0,0).applyQuaternion(n),c=new r.Vector3(0,-o,0).applyQuaternion(n),l=this.calculateLightImportance(e,`area`),u=e.userData?.normalize??!0?1:0,d=Number.isFinite(e.userData?.spread)?e.userData.spread:Math.PI,f=+(e.userData?.shape===`ellipse`||e.userData?.shape===`disk`||e.userData?.shape===1),p=wc(e);this.areaLightCache.push({data:[t.x,t.y,t.z,s.x,s.y,s.z,c.x,c.y,c.z,p.r,p.g,p.b,p.intensity,u,d,f],importance:l,light:e})}addPointLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=this.calculateLightImportance(e,`point`),i=wc(e);this.pointLightCache.push({data:[t.x,t.y,t.z,i.r,i.g,i.b,i.intensity*Cc,e.distance||0,e.decay===void 0?2:e.decay],importance:n,light:e})}addSpotLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=(e.target?e.target.getWorldPosition(new r.Vector3):new r.Vector3(0,0,-1)).sub(t).normalize(),i=this.calculateLightImportance(e,`spot`),a=e.userData?.gobo,o=a&&Number.isInteger(a.index)?a.index:-1,s=a&&typeof a.intensity==`number`?a.intensity:1,c=a&&a.inverted?-Math.abs(s):Math.abs(s),l=e.userData?.ies,u=l&&Number.isInteger(l.index)?l.index:-1,d=l&&typeof l.intensity==`number`?l.intensity:1,f=wc(e);this.spotLightCache.push({data:[t.x,t.y,t.z,n.x,n.y,n.z,f.r,f.g,f.b,f.intensity*Cc,e.angle||Math.PI/4,e.penumbra||0,e.distance||0,e.decay===void 0?2:e.decay,o,c,u,d,0,0],importance:i,light:e})}preprocessLights(){this.directionalLightCache.sort((e,t)=>t.importance-e.importance),this.areaLightCache.sort((e,t)=>t.importance-e.importance),this.pointLightCache.sort((e,t)=>t.importance-e.importance),this.spotLightCache.sort((e,t)=>t.importance-e.importance),this.lightData.directional=[],this.lightData.rectArea=[],this.lightData.point=[],this.lightData.spot=[],this.directionalLightCache.forEach(e=>{this.lightData.directional.push(...e.data)}),this.areaLightCache.forEach(e=>{this.lightData.rectArea.push(...e.data)}),this.pointLightCache.forEach(e=>{this.lightData.point.push(...e.data)}),this.spotLightCache.forEach(e=>{this.lightData.spot.push(...e.data)}),this.areaLightCache.length>0&&console.log(`Preprocessed ${this.areaLightCache.length} area lights by importance`),this.pointLightCache.length>0&&console.log(`Preprocessed ${this.pointLightCache.length} point lights by importance`),this.spotLightCache.length>0&&console.log(`Preprocessed ${this.spotLightCache.length} spot lights by importance`)}updateShaderUniforms(e){let t=Math.floor(this.lightData.directional.length/12),n=Math.floor(this.lightData.rectArea.length/16),r=Math.floor(this.lightData.point.length/9),i=Math.floor(this.lightData.spot.length/20);e.defines.MAX_DIRECTIONAL_LIGHTS=t,e.defines.MAX_AREA_LIGHTS=n,e.defines.MAX_POINT_LIGHTS=r,e.defines.MAX_SPOT_LIGHTS=i,e.uniforms.directionalLights.value=new Float32Array(this.lightData.directional),e.uniforms.areaLights.value=new Float32Array(this.lightData.rectArea),e.uniforms.pointLights.value=new Float32Array(this.lightData.point),e.uniforms.spotLights.value=new Float32Array(this.lightData.spot),e.needsUpdate=!0}processSceneLights(e,t){this.clear(),e.traverse(e=>{e.isDirectionalLight?this.addDirectionalLight(e):e.isRectAreaLight?this.addRectAreaLight(e):e.isPointLight?this.addPointLight(e):e.isSpotLight&&this.addSpotLight(e)}),this.preprocessLights(),this.updateShaderUniforms(t)}getLightStatistics(){return{directionalLights:this.directionalLightCache.map(e=>({intensity:e.light.intensity,importance:e.importance,color:e.light.color})),areaLights:this.areaLightCache.map(e=>({intensity:e.light.intensity,importance:e.importance,color:e.light.color,size:e.light.width*e.light.height}))}}},Ec={stbnScalarAtlas:`https://assets.rayzee.atulmourya.com/noise/stbn_scalar_atlas.png`,stbnVec2Atlas:`https://assets.rayzee.atulmourya.com/noise/stbn_vec2_atlas.png`,ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,dracoDecoderPath:`https://www.gstatic.com/draco/v1/decoders/`,ktx2TranscoderPath:`https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/libs/basis/`,oidnWeightsBaseUrl:`https://cdn.jsdelivr.net/npm/denoiser/tzas/`,upscalerModelBaseUrl:`https://huggingface.co/notaneimu/onnx-image-models/resolve/main/`,cacheNamespace:`rayzee`};function Dc(e){e&&Object.assign(Ec,e)}function Oc(){return{...Ec}}var kc=It(`pathtracer`),Ac=100,jc=4,Mc=class extends _e{constructor(e,t,n,i={}){super(`PathTracer`,{...i,executionMode:ge.ALWAYS});let a=i.width||1920,o=i.height||1080;this.camera=n,this.width=a,this.height=o,this.renderer=e,this.scene=t,this.sdfs=new vc,this.lightSerializer=new Tc,this.accumulationEnabled=!0,this.isComplete=!1,this.cameras=[],this.performanceMonitor=je(),this.completionThreshold=0,this.renderLimitMode=`frames`,this._initDataTextures(),this.storageTextures=new Ut(0,0),this.uniforms=new Gt(a,o),this._defineUniformGetters(),this.materialData=new Zt(this.sdfs),this.materialData.callbacks.onReset=()=>this.reset(),this.materialData.callbacks.getTriangleData=()=>({array:this.triangleStorageAttr?.array,records:this._triangleRecords,count:this.triangleCount}),this.materialData.callbacks.onTriangleDataChanged=()=>{this.triangleStorageAttr&&(this._triangleRecords?x(this.renderer,this.triangleStorageAttr,this._triangleRecords.chunks):this.triangleStorageAttr.needsUpdate=!0)},this.environment=new jn(this.scene,this.uniforms),this.environment.callbacks.onReset=()=>this.reset(),this.environment.callbacks.getSceneTextureNodes=()=>this.shaderBuilder.getSceneTextureNodes(),this.shaderBuilder=new Ba,this._initRenderingState(),this.setupBlueNoise(),this.tempVector2=new r.Vector2,this.lastCameraMatrix=new r.Matrix4,this.lastProjectionMatrix=new r.Matrix4,this._seedTick=0,this._pinSeedToFrame=!1,this.lastRenderMode=-1,this.renderModeChangeTimeout=null,this.renderModeChangeDelay=50,this.pendingRenderMode=null,this.lastInteractionModeState=!1,this.cameraChanged=!1,this._lastViewChangeAt=-1/0,this.updateCompletionThreshold()}_initDataTextures(){this.triangleStorageAttr=null,this._triangleRecords=null,this.triangleStorageNode=null,this.triangleCount=0,this.bvhStorageAttr=null,this._bvhRecords=null,this.bvhStorageNode=null,this.bvhNodeCount=0,this.directionalLightsData=null,this.pointLightsData=null,this.spotLightsData=null,this.areaLightsData=null,this.goboMaps=null,this.iesProfiles=null,this.stbnScalarTexture=null,this.stbnVec2Texture=null,this.blueNoiseReady=Promise.resolve(),this.lightStorageAttr=new t.StorageInstancedBufferAttribute(new Float32Array(16),4),this.lightStorageNode=(0,n.storage)(this.lightStorageAttr,`vec4`,1).toReadOnly(),this._lightBufferRealloc=!1,this._lbvhDataCache=null,this._emissiveDataCache=null,this._bitTrailMapCache=null,this._instanceTable=null,this.spheres=[]}_defineUniformGetters(){let e=this.uniforms;for(let t of e.keys())Object.defineProperty(this,t,{get:()=>e.get(t),configurable:!0});let t=e.getLightBufferNodes();for(let[e,n]of Object.entries(t))Object.defineProperty(this,`${e}LightsBufferNode`,{get:()=>n,configurable:!0})}_initRenderingState(){this.isReady=!1,this.frameCount=0}_initCameraOptimizer(){let e=this;this.cameraOptimizer=new ve(this.renderer,{uniforms:{maxBounceCount:{get value(){return e.maxBounces.value},set value(t){e.maxBounces.value=t}},enableAccumulation:{get value(){return e.enableAccumulation.value},set value(t){e.enableAccumulation.value=t}},enableEmissiveTriangleSampling:{get value(){return e.enableEmissiveTriangleSampling.value},set value(t){e.enableEmissiveTriangleSampling.value=t}},cameraIsMoving:{get value(){return e.cameraIsMoving.value},set value(t){e.cameraIsMoving.value=t}}}},{enabled:W.interactionModeEnabled,qualitySettings:{maxBounceCount:1,enableAccumulation:!1,enableEmissiveTriangleSampling:!1},onReset:()=>{this.reset(),this.emit(`pathtracer:viewpointChanged`)}})}setupBlueNoise(){let e=new r.TextureLoader;e.setCrossOrigin(`anonymous`);let t=e=>(e.minFilter=r.NearestFilter,e.magFilter=r.NearestFilter,e.wrapS=r.RepeatWrapping,e.wrapT=r.RepeatWrapping,e.generateMipmaps=!1,e),{stbnScalarAtlas:n,stbnVec2Atlas:i}=Oc(),a=e.loadAsync(n).then(e=>{this.stbnScalarTexture=t(e),P.value=e,kc.debug(`STBN scalar atlas ${Y.px(e.image.width,e.image.height)}`)}),o=e.loadAsync(i).then(e=>{this.stbnVec2Texture=t(e),F.value=e,kc.debug(`STBN vec2 atlas ${Y.px(e.image.width,e.image.height)}`)});this.blueNoiseReady=Promise.allSettled([a,o]).then(e=>{for(let t of e)t.status===`rejected`&&kc.warn(`STBN atlas failed to load`,t.reason)})}setupEventListeners(){this.on(`pipeline:reset`,()=>{this.reset()}),this.on(`pipeline:resize`,e=>{e&&e.width&&e.height&&this.setSize(e.width,e.height)}),this.on(`pathtracer:setCompletionThreshold`,e=>{e&&e.threshold!==void 0&&(this.completionThreshold=e.threshold)})}async build(e){this.dispose(),this.scene=e,await this.sdfs.buildBVH(e),this.cameras=this.sdfs.cameras,this.updateSceneUniforms(),this.updateLights(),this._initCameraOptimizer(),this.setupMaterial()}updateSceneUniforms(){this.setTriangleData(this.sdfs.triangleData,this.sdfs.triangleCount),this.setBVHData(this.sdfs.bvhData),this.setInstanceTable(this.sdfs.instanceTable),this.materialData.setMaterialData(this.sdfs.materialData),this.materialData.loadTexturesFromSdfs(),this.sdfs.emissiveTriangleData?this.setEmissiveTriangleData(this.sdfs.emissiveTriangleData,this.sdfs.emissiveTriangleCount||0):this.emissiveTriangleCount.value=0,this.sdfs.lightBVHNodeData?this.setLightBVHData(this.sdfs.lightBVHNodeData,this.sdfs.lightBVHNodeCount||0):this.lightBVHNodeCount.value=0,this._meshRefs=this._collectMeshRefs(this.scene),this.setMeshVisibilityData(this._meshRefs),this.spheres=this.sdfs.spheres||[]}updateLights(){let e={uniforms:{directionalLights:{value:null},pointLights:{value:null},spotLights:{value:null},areaLights:{value:null}},defines:{}};if(this.lightSerializer.processSceneLights(this.scene,e),this.directionalLightsData=e.uniforms.directionalLights.value,this.pointLightsData=e.uniforms.pointLights.value,this.spotLightsData=e.uniforms.spotLights.value,this.areaLightsData=e.uniforms.areaLights.value,this.hasSun.value){let t=this.environment.envParams.skySunIntensity*950,n={intensity:t,color:{r:1,g:1,b:1},userData:{angle:this.sunAngularSize.value},updateMatrixWorld:()=>{},getWorldPosition:e=>{let t=this.sunDirection.value;return e.set(t.x,t.y,t.z).multiplyScalar(1e10)}};this.lightSerializer.addDirectionalLight(n),this.lightSerializer.preprocessLights(),this.lightSerializer.updateShaderUniforms(e),this.directionalLightsData=e.uniforms.directionalLights.value,kc.debug(`sun added as directional light · intensity ${t.toFixed(2)}`)}this._updateLightBufferNodes()}_updateLightBufferNodes(){this.directionalLightsData&&this.directionalLightsData.length>0?(this.directionalLightsBufferNode.array=Array.from(this.directionalLightsData),this.numDirectionalLights.value=Math.floor(this.directionalLightsData.length/12)):this.numDirectionalLights.value=0,this.areaLightsData&&this.areaLightsData.length>0?(this.areaLightsBufferNode.array=Array.from(this.areaLightsData),this.numAreaLights.value=Math.floor(this.areaLightsData.length/16)):this.numAreaLights.value=0,this.pointLightsData&&this.pointLightsData.length>0?(this.pointLightsBufferNode.array=Array.from(this.pointLightsData),this.numPointLights.value=Math.floor(this.pointLightsData.length/9)):this.numPointLights.value=0,this.spotLightsData&&this.spotLightsData.length>0?(this.spotLightsBufferNode.array=Array.from(this.spotLightsData),this.numSpotLights.value=Math.floor(this.spotLightsData.length/20)):this.numSpotLights.value=0}reset(){this.frameCount=0,this.frame.value=0,this.hasPreviousAccumulated.value=0,this.storageTextures.currentTarget=0,this.updateCompletionThreshold(),this.isComplete=!1,this.performanceMonitor?.reset(),this.lastInteractionModeState=!1,this._pinSeedToFrame&&(this._seedTick=0)}setSize(e,t){this.width=e,this.height=t,this.resolution.value.set(e,t),this.createStorageTextures(e,t)}setAccumulationEnabled(e){this.accumulationEnabled=e,this.enableAccumulation.value=+!!e}enterInteractionMode(){this.cameraOptimizer?.enterInteractionMode()}setInteractionModeEnabled(e){this.cameraOptimizer?.setInteractionModeEnabled(e)}get interactionMode(){return this.cameraOptimizer?.isInInteractionMode()??!1}get viewIsChanging(){return this.interactionMode||performance.now()-this._lastViewChangeAt<Ac}noteViewChanged(){this._lastViewChangeAt=performance.now()}setTriangleData(e,r){if(!e)return;let i=e.chunks&&e.chunks.length>1?e:null,a=i?null:e.chunks?e.chunks[0]:e,o=(i?i.recordCount*i.lanesPerRecord:a.length)/4,s=()=>i?y(o,4,Uint32Array):new t.StorageInstancedBufferAttribute(a,4);this.triangleStorageNode?(this.triangleStorageAttr=s(),this.triangleStorageNode.value=this.triangleStorageAttr,this.triangleStorageNode.bufferCount=o):(this.triangleStorageAttr=s(),this.triangleStorageNode=(0,n.storage)(this.triangleStorageAttr,`uvec4`,o).toReadOnly()),this._triangleRecords=i,i&&x(this.renderer,this.triangleStorageAttr,i.chunks),this.triangleCount=r,kc.debug(`${Y.n(this.triangleCount)} triangles (storage buffer)`)}setBVHData(e){if(!e)return;let r=e.chunks&&e.chunks.length>1?e:null,i=r?null:e.chunks?e.chunks[0]:e,a=(r?r.recordCount*r.lanesPerRecord:i.length)/4,o=()=>r?y(a,4,Float32Array):new t.StorageInstancedBufferAttribute(i,4);this.bvhStorageNode?(this.bvhStorageAttr=o(),this.bvhStorageNode.value=this.bvhStorageAttr,this.bvhStorageNode.bufferCount=a):(this.bvhStorageAttr=o(),this.bvhStorageNode=(0,n.storage)(this.bvhStorageAttr,`vec4`,a).toReadOnly()),this._bvhRecords=r,r&&x(this.renderer,this.bvhStorageAttr,r.chunks),this.bvhNodeCount=Math.floor(a/jc),kc.debug(`${Y.n(this.bvhNodeCount)} BVH nodes (storage buffer)`)}setInstanceTable(e){this._instanceTable=e}setMeshVisibilityData(e){!e||e.length===0||!this._instanceTable||(this._patchVisibilityFromMeshes(e),this._flushBVHEdits())}_patchVisibilityFromMeshes(e){let t=this._instanceTable,n=new Map;for(let r=0;r<t.count;r++){if(!t.isSet[r])continue;let i=t.sourceMesh[r],a=n.get(i);a===void 0&&n.set(i,a=this._isWorldVisible(e[i])),this._patchTLASLeafVisibility(r,a)}}updateMeshVisibility(e,t){this._patchTLASLeafVisibility(e,t)&&this._flushBVHEdits()}updateAllMeshVisibility(){!this._meshRefs||!this._instanceTable||(this._patchVisibilityFromMeshes(this._meshRefs),this._flushBVHEdits())}_patchTLASLeafVisibility(e,t){let n=this._instanceTable;if(!n||!n.isSet?.[e]||!this.bvhStorageAttr)return!1;let r=n.tlasLeafIndex[e];return r<0?!1:(n.visible[e]=+!!t,this._bvhRecords?this._bvhRecords.chunkFor(r)[this._bvhRecords.baseOf(r)+2]=+!!t:this.bvhStorageAttr.array[r*16+2]=+!!t,this._dirtyBVHLeaves??=new Set,this._dirtyBVHLeaves.add(r),!0)}_flushBVHEdits(){if(this.bvhStorageAttr){if(!this._bvhRecords){this.bvhStorageAttr.needsUpdate=!0,this._dirtyBVHLeaves?.clear();return}for(let e of this._dirtyBVHLeaves??[])S(this.renderer,this.bvhStorageAttr,this._bvhRecords,e*16,16);this._dirtyBVHLeaves?.clear()}}_collectMeshRefs(e){if(!e)return[];let t=[];return e.traverse(e=>{e.isMesh&&e.userData.meshIndex!==void 0&&(t[e.userData.meshIndex]=e)}),t}_isWorldVisible(e){for(;e;){if(!e.visible)return!1;e=e.parent}return!0}_updateStorageBuffer(e,t){e&&(e.array.set(t),e.needsUpdate=!0)}updateTriangleData(e){if(this._triangleRecords){x(this.renderer,this.triangleStorageAttr,this._triangleRecords.chunks);return}this._updateStorageBuffer(this.triangleStorageAttr,e?.chunks?e.chunks[0]:e)}updateBVHData(e){if(this._bvhRecords){x(this.renderer,this.bvhStorageAttr,this._bvhRecords.chunks);return}this._updateStorageBuffer(this.bvhStorageAttr,e?.chunks?e.chunks[0]:e)}updateBufferRanges(e,t){if(this.triangleStorageAttr&&e.length>0)if(this._triangleRecords)for(let t of e)S(this.renderer,this.triangleStorageAttr,this._triangleRecords,t.offset,t.count);else{this.triangleStorageAttr.clearUpdateRanges();for(let t of e)this.triangleStorageAttr.addUpdateRange(t.offset,t.count);this.triangleStorageAttr.version++}if(this.bvhStorageAttr&&t.length>0)if(this._bvhRecords)for(let e of t)S(this.renderer,this.bvhStorageAttr,this._bvhRecords,e.offset,e.count);else{this.bvhStorageAttr.clearUpdateRanges();for(let e of t)this.bvhStorageAttr.addUpdateRange(e.offset,e.count);this.bvhStorageAttr.version++}}createStorageTextures(e,t){this.storageTextures.writeColor?this.storageTextures.setSize(e,t):this.storageTextures.create(e,t),this.resolution.value.set(e,t)}setupMaterial(){if(this.cameraOptimizer||this._initCameraOptimizer(),!this.triangleStorageNode){kc.error(`triangle data required`);return}if(!this.bvhStorageNode){kc.error(`BVH data required`);return}if(this.isReady&&this.shaderBuilder.getSceneTextureNodes()){this.shaderBuilder.updateSceneTextures(this);return}this._ensureStorageTextures(),this.shaderBuilder.createSceneTextureNodes(this,this.storageTextures),this.isReady=!0}_ensureStorageTextures(){let e=this.renderer.domElement,t=Math.max(1,e.width||this.width),n=Math.max(1,e.height||this.height);this.storageTextures.ensureSize(t,n)&&this.resolution.value.set(t,n)}_handleResize(){let{width:e,height:t}=this.renderer.domElement;(e!==this.storageTextures.renderWidth||t!==this.storageTextures.renderHeight)&&(this.createStorageTextures(e,t),this.frameCount=0),this.resolution.value.set(e,t)}_matricesApproxEqual(e,t,n=1e-10){let r=e.elements,i=t.elements;for(let e=0;e<16;e++)if(Math.abs(r[e]-i[e])>n)return!1;return!0}_updateCameraUniforms(){return!this._matricesApproxEqual(this.lastCameraMatrix,this.camera.matrixWorld)||!this._matricesApproxEqual(this.lastProjectionMatrix,this.camera.projectionMatrixInverse)?(this.cameraWorldMatrix.value.copy(this.camera.matrixWorld),this.cameraViewMatrix.value.copy(this.camera.matrixWorldInverse),this.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.cameraProjectionMatrixInverse.value.copy(this.camera.projectionMatrixInverse),this.lastCameraMatrix.copy(this.camera.matrixWorld),this.lastProjectionMatrix.copy(this.camera.projectionMatrixInverse),!0):!1}_updateAccumulationUniforms(e,t){let n=this.cameraOptimizer?.isInInteractionMode()??!1;this.lastInteractionModeState=n,this.accumulationEnabled?n?(this.accumulationAlpha.value=1,this.hasPreviousAccumulated.value=0):(this.accumulationAlpha.value=Ae(e),this.hasPreviousAccumulated.value=+(e>0)):(this.accumulationAlpha.value=1,this.hasPreviousAccumulated.value=0)}_publishTexturesToContext(e,t){e.setTexture(`pathtracer:color`,t.color),e.setTexture(`pathtracer:normalDepth`,t.normalDepth),e.setTexture(`pathtracer:albedo`,t.albedo),e.setState(`pathtracer:samples`,this.frameCount),e.setState(`interactionMode`,this.cameraOptimizer?.isInInteractionMode()??!1),e.setState(`renderMode`,this.renderMode.value)}_emitStateEvents(){this.emit(`pathtracer:frameComplete`,{frame:this.frameCount,isComplete:this.isComplete}),this.cameraChanged&&=(this.emit(`camera:moved`),!1)}updateCompletionThreshold(){this.completionThreshold=ke(this.renderMode.value,this.maxSamples.value)}setRenderLimitMode(e){this.renderLimitMode=e,this.updateCompletionThreshold()}manageASVGFForRenderMode(e){e!==this.lastRenderMode&&(this.renderModeChangeTimeout&&clearTimeout(this.renderModeChangeTimeout),this.pendingRenderMode=e,this.renderModeChangeTimeout=setTimeout(()=>{this.pendingRenderMode!==null&&this.pendingRenderMode!==this.lastRenderMode&&(this.lastRenderMode=this.pendingRenderMode,this.emit(`asvgf:reset`),this.emit(`denoiser:reset`)),this.renderModeChangeTimeout=null,this.pendingRenderMode=null},this.renderModeChangeDelay))}setUniform(e,t){this.uniforms.set(e,t)}setBlueNoiseTexture(e){this.stbnScalarTexture=e,e&&(P.value=e)}_rebuildLightBuffer(){let e=this._lbvhDataCache,n=this._emissiveDataCache,r=this._bitTrailMapCache,i=e?e.length:0,a=n?n.length:0,o=r?Math.ceil(r.length/4)*4:0,s=Math.max(i+a+o,4);if(this.lightStorageAttr&&s<=this.lightStorageAttr.array.length){let t=this.lightStorageAttr.array;e&&t.set(e,0),n&&t.set(n,i),r&&t.set(r,i+a),this.lightStorageAttr.needsUpdate=!0}else{let o=new Float32Array(s);e&&o.set(e,0),n&&o.set(n,i),r&&o.set(r,i+a),this.lightStorageAttr=new t.StorageInstancedBufferAttribute(o,4),this.lightStorageNode.value=this.lightStorageAttr,this.lightStorageNode.bufferCount=o.length/4,this._lightBufferRealloc=!0}this.emissiveVec4Offset.value=(this.lightBVHNodeCount.value||0)*4,this.reverseMapVec4Offset.value=(i+a)/4}setEmissiveTriangleData(e,t,n=0,r=null){e&&(this._emissiveDataCache=e,r&&(this._bitTrailMapCache=r),this.emissiveTriangleCount.value=t,this.emissiveTotalPower.value=n,this._rebuildLightBuffer(),kc.debug(`${Y.n(t)} emissive triangles · totalPower ${n.toFixed(4)} (storage buffer)`))}setLightBVHData(e,t){e&&(this._lbvhDataCache=e,this.lightBVHNodeCount.value=t,this._rebuildLightBuffer(),kc.debug(`light BVH ${Y.n(t)} nodes`))}updateUniforms(e){let t=!1;for(let[n,r]of Object.entries(e))this[n]&&this[n].value!==void 0&&this[n].value!==r&&(this[n].value=r,t=!0);t&&this.reset()}async rebuildMaterials(e){if(!this.sdfs)throw Error(`Scene not built yet. Call build() first.`);try{kc.debug(`material rebuild started`),await this.sdfs.rebuildMaterials(e),this.updateSceneUniforms(),this.shaderBuilder.updateSceneTextures(this),this.updateLights(),this.reset(),kc.debug(`material rebuild complete`)}catch(e){kc.error(`material rebuild failed:`,e);try{kc.warn(`attempting recovery by resetting the path tracer`),this.reset()}catch(e){kc.error(`recovery failed:`,e)}throw e}}dispose(){this.renderModeChangeTimeout&&=(clearTimeout(this.renderModeChangeTimeout),null),this.cameraOptimizer?.dispose(),this.materialData?.dispose(),this.environment?.dispose(),this.shaderBuilder?.dispose(),this.uniforms?.dispose(),this.storageTextures?.dispose(),this.stbnScalarTexture?.dispose(),this.stbnVec2Texture?.dispose(),this.placeholderTexture?.dispose(),this.triangleStorageAttr=null,this._triangleRecords=null,this.triangleStorageNode=null,this.bvhStorageAttr=null,this._bvhRecords=null,this.bvhStorageNode=null,this.placeholderTexture=null,this.isReady=!1}},Nc=It(`gpu`),Pc={ORIGIN_META:0,DIR_FLAGS:1,THROUGHPUT_PDF:2,RADIANCE_ALPHA:3,MEDIUM_STACK:4,MEDIUM_SIGMA_A:5,SSS_SIGMA_S:6},Fc={DIST_TRI_BARY:0,NORMAL_MAT:1},Ic=0,Lc=(e,t)=>t===0?e:e.add(t*Ic);function Rc(e,t){t&&e?._attributes?.delete?.(t)}var zc=class{constructor(e=0,t=null){this.capacity=0,this._renderer=t,this._attrs={},this.rayBuffer=null,this.rngBuffer=null,this.hitBuffer=null,e>0&&this.allocate(e)}allocate(e){this.dispose(),this.capacity=e,Ic=e;let t=e*7,r=y(t,4);this._attrs.ray=r,this.rayBuffer={rw:(0,n.storage)(r,`vec4`),ro:(0,n.storage)(r,`vec4`).toReadOnly()};let i=y(e,1,Uint32Array);this._attrs.rng=i,this.rngBuffer={rw:(0,n.storage)(i,`uint`),ro:(0,n.storage)(i,`uint`).toReadOnly()};let a=e*2,o=y(a,4,Uint32Array);this._attrs.hit=o,this.hitBuffer={rw:(0,n.storage)(o,`uvec4`),ro:(0,n.storage)(o,`uvec4`).toReadOnly()},this.rayBytes=t*16+e*4,this.hitBytes=a*16,this.totalBytes=this.rayBytes+this.hitBytes,Nc.debug(`ray pool capacity ${Y.n(e)} · ${Y.mb(this.totalBytes)} (rays ${Y.mb(this.rayBytes)} · hits ${Y.mb(this.hitBytes)})`)}resize(e){return e<=this.capacity&&this.capacity>0?!1:(this.allocate(e),!0)}dispose(){Rc(this._renderer,this._attrs.ray),Rc(this._renderer,this._attrs.rng),Rc(this._renderer,this._attrs.hit),this._attrs={},this.rayBuffer=null,this.rngBuffer=null,this.hitBuffer=null,this.capacity=0}},Bc=(e,t)=>e.element(Lc(t,Pc.ORIGIN_META)).xyz,Vc=(e,t)=>e.element(Lc(t,Pc.DIR_FLAGS)).xyz,Hc=(e,t)=>(0,n.floatBitsToUint)(e.element(Lc(t,Pc.DIR_FLAGS)).w),Uc=(e,t)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).xyz,Wc=(e,t)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).w,Gc=(e,t)=>e.element(Lc(t,Pc.RADIANCE_ALPHA)),Kc=e=>(0,n.uint)(e).mul(1),qc=(e,t,r,i,a,o=null)=>{let s=Kc(t),c=o===null?(0,n.unpackUnorm2x16)(e.element(s).w).y:(0,n.float)(o);return e.element(s).assign((0,n.uvec4)((0,n.packSnorm2x16)((0,n.vec2)(r.x,r.y)),(0,n.packSnorm2x16)((0,n.vec2)(r.z,i)),(0,n.packUnorm2x16)((0,n.vec2)(a.x,a.y)),(0,n.packUnorm2x16)((0,n.vec2)(a.z,c))))},Jc=(e,t,r)=>{let i=Kc(t),a=e.element(i).toVar();return e.element(i).assign((0,n.uvec4)(a.x,a.y,a.z,(0,n.packUnorm2x16)((0,n.vec2)((0,n.unpackUnorm2x16)(a.w).x,r))))},Yc=(e,t)=>e.element(Kc(t)),Xc=e=>(0,n.unpackUnorm2x16)(e.w).y,Zc=e=>{let t=(0,n.unpackSnorm2x16)(e.x),r=(0,n.unpackSnorm2x16)(e.y);return(0,n.vec4)((0,n.vec3)(t.x,t.y,r.x).mul(.5).add(.5),r.y)},Qc=e=>(0,n.vec3)((0,n.unpackUnorm2x16)(e.z),(0,n.unpackUnorm2x16)(e.w).x),$c=e=>{let t=(0,n.clamp)((0,n.floor)((0,n.log2)((0,n.max)(e,1e-6))),-8,7),r=(0,n.clamp)((0,n.float)(e).mul((0,n.exp2)(t.negate())).sub(1).mul(64),0,63);return(0,n.select)((0,n.float)(e).lessThan(.004),(0,n.uint)(0),(0,n.uint)(t.add(8)).shiftLeft(6).bitOr((0,n.uint)(r)))},el=(e,t)=>{let r=(0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(22),i=(0,n.float)(r.shiftRight(6).bitAnd((0,n.uint)(15))).sub(8),a=(0,n.float)(r.bitAnd((0,n.uint)(63))).div(64).add(1);return(0,n.select)(r.equal((0,n.uint)(0)),(0,n.float)(0),a.mul((0,n.exp2)(i)))},tl=(e,t,r,i,a,o=(0,n.uint)(0),s=null)=>{let c=(0,n.uint)(i).bitAnd((0,n.uint)(255)).bitOr((0,n.uint)(a).bitAnd((0,n.uint)(255)).shiftLeft(8)).bitOr((0,n.uint)(o).bitAnd((0,n.uint)(63)).shiftLeft(16));return s!==null&&(c=c.bitOr($c(s).shiftLeft(22))),e.element(Lc(t,Pc.ORIGIN_META)).assign((0,n.vec4)(r,(0,n.uintBitsToFloat)(c)))},nl=(e,t,r,i)=>e.element(Lc(t,Pc.DIR_FLAGS)).assign((0,n.vec4)(r,(0,n.uintBitsToFloat)(i))),rl=(e,t,r,i)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).assign((0,n.vec4)(r,i)),il=(e,t,n)=>e.element(Lc(t,Pc.RADIANCE_ALPHA)).assign(n),al=(e,t)=>(0,n.uintBitsToFloat)(e.element(Lc(t,Fc.DIST_TRI_BARY)).x),ol=(e,t)=>e.element(Lc(t,Fc.DIST_TRI_BARY)).y,sl=(e,t)=>(0,n.uintBitsToFloat)(e.element(Lc(t,Fc.DIST_TRI_BARY)).zw),cl=(e,t)=>vr(e.element(Lc(t,Fc.NORMAL_MAT)).x),ll=(e,t)=>(0,n.uint)(e.element(Lc(t,Fc.NORMAL_MAT)).y),ul=(e,t)=>(0,n.int)(e.element(Lc(t,Fc.NORMAL_MAT)).z).sub((0,n.int)(1)),dl=(e,t,r,i,a,o,s,c,l)=>{e.element(Lc(t,Fc.DIST_TRI_BARY)).assign((0,n.uvec4)((0,n.floatBitsToUint)(r),i,(0,n.floatBitsToUint)(a),(0,n.floatBitsToUint)(o))),e.element(Lc(t,Fc.NORMAL_MAT)).assign((0,n.uvec4)(_r(s),c,l,(0,n.uint)(0)))},fl=(e,t)=>{let r=e.element(Lc(t,Pc.MEDIUM_STACK)),i=(0,n.floatBitsToUint)(r.x);return{stackDepth:i.bitAnd(255),transTraversals:i.shiftRight(8).bitAnd(255),wavelength:i.shiftRight(16).bitAnd(65535),ior1:r.y,ior2:r.z,ior3:r.w}},pl=(e,t,r,i,a,o,s,c=(0,n.uint)(0))=>e.element(Lc(t,Pc.MEDIUM_STACK)).assign((0,n.vec4)((0,n.uintBitsToFloat)(r.bitOr(i.shiftLeft(8)).bitOr(c.shiftLeft(16))),a,o,s)),ml=(e,t)=>e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).xyz,hl=(e,t,r)=>{let i=e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).w.toVar();e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).assign((0,n.vec4)(r,i))},gl=e=>{let t=(0,n.clamp)(e,(0,n.vec3)(0),(0,n.vec3)(1)).mul(1023).add(.5);return(0,n.uint)(t.x).bitOr((0,n.uint)(t.y).shiftLeft(10)).bitOr((0,n.uint)(t.z).shiftLeft(20))},_l=e=>(0,n.vec3)((0,n.float)(e.bitAnd((0,n.uint)(1023))),(0,n.float)(e.shiftRight(10).bitAnd((0,n.uint)(1023))),(0,n.float)(e.shiftRight(20).bitAnd((0,n.uint)(1023)))).div(1023),vl=(e,t)=>_l((0,n.floatBitsToUint)(e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).w)),yl=(e,t,r)=>{let i=e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).xyz.toVar();e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).assign((0,n.vec4)(i,(0,n.uintBitsToFloat)(gl(r))))},bl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).bitAnd(255)),xl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(8).bitAnd(255)),Sl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(16).bitAnd((0,n.uint)(63))),Cl=(e,t)=>{let n=e.element(Lc(t,Pc.SSS_SIGMA_S));return{sigmaS:n.xyz,g:n.w}},wl=(e,t,r,i)=>e.element(Lc(t,Pc.SSS_SIGMA_S)).assign((0,n.vec4)(r,i)),Tl=It(`gpu`),$={ACTIVE_RAY_COUNT:0,ENTERING_COUNT:1,CONVERGED_COUNT:2,RESERVED_3:3,ACTIVE_PIXEL_COUNT:4,GEOMETRY_COUNT:5,CONVERGED_GEOMETRY_COUNT:6,ACTIVE_ENERGY:7,COUNT:8},El=65535,Dl={BOUNCE_MASK:255,ACTIVE:256,SPECULAR:512,INSIDE_MEDIUM:1024,RAY_TYPE_SHIFT:11,RAY_TYPE_MASK:63488,HAS_HIT_OPAQUE:65536,AUX_LOCKED:1<<17,REDIRECTED:1<<18},Ol=class{constructor(e=0,t=null){this._renderer=t,this.capacity=0,this.counters=null,this.activeIndices=null,this.activeIndicesRO=null,this.sortedIndices=null,this.sortedIndicesRO=null,this.sortGlobalHistogram=null,this.pingPong=0,e>0&&this.allocate(e)}allocate(e){this.dispose(),this.capacity=e,this._countersAttr=new t.StorageInstancedBufferAttribute(new Uint32Array($.COUNT),1),this.counters=(0,n.storage)(this._countersAttr,`uint`).toAtomic(),this.MAX_BOUNCE_SNAPSHOTS=32,this._bounceCountsAttr=new t.StorageInstancedBufferAttribute(new Uint32Array(2*this.MAX_BOUNCE_SNAPSHOTS),1),this.bounceCounts=(0,n.storage)(this._bounceCountsAttr,`uint`);let r=y(e,1,Uint32Array),i=y(e,1,Uint32Array);this._attrA=r,this._attrB=i,this.activeIndices={a:(0,n.storage)(r,`uint`),b:(0,n.storage)(i,`uint`)},this.activeIndicesRO={a:(0,n.storage)(r,`uint`).toReadOnly(),b:(0,n.storage)(i,`uint`).toReadOnly()};let a=y(e,1,Uint32Array);this._sortAttr=a,this.sortedIndices=(0,n.storage)(a,`uint`),this.sortedIndicesRO=(0,n.storage)(a,`uint`).toReadOnly(),this._sortGlobalHistAttr=new t.StorageInstancedBufferAttribute(new Uint32Array(256),1),this.sortGlobalHistogram=(0,n.storage)(this._sortGlobalHistAttr,`uint`).toAtomic(),this.pingPong=0,this.totalBytes=$.COUNT*4+e*4*3,Tl.debug(`queues capacity ${Y.n(e)} · ${Y.mb(this.totalBytes)}`)}resize(e){return e<=this.capacity&&this.capacity>0?!1:(this.allocate(e),!0)}getCounters(){return this.counters}getActiveReadRO(){return this.pingPong===0?this.activeIndicesRO.a:this.activeIndicesRO.b}getActiveRead(){return this.pingPong===0?this.activeIndices.a:this.activeIndices.b}getActiveWrite(){return this.pingPong===0?this.activeIndices.b:this.activeIndices.a}getSortedRW(){return this.sortedIndices}getSortedRO(){return this.sortedIndicesRO}getSortGlobalHistogram(){return this.sortGlobalHistogram}getCountersAttribute(){return this._countersAttr}getBounceCounts(){return this.bounceCounts}getBounceCountsAttribute(){return this._bounceCountsAttr}swap(){this.pingPong=1-this.pingPong}resetPingPong(){this.pingPong=0}dispose(){Rc(this._renderer,this._countersAttr),Rc(this._renderer,this._bounceCountsAttr),Rc(this._renderer,this._attrA),Rc(this._renderer,this._attrB),Rc(this._renderer,this._sortAttr),Rc(this._renderer,this._sortGlobalHistAttr),this._countersAttr=this._bounceCountsAttr=null,this._attrA=this._attrB=this._sortAttr=this._sortGlobalHistAttr=null,this.counters=null,this.activeIndices=null,this.activeIndicesRO=null,this.sortedIndices=null,this.sortedIndicesRO=null,this.sortGlobalHistogram=null,this.capacity=0}},kl={[r.RGBAFormat]:4,[r.RGBFormat]:3,[r.RGFormat]:2,[r.RedFormat]:1},Al={[r.FloatType]:4,[r.HalfFloatType]:2,[r.UnsignedByteType]:1,[r.ByteType]:1,[r.UnsignedShortType]:2,[r.ShortType]:2,[r.UnsignedIntType]:4,[r.IntType]:4};function jl(e){return(kl[e.format]??4)*(Al[e.type]??4)}function Ml(e){return e?.gpuByteLength??e?.array?.byteLength??0}function Nl(e){if(!e)return 0;if(e.isRenderTarget){let t=e.textures?.length?e.textures:[e.texture],n=e.width||0,r=e.height||0,i=e.depth||1,a=0;for(let e of t)e&&(a+=n*r*i*jl(e));return a}let t=e.image||{},n=t.width??e.width??0,r=t.height??e.height??0,i=t.depth??1;return n*r*i*jl(e)}var Pl=class{constructor(e=null){this._providers=[],this._renderer=e,this.current=0,this.peak=0,this.byCategory={}}setRenderer(e){this._renderer=e}register(e,t){this._providers.push({category:e,fn:t})}measure(){let e=new WeakSet,t={},n=0;for(let{category:r,fn:i}of this._providers){let a;try{a=i()}catch{a=null}if(!a)continue;let o=0;for(let t of Array.isArray(a)?a:[a])o+=this._resourceBytes(t,e);t[r]=(t[r]||0)+o,n+=o}return this.byCategory=t,this.current=n,n>this.peak&&(this.peak=n),{current:n,peak:this.peak,byCategory:t}}_resourceBytes(e,t){return e?typeof e.bytes==`number`&&!e.isTexture&&!e.isRenderTarget?e.bytes:e.gpuByteLength==null?e.array&&e.array.byteLength!=null?t.has(e.array)?0:(t.add(e.array),e.array.byteLength):e.isRenderTarget||e.isTexture?t.has(e)?0:(t.add(e),this._residentTextureBytes(e)):0:t.has(e)?0:(t.add(e),e.gpuByteLength):0}_isResident(e){let t=this._renderer?.backend;if(!t||typeof t.get!=`function`)return!0;if(typeof t.has==`function`&&!t.has(e))return!1;let n=t.get(e);return!!(n&&(n.texture||n.gpuTexture))}_residentTextureBytes(e){if(e.isRenderTarget){let t=e.textures?.length?e.textures:[e.texture],n=e.width||0,r=e.height||0,i=e.depth||1,a=0;for(let e of t)e&&this._isResident(e)&&(a+=n*r*i*jl(e));return a}return this._isResident(e)?Nl(e):0}resetPeak(){this.peak=this.current}getReport(){let e=e=>(e/1048576).toFixed(1),t=Object.entries(this.byCategory).map(([t,n])=>`${t}=${e(n)}`);return`VRAM current=${e(this.current)}MB peak=${e(this.peak)}MB [${t.join(` `)}]`}},Fl=It(`wavefront`),Il=class{constructor(e){this.renderer=e,this.kernels=new Map,this.timing=new Map,this.profiling=!1,this.profile=new Map,this._firstDispatches=[],this._firstDispatchFlush=null}_recordFirstDispatch(e,t){this._firstDispatches.push({name:e,ms:t}),clearTimeout(this._firstDispatchFlush),this._firstDispatchFlush=setTimeout(()=>this._flushFirstDispatches(),0)}_flushFirstDispatches(){let e=this._firstDispatches;if(this._firstDispatches=[],this._firstDispatchFlush=null,e.length===0)return;let t=e.reduce((e,t)=>e+t.ms,0),n=[...e].sort((e,t)=>t.ms-e.ms);Fl.info(Y.list([`${e.length} kernel${e.length===1?``:`s`} compiled in ${Y.ms(t)}`,`slowest ${n.slice(0,2).map(e=>`${e.name} ${Y.ms(e.ms)}`).join(`, `)}`])),e.forEach(e=>Fl.debug(`kernel '${e.name}' first dispatch (incl. compilation) ${Y.ms(e.ms)}`))}register(e,t){this.kernels.set(e,t),this.timing.set(e,{compiledOnce:!1,lastDispatchMs:0})}dispatch(e){let t=this.kernels.get(e);if(!t)throw Error(`KernelManager: Unknown kernel '${e}'`);let n=this.timing.get(e);if(n&&!n.compiledOnce){let r=performance.now();this.renderer.compute(t);let i=performance.now();n.compiledOnce=!0,n.lastDispatchMs=i-r,this._recordFirstDispatch(e,i-r)}else if(this.profiling){let n=performance.now();this.renderer.compute(t);let r=performance.now(),i=this.profile.get(e);i||(i={calls:0,totalMs:0},this.profile.set(e,i)),i.calls++,i.totalMs+=r-n}else this.renderer.compute(t)}setDispatchForCount(e,t){let n=this.kernels.get(e);n&&(n.dispatchSize=[Math.ceil(t/n.workgroupSize[0]),1,1])}setDispatchForGrid(e,t,n){let r=this.kernels.get(e);if(!r)return;let i=r.workgroupSize;r.dispatchSize=[Math.ceil(t/i[0]),Math.ceil(n/i[1]),1]}has(e){return this.kernels.has(e)}get(e){return this.kernels.get(e)}getTimingReport(){let e={};for(let[t,n]of this.timing)e[t]={...n};return e}enableProfiling(e){this.profiling=e,e&&this.profile.clear()}getProfileReport(){let e=[],t=0;for(let[n,{calls:r,totalMs:i}]of this.profile)t+=i,e.push({name:n,calls:r,totalMs:+i.toFixed(2),avgMs:+(i/r).toFixed(3)});return e.sort((e,t)=>t.totalMs-e.totalMs),e.push({name:`TOTAL`,calls:e.reduce((e,t)=>e+t.calls,0),totalMs:+t.toFixed(2),avgMs:null}),e}dispose(){clearTimeout(this._firstDispatchFlush),this._firstDispatchFlush=null,this._firstDispatches=[],this.kernels.clear(),this.timing.clear(),this.profile.clear()}},Ll=(0,n.Fn)(([e,t,r,i,a,o,s])=>{let c=(0,n.vec3)(0).toVar();return(0,n.If)(i.equal((0,n.int)(1)),()=>{let r=(0,n.mix)(a.x,a.y,e.x).toVar(),i=(0,n.mix)(o.y,o.x,e.y).toVar(),l=(0,n.cos)(i).toVar(),u=(0,n.vec3)(0).toVar(),d=(0,n.vec3)(0).toVar(),f=(0,n.vec3)(0).toVar();(0,n.If)(s.equal((0,n.int)(1)),()=>{let e=(0,n.vec3)(t[2].x,0,t[2].z).toVar();(0,n.If)((0,n.dot)(e,e).lessThan((0,n.float)(1e-8)),()=>{e.assign((0,n.vec3)(t[1].x,0,t[1].z))}),f.assign((0,n.normalize)(e)),d.assign((0,n.vec3)(0,1,0)),u.assign((0,n.cross)(d,f))}).Else(()=>{u.assign((0,n.normalize)((0,n.vec3)(t[0]))),d.assign((0,n.normalize)((0,n.vec3)(t[1]))),f.assign((0,n.normalize)((0,n.vec3)(t[2])))}),c.assign((0,n.normalize)(u.mul((0,n.sin)(r).mul(l)).add(d.mul((0,n.sin)(i))).sub(f.mul((0,n.cos)(r).mul(l)))))}).Else(()=>{let i=(0,n.vec3)(e.x.mul(2).sub(1),(0,n.float)(1).sub(e.y.mul(2)),1),a=r.mul((0,n.vec4)(i,1));c.assign((0,n.normalize)((0,n.mat3)(t[0].xyz,t[1].xyz,t[2].xyz).mul(a.xyz.div(a.w))))}),c}),Rl=(0,n.Fn)(([e,t,r,i,a,o,s,c,l,u,d,f,p,m,h])=>{let g=(0,n.vec3)(r[3]).toVar(),_=Ll(e,r,i,a,o,s,c).toVar(),v=g.toVar(),y=_.toVar();return(0,n.If)(l.and(u.greaterThan(0)).and(d.lessThan(64)).and(f.greaterThan(.001)),()=>{let e=u.div(d).mul(.001).mul(p).mul(m),i=ne(t),o=i.x.mul(h.max(.01)),s=i.y,c=(0,n.vec3)(0).toVar();(0,n.If)(a.equal((0,n.int)(1)),()=>{c.assign(ur({N:_}).mul((0,n.vec3)(o,s,0)))}).Else(()=>{let e=(0,n.normalize)((0,n.vec3)(r[0])),t=(0,n.normalize)((0,n.vec3)(r[1]));c.assign(e.mul(o).add(t.mul(s)))}),v.assign(g.add(c.mul(e))),y.assign((0,n.normalize)(g.add(_.mul(f)).sub(v)))}),Mn({origin:v,direction:y})});function zl(e){let{rayBufferRW:t,rngBufferRW:r,gBufferRW:i,resolution:a,frame:o,cameraWorldMatrix:s,cameraProjectionMatrixInverse:c,cameraProjection:l,panoLonRange:u,panoLatRange:d,panoLevelHorizon:f,enableDOF:p,focalLength:m,aperture:h,focusDistance:g,sceneScale:_,apertureScale:v,anamorphicRatio:y,renderWidth:b,chunkRowBase:x,chunkRows:S,transmissiveBounces:C,transparentBackground:w,auxGBufferEnabled:T,listDriven:E=!1,activeIndicesRO:D=null,counters:O=null}=e,k=T.greaterThan((0,n.uint)(0)),A=(e,b,x)=>{let S=(0,n.vec2)((0,n.float)(e).add(.5),(0,n.float)(b).add(.5)),w=R({state:he({pixelCoord:S,rayIndex:(0,n.int)(0),frame:o}).toVar()}).toVar(),T=me(S,(0,n.int)(1),(0,n.int)(1),w,a,o).toVar().sub(.5),E=(0,n.vec2)(S.x.add(T.x),S.y.sub(T.y)).div(a),D=Mn.wrap(Rl(E,w,s,c,l,u,d,f,p,m,h,g,_,v,y));tl(t,x,D.origin,(0,n.int)(0),(0,n.int)(0)),nl(t,x,D.direction,(0,n.uint)(Dl.ACTIVE)),rl(t,x,(0,n.vec4)(1,1,1,0).xyz,(0,n.float)(0)),il(t,x,(0,n.vec4)((0,n.vec3)(0),(0,n.float)(1))),(0,n.If)(k,()=>{qc(i,x,(0,n.vec3)(0,0,1),(0,n.float)(1),(0,n.vec3)(0),(0,n.float)(0)),yl(t,x,(0,n.vec3)(1))}),pl(t,x,(0,n.uint)(0),(0,n.uint)(C),(0,n.float)(1),(0,n.float)(1),(0,n.float)(1)),r.element(x).assign(w)};return(0,n.Fn)(()=>{if(E){let e=n.instanceIndex;(0,n.If)(e.lessThan((0,n.atomicLoad)(O.element((0,n.uint)($.ENTERING_COUNT)))),()=>{let t=(0,n.int)(D.element(e)),r=t.add(x.mul(b));A(r.mod(b),r.div(b),(0,n.uint)(t))})}else{let e=(0,n.int)(n.workgroupId.x).mul(16).add((0,n.int)(n.localId.x)),t=(0,n.int)(n.workgroupId.y).mul(16).add((0,n.int)(n.localId.y));(0,n.If)(e.lessThan(b).and(t.lessThan(S)),()=>{A(e,t.add(x),(0,n.uint)(t.mul(b).add(e)))})}})}var Bl=32,Vl=4096,Hl=4,Ul=1e8,Wl=()=>(0,n.array)(`int`,Bl).toVar(),Gl=e=>{let t=(0,n.mix)((0,n.vec3)(1),(0,n.sign)(e),(0,n.notEqual)(e,(0,n.vec3)(0)));return(0,n.mix)((0,n.vec3)(1).div(e),(0,n.vec3)(Ul).mul(t),(0,n.lessThan)((0,n.abs)(e),(0,n.vec3)(1e-8)))},Kl=(e,t)=>(0,n.vec3)(e[0].xyz.dot(t).add(e[0].w),e[1].xyz.dot(t).add(e[1].w),e[2].xyz.dot(t).add(e[2].w)),ql=(e,t)=>(0,n.vec3)(e[0].xyz.dot(t),e[1].xyz.dot(t),e[2].xyz.dot(t)),Jl=(0,n.wgslFn)(`
|
|
522
|
+
`),za=It(`shader`),Ba=class{constructor(){this.prevColorTexNode=null,this.prevAlbedoTexNode=null,this.prevNormalDepthTexNode=null,this._sceneTextureNodes=null}updateSceneTextures(e){let t=this._sceneTextureNodes,n=e.environment;n.environmentTexture&&t.envTex&&(t.envTex.value=n.environmentTexture),e.goboMaps&&t.goboMapsTex&&(t.goboMapsTex.value=e.goboMaps),e.iesProfiles&&t.iesProfilesTex&&(t.iesProfilesTex.value=e.iesProfiles),za.debug(`scene textures updated in-place`)}updateGoboMaps(e){let t=this._sceneTextureNodes;!t||!t.goboMapsTex||e&&(t.goboMapsTex.value=e)}updateIESProfiles(e){let t=this._sceneTextureNodes;!t||!t.iesProfilesTex||e&&(t.iesProfilesTex.value=e)}getSceneTextureNodes(){return this._sceneTextureNodes}createSceneTextureNodes(e,t){let i=e.triangleStorageNode,a=e.bvhStorageNode,o=e.materialData.materialStorageNode,s=e.lightStorageNode;wr(e.uniforms.get(`enableAlphaShadows`));let c=(0,n.texture)(e.environment.environmentTexture),l=t.getReadTextures();this.prevColorTexNode=(0,n.texture)(l.color),this.prevAlbedoTexNode=(0,n.texture)(l.albedo),this.prevNormalDepthTexNode=(0,n.texture)(l.normalDepth);let u=()=>{let e=new r.DataArrayTexture(new Uint8Array([255,255,255,255]),1,1,1);return e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e.generateMipmaps=!1,e.needsUpdate=!0,(0,n.texture)(e)},d=e.goboMaps?(0,n.texture)(e.goboMaps):u();ka(d);let f=e.iesProfiles?(0,n.texture)(e.iesProfiles):u();Na(f);let p={triStorage:i,bvhStorage:a,matStorage:o,lightBufferStorage:s,envTex:c,goboMapsTex:d,iesProfilesTex:f};return this._sceneTextureNodes=p,p}dispose(){this.prevColorTexNode=null,this.prevAlbedoTexNode=null,this.prevNormalDepthTexNode=null,this._sceneTextureNodes=null}},Va=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,t,n){if(typeof e==`number`){let r=t[n[e]],i=new Ha;return i.minX=r.minX,i.minY=r.minY,i.minZ=r.minZ,i.maxX=r.maxX,i.maxY=r.maxY,i.maxZ=r.maxZ,i.triangleOffset=r.triangleOffset,i.triangleCount=r.triangleCount,i}let r=this.buildSubtree(e[0],t,n),i=this.buildSubtree(e[1],t,n),a=new Ha;return a.leftChild=r,a.rightChild=i,a.minX=Math.min(r.minX,i.minX),a.minY=Math.min(r.minY,i.minY),a.minZ=Math.min(r.minZ,i.minZ),a.maxX=Math.max(r.maxX,i.maxX),a.maxY=Math.max(r.maxY,i.maxY),a.maxZ=Math.max(r.maxZ,i.maxZ),a}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},Ha=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},Ua=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}},Wa=It(`bvh`),Ga=1073741824,Ka=1073741826,qa=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),Ja=1073741824;function Ya(e,t){if(e>=Ja)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${Ja}`);return e}var Xa=null;function Za(e){Xa=e}var Qa={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},$a=Qa.FLOATS_PER_TRIANGLE,eo=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),to=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},no=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=eo(this.triangles),n=Qa.POSITION_A_OFFSET,r=Qa.POSITION_B_OFFSET,i=Qa.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*$a,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){return this.totalTriangles=e.byteLength/($a*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),this.useWorker&&Xa&&typeof Worker<`u`?new Promise((r,i)=>{let a=a=>{let o=this.totalTriangles,s=typeof SharedArrayBuffer<`u`;Wa.debug(`SharedArrayBuffer ${s?`enabled`:`unavailable (using transfer fallback)`}`);let c=s?new SharedArrayBuffer(o*$a*4):null;a.onmessage=e=>{let{bvhData:t,triangles:o,originalToBvh:s,error:l,progress:u,treeletStats:d}=e.data;if(l){a.terminate(),i(Error(l));return}if(u!==void 0&&n){n(u);return}d&&(this.splitStats=d),a.terminate(),r({bvhData:t,bvhRoot:!0,reorderedTriangles:c?new Float32Array(c):o,originalToBvh:s||null})},a.onerror=e=>{a.terminate(),i(e)};let l=e.buffer,u={triangleData:l,triangleByteOffset:e.byteOffset,triangleByteLength:e.byteLength,triangleCount:o,depth:t,reportProgress:!!n,sharedReorderBuffer:c,treeletOptimization:{enabled:this.enableTreeletOptimization,size:this.treeletSize,passes:this.treeletOptimizationPasses,minImprovement:this.treeletMinImprovement},reinsertionOptimization:{enabled:this.enableReinsertionOptimization,batchSizeRatio:this.reinsertionBatchSizeRatio,maxIterations:this.reinsertionMaxIterations}};a.postMessage(u,[l])};try{a(Xa())}catch(i){Wa.warn(`worker creation failed, falling back to synchronous build:`,i),r(this._buildSyncAndFlatten(e,t,n))}}):new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(e,t=30,n=null,r=null){let i=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=e,this.totalTriangles=e.byteLength/($a*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let a=this.totalTriangles,o=performance.now();this.centroids=new Float32Array(a*3),this.bMin=new Float32Array(a*3),this.bMax=new Float32Array(a*3),this.indices=new Uint32Array(a),this.mortonCodes=new Uint32Array(a),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-o,this.sortTrianglesByMortonCode();let s=performance.now(),c=this.buildNodeRecursive(0,a,t,n);if(this.splitStats.sahBuildTime=performance.now()-s,this.enableTreeletOptimization&&this.totalTriangles>1e3){let e=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,t=new Va(this.traversalCost,this.intersectionCost);t.setTreeletSize(e),t.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let i=n?t=>{n(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{t.optimizeBVH(c,i)}catch(t){Wa.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=t.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let i=performance.now()-r;this.splitStats.treeletOptimizationTime=i;let a=t.getStatistics();this.splitStats.treeletsProcessed=a.treeletsProcessed,this.splitStats.treeletsImproved=a.treeletsImproved,this.splitStats.averageSAHImprovement=a.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new Ua(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=n?e=>{n(e)}:null;try{e.optimizeBVH(c,t)}catch(e){Wa.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let l=performance.now();this.applySAOrdering(c),this.splitStats.saOrderTime=performance.now()-l;let u=performance.now(),d=this.triangles,f=r||new d.constructor(a*$a);for(let e=0;e<a;e++){let t=this.indices[e]*$a,n=e*$a;f.set(d.subarray(t,t+$a),n)}this.reorderedTriangleData=f;let p=new Uint32Array(a);for(let e=0;e<a;e++)p[this.indices[e]]=e;this.originalToBvhMap=p,this.splitStats.reorderTime=performance.now()-u,this.splitStats.totalBuildTime=performance.now()-i;let m=this.splitStats.totalBuildTime,h=this.splitStats;return Wa.debug(`${Y.n(a)} tris → ${Y.n(this.totalNodes)} nodes in ${Y.ms(m)} | SAH ${h.sahSplits} objMed ${h.objectMedianSplits} spatMed ${h.spatialMedianSplits} failed ${h.failedSplits}`+(h.treeletsProcessed?` | treelets ${h.treeletsImproved}/${h.treeletsProcessed} improved`:``)+(h.reinsertionsApplied?` | reinsertions ${h.reinsertionsApplied}`:``)),n&&n(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,c}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new to;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new to;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}Ya(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=qa(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=Ga}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}Ya(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=qa(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=Ka,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=Ga}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;Ya(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=qa(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<Ga&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}},ro={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11},io=ro.FLOATS_PER_TRIANGLE,ao=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),oo=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),so=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):oo(e)}},co=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,lo=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,uo=(e,t)=>e.chunked?e.chunked.baseOf(t):t*mo,fo=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):ao(e),u:t?e:oo(e)}};function po(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}var mo=16,ho=1073741824,go=1073741825,_o=1e-12;function vo(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=_o*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,ee=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>ee&&(ee=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=ee}var yo=class{constructor(){this._bounds=null,this._boundsNodeCount=0}updateTrianglePositions(e,t,n){let r=n.length,i=fo(e);for(let e=0;e<r;e++){let r=n[e],a=i.chunked?i.f.chunkFor(e):i.f,o=i.chunked?i.u.chunkFor(e):i.u,s=i.chunked?i.chunked.baseOf(e):e*io,c=r*9,l=t[c],u=t[c+1],d=t[c+2],f=t[c+3],p=t[c+4],m=t[c+5],h=t[c+6],g=t[c+7],_=t[c+8];a[s+ro.POSITION_A_OFFSET]=l,a[s+ro.POSITION_A_OFFSET+1]=u,a[s+ro.POSITION_A_OFFSET+2]=d,a[s+ro.POSITION_B_OFFSET]=f,a[s+ro.POSITION_B_OFFSET+1]=p,a[s+ro.POSITION_B_OFFSET+2]=m,a[s+ro.POSITION_C_OFFSET]=h,a[s+ro.POSITION_C_OFFSET+1]=g,a[s+ro.POSITION_C_OFFSET+2]=_;let v=f-l,y=p-u,b=m-d,x=h-l,S=g-u,C=_-d,w=po(y*C-b*S,b*x-v*C,v*S-y*x);o[s+ro.NORMAL_A_PACKED_OFFSET]=w,o[s+ro.NORMAL_B_PACKED_OFFSET]=w,o[s+ro.NORMAL_C_PACKED_OFFSET]=w}}refitRange(e,t,n,r){let i=fo(t);r>this._boundsNodeCount&&(this._bounds=new Float32Array(r*6),this._boundsNodeCount=r);let a=this._bounds,o=n+r,s=so(e);for(let e=o-1;e>=n;e--){let t=co(s,e),r=lo(s,e),o=uo(s,e),c=(e-n)*6;if(r[o+3]===ho){let e=r[o],t=r[o+1],n=1/0,s=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0;for(let r=0;r<t;r++){let t=e+r,a=i.chunked?i.f.chunkFor(t):i.f,o=i.chunked?i.chunked.baseOf(t):t*io,c=a[o+ro.POSITION_A_OFFSET],p=a[o+ro.POSITION_A_OFFSET+1],m=a[o+ro.POSITION_A_OFFSET+2],h=a[o+ro.POSITION_B_OFFSET],g=a[o+ro.POSITION_B_OFFSET+1],_=a[o+ro.POSITION_B_OFFSET+2],v=a[o+ro.POSITION_C_OFFSET],y=a[o+ro.POSITION_C_OFFSET+1],b=a[o+ro.POSITION_C_OFFSET+2];n=Math.min(n,c,h,v),s=Math.min(s,p,g,y),l=Math.min(l,m,_,b),u=Math.max(u,c,h,v),d=Math.max(d,p,g,y),f=Math.max(f,m,_,b)}a[c]=n,a[c+1]=s,a[c+2]=l,a[c+3]=u,a[c+4]=d,a[c+5]=f}else{let e=r[o+3],i=r[o+7],s=(e-n)*6,l=(i-n)*6,u=a[s],d=a[s+1],f=a[s+2],p=a[s+3],m=a[s+4],h=a[s+5],g=a[l],_=a[l+1],v=a[l+2],y=a[l+3],b=a[l+4],x=a[l+5];t[o]=u,t[o+1]=d,t[o+2]=f,t[o+4]=p,t[o+5]=m,t[o+6]=h,t[o+8]=g,t[o+9]=_,t[o+10]=v,t[o+12]=y,t[o+13]=b,t[o+14]=x,a[c]=Math.min(u,g),a[c+1]=Math.min(d,_),a[c+2]=Math.min(f,v),a[c+3]=Math.max(p,y),a[c+4]=Math.max(m,b),a[c+5]=Math.max(h,x)}}}refit(e,t,n){let r=fo(t);n!==this._boundsNodeCount&&(this._bounds=new Float32Array(n*6),this._boundsNodeCount=n);let i=this._bounds,a=so(e);for(let e=n-1;e>=0;e--){let t=co(a,e),n=lo(a,e),o=uo(a,e),s=e*6,c=n[o+3];if(c===ho){let e=n[o],t=n[o+1],a=1/0,c=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0;for(let n=0;n<t;n++){let t=e+n,i=r.chunked?r.f.chunkFor(t):r.f,o=r.chunked?r.chunked.baseOf(t):t*io,s=i[o+ro.POSITION_A_OFFSET],p=i[o+ro.POSITION_A_OFFSET+1],m=i[o+ro.POSITION_A_OFFSET+2],h=i[o+ro.POSITION_B_OFFSET],g=i[o+ro.POSITION_B_OFFSET+1],_=i[o+ro.POSITION_B_OFFSET+2],v=i[o+ro.POSITION_C_OFFSET],y=i[o+ro.POSITION_C_OFFSET+1],b=i[o+ro.POSITION_C_OFFSET+2];a=Math.min(a,s,h,v),c=Math.min(c,p,g,y),l=Math.min(l,m,_,b),u=Math.max(u,s,h,v),d=Math.max(d,p,g,y),f=Math.max(f,m,_,b)}i[s]=a,i[s+1]=c,i[s+2]=l,i[s+3]=u,i[s+4]=d,i[s+5]=f}else if(c===go)vo(t,o,i,n[o]*6,i,s);else{let e=n[o+3],r=n[o+7],a=e*6,c=r*6,l=i[a],u=i[a+1],d=i[a+2],f=i[a+3],p=i[a+4],m=i[a+5],h=i[c],g=i[c+1],_=i[c+2],v=i[c+3],y=i[c+4],b=i[c+5];t[o]=l,t[o+1]=u,t[o+2]=d,t[o+4]=f,t[o+5]=p,t[o+6]=m,t[o+8]=h,t[o+9]=g,t[o+10]=_,t[o+12]=v,t[o+13]=y,t[o+14]=b,i[s]=Math.min(l,h),i[s+1]=Math.min(u,g),i[s+2]=Math.min(d,_),i[s+3]=Math.max(f,v),i[s+4]=Math.max(p,y),i[s+5]=Math.max(m,b)}}}},bo="var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}function b(e){e&&e in r&&(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e])}const x=y(`bvh`),S=1073741824,C=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),w=1073741824;function T(e,t){if(e>=w)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${w}`);return e}const E={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},D=E.FLOATS_PER_TRIANGLE,O=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var k=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},A=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=O(this.triangles),n=E.POSITION_A_OFFSET,r=E.POSITION_B_OFFSET,i=E.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*D,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(D*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),!(this.useWorker&&null))return new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(D*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){x.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){x.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*D);for(let e=0;e<s;e++){let t=this.indices[e]*D,n=e*D;m.set(p.subarray(t,t+D),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return x.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new k;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new k;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}T(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=C(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=S}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}T(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=C(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=S}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;T(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=C(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<S&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const j=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?M(t):n===`assemble`?N(t):P(t)};function M(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u,treeletOptimization:d}=e;try{let e=new A;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let p=performance.now(),m=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-m,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let h=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,f);e.splitStats.sahBuildTime=performance.now()-h,e.applySAOrdering(g);let v=performance.now(),{flatData:y,frontierMap:b,nodeCount:x}=e.flattenBVHWithFrontier(g),S=performance.now()-v,C=performance.now()-p;j.debug(`phase 1 ${_.ms(C)} (init ${_.ms(e.splitStats.initTime)} · morton ${_.ms(e.splitStats.mortonSortTime)} · SAH ${_.ms(e.splitStats.sahBuildTime)} · flatten ${_.ms(S)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:y,topNodeCount:x,frontierTasks:e.frontierTasks,frontierMap:b,splitStats:e.splitStats},[y.buffer])}catch(e){j.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function N(e){let{topFlatData:t,topNodeCount:n,frontierMap:r,subtreeResults:i,sharedTriangleData:a,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c}=e;try{let e=performance.now(),l=new A().assembleParallelBVH(t,n,r,i),u=new Uint32Array(o),d=new Uint32Array(a),f=new Uint32Array(s);for(let e=0;e<c;e++){let t=u[e]*20,n=e*20;f.set(d.subarray(t,t+20),n)}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[u[e]]=e;let m=performance.now()-e;j.debug(`phase 3 assemble + reorder ${_.ms(m)} (${_.mb(l.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:l,originalToBvh:p,triangleCount:c},[l.buffer,p.buffer])}catch(e){j.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function P(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,treeletOptimization:o,reinsertionOptimization:s,sharedReorderBuffer:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f}=e,p=new A;l!==void 0&&(p.maxLeafSize=l),u!==void 0&&(p.numBins=u),d!==void 0&&(p.maxBins=d),f!==void 0&&(p.minBins=f);try{o&&p.setTreeletConfig(o),s&&p.setReinsertionConfig(s);let e=a?e=>{self.postMessage({progress:e})}:null,l=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),u=c?new Uint32Array(c):null,d=p.buildSync(l,i,e,u),f=performance.now(),m=p.flattenBVH(d),h=performance.now()-f;j.debug(`flatten ${_.ms(h)} (${_.mb(m.byteLength)})`);let g=p.originalToBvhMap||null;if(c){let e=[m.buffer];g&&e.push(g.buffer),self.postMessage({bvhData:m,originalToBvh:g,triangleCount:l.length/20,treeletStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/80,n=[m.buffer,e.buffer];g&&n.push(g.buffer),self.postMessage({bvhData:m,triangles:e,originalToBvh:g,triangleCount:t,treeletStats:p.splitStats},n)}}catch(e){j.error(`build failed:`,e),self.postMessage({error:e.message})}}",xo=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,bo],{type:`text/javascript;charset=utf-8`});function So(e){let t;try{if(t=xo&&(self.URL||self.webkitURL).createObjectURL(xo),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(bo),{type:`module`,name:e?.name})}}var Co="var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}const b=y(`bvh`),x=1073741824,S=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),C=1073741824;function w(e,t){if(e>=C)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${C}`);return e}const T={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},E=T.FLOATS_PER_TRIANGLE,D=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var O=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},k=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.numBins=32,this.minBins=8,this.maxBins=64,this.totalNodes=0,this.processedTriangles=0,this.totalTriangles=0,this.lastProgressUpdate=0,this.progressUpdateInterval=100,this.traversalCost=1,this.intersectionCost=2.5,this.useMortonCodes=!0,this.mortonBits=10,this.mortonClusterThreshold=128,this.enableObjectMedianFallback=!0,this.enableSpatialMedianFallback=!0,this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=D(this.triangles),n=T.POSITION_A_OFFSET,r=T.POSITION_B_OFFSET,i=T.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*E,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(E*4),this.processedTriangles=0,this.lastProgressUpdate=performance.now(),!(this.useWorker&&null))return new Promise(r=>{r(this._buildSyncAndFlatten(e,t,n))})}_buildSyncAndFlatten(e,t,n){let r=this.buildSync(e,t,n);return{bvhData:this.flattenBVH(r),bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(E*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){b.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){b.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*E);for(let e=0;e<s;e++){let t=this.indices[e]*E,n=e*E;m.set(p.subarray(t,t+E),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return b.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new O;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new O;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}w(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=S(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=x}return r}flattenBVHWithFrontier(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}w(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=S(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=x}return{flatData:r,frontierMap:i,nodeCount:t.length}}assembleParallelBVH(e,t,n,r){let i=[...r].sort((e,t)=>e.taskId-t.taskId),a=t;for(let e=0;e<i.length;e++)a+=i[e].nodeCount;w(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=S(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<x&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:r,sharedTriangleData:i,sharedCentroids:a,sharedBMin:o,sharedBMax:s,sharedIndices:c,triangleCount:l,maxLeafSize:u,numBins:d,maxBins:f,minBins:p,treeletConfig:m,reinsertionConfig:h,reportProgress:g}=t.data;for(let t=0;t<r.length;t++){let _=r[t];try{let t=new k;t.maxLeafSize=u,t.numBins=d,t.maxBins=f,t.minBins=p,t.triangles=new Float32Array(i),t.centroids=new Float32Array(a),t.bMin=new Float32Array(o),t.bMax=new Float32Array(s),t.indices=new Uint32Array(c),t.totalTriangles=l,t.totalNodes=0,t.processedTriangles=0,t.lastProgressUpdate=performance.now(),t.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let r=g?e=>{self.postMessage({type:`progress`,taskId:_.taskId,progress:e})}:null,v=performance.now(),y=t.buildNodeRecursive(_.start,_.end,_.depth,r,_.preMinX,_.preMinY,_.preMinZ,_.preMaxX,_.preMaxY,_.preMaxZ);if(m&&m.enabled&&_.end-_.start>1e3){let n=_.end-_.start>5e4,r=n?3:m.size||5,i=n?10:20,a=new e(t.traversalCost,t.intersectionCost);a.setTreeletSize(r),a.setMinImprovement(m.minImprovement||.02),a.setMaxTreelets(i);let o=m.passes||1;for(let e=0;e<o;e++)try{a.optimizeBVH(y,null)}catch(t){console.error(`[BVHSubtreeWorker] Treelet pass ${e+1} error:`,t);break}}if(h&&h.enabled&&_.end-_.start>1e3){let e=new n(t.traversalCost,t.intersectionCost);h.batchSizeRatio&&e.setBatchSizeRatio(h.batchSizeRatio),h.maxIterations&&e.setMaxIterations(h.maxIterations);try{e.optimizeBVH(y,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(y);let b=t.flattenBVH(y),x=b.length/16,S=performance.now()-v;console.log(`[BVHSubtreeWorker] Task ${_.taskId}: ${(_.end-_.start).toLocaleString()} triangles, ${x} nodes, ${Math.round(S)}ms`),self.postMessage({type:`subtreeResult`,taskId:_.taskId,flatData:b,nodeCount:x},[b.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${_.taskId} error:`,e),self.postMessage({type:`error`,taskId:_.taskId,error:e.message})}}};",wo=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,Co],{type:`text/javascript;charset=utf-8`});function To(e){let t;try{if(t=wo&&(self.URL||self.webkitURL).createObjectURL(wo),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(Co),{type:`module`,name:e?.name})}}Za(()=>new So);var Eo=It(`bvh`),Do=20,Oo=5e4,ko=8;function Ao(e,t,n,r){let i=e.byteLength/(Do*4),a=Math.min(navigator.hardwareConcurrency||4,ko),o=Math.ceil(Math.log2(a*2.5+1));return Eo.debug(`parallel build ${Y.n(i)} triangles · ${a} workers · parallelDepth ${o}`),new Promise((s,c)=>{(async()=>{let c=new SharedArrayBuffer(e.byteLength);new Uint32Array(c).set(e),e=null;let l=new SharedArrayBuffer(i*3*4),u=new SharedArrayBuffer(i*3*4),d=new SharedArrayBuffer(i*3*4),f=new SharedArrayBuffer(i*4),p=new SharedArrayBuffer(i*4),m=new SharedArrayBuffer(i*Do*4),h=new So,g=null,_=[h],v={id:null},y=!1,b=()=>{v.id&&=(clearTimeout(v.id),null);for(let e of _)try{e.terminate()}catch{}},x=e=>{if(y)return;y=!0,Eo.warn(`parallel build failed (${e}), falling back to single worker`),b();let i=new ArrayBuffer(c.byteLength);new Uint32Array(i).set(new Uint32Array(c)),s(Mo(new Uint32Array(i),t,n,r))};h.onerror=e=>{x(`coordinator error: ${e.message}`)},h.onmessage=e=>{let t=e.data;if(t.error||t.type===`error`){x(t.error);return}if(t.type===`progress`&&n){n(Math.floor(t.progress*.3));return}if(t.type===`phase1Result`){g=t.splitStats,jo(t,a,c,l,u,d,f,m,i,n,h,_,b,x,s,v,r).catch(e=>x(e.message));return}if(t.type===`assembleResult`){y=!0,b();let e=new Uint32Array(m);s({bvhData:t.bvhData,bvhRoot:!0,reorderedTriangles:e,originalToBvh:t.originalToBvh||null,splitStats:g||{}});return}},n&&n(0),h.postMessage({type:`buildPhase1`,sharedTriangleData:c,sharedCentroids:l,sharedBMin:u,sharedBMax:d,sharedIndices:f,sharedMortonCodes:p,triangleCount:i,depth:t,parallelDepth:o,reportProgress:!!n,treeletOptimization:r.treeletOptimization})})().catch(e=>{Eo.warn(`parallel build setup failed:`,e),c(e)})})}async function jo(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g){let{topFlatData:_,topNodeCount:v,frontierTasks:y,frontierMap:b}=e;if(!y||y.length===0){Eo.debug(`no frontier tasks, assembling with top-level tree only`),u.postMessage({type:`assemble`,topFlatData:_,topNodeCount:v,frontierMap:[],subtreeResults:[],sharedTriangleData:n,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c},[_.buffer]);return}Eo.debug(`phase 2 distributing ${y.length} tasks across ${t} workers`);let x=[...y].sort((e,t)=>t.end-t.start-(e.end-e.start)),S=Array.from({length:Math.min(t,x.length)},()=>[]),C=Array(S.length).fill(0);for(let e of x){let t=0;for(let e=1;e<C.length;e++)C[e]<C[t]&&(t=e);S[t].push(e),C[t]+=e.end-e.start}let w=[],T=0,E=y.length,D=y.reduce((e,t)=>e+(t.end-t.start),0),O=0;h.id=setTimeout(()=>{p(`Phase 2 timeout (30s)`)},3e4);let k=()=>{clearTimeout(h.id),h.id=null,l&&l(85);let t=[];e.topFlatData&&e.topFlatData.buffer&&t.push(e.topFlatData.buffer);for(let e of w)e.flatData&&e.flatData.buffer&&t.push(e.flatData.buffer);u.postMessage({type:`assemble`,topFlatData:e.topFlatData,topNodeCount:v,frontierMap:b,subtreeResults:w,sharedTriangleData:n,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c},t)},A=S.length;for(let e=0;e<A;e++){let t=S[e];if(t.length===0)continue;let s=new To;d.push(s),s.onerror=e=>{p(`subtree worker error: ${e.message}`)},s.onmessage=e=>{let t=e.data;if(t.type===`error`){p(`subtree task ${t.taskId} error: ${t.error}`);return}if(t.type===`progress`&&l){let e=30+Math.floor(O/D*55);l(Math.min(e,85));return}if(t.type===`subtreeResult`){w.push({taskId:t.taskId,flatData:t.flatData,nodeCount:t.nodeCount});let e=y.find(e=>e.taskId===t.taskId);if(e&&(O+=e.end-e.start),T++,l){let e=30+Math.floor(O/D*55);l(Math.min(e,85))}if(T===E){for(let e of d)if(e!==u)try{e.terminate()}catch{}k()}}},s.postMessage({tasks:t,sharedTriangleData:n,sharedCentroids:r,sharedBMin:i,sharedBMax:a,sharedIndices:o,triangleCount:c,maxLeafSize:g.maxLeafSize,numBins:g.numBins,maxBins:g.maxBins,minBins:g.minBins,treeletConfig:g.treeletOptimization,reinsertionConfig:g.reinsertionOptimization,reportProgress:!!l})}}function Mo(e,t,n,r){return new Promise((i,a)=>{(async()=>{let o=new So,s=e.byteLength/(Do*4),c=typeof SharedArrayBuffer<`u`?new SharedArrayBuffer(s*Do*4):null;o.onmessage=e=>{let{bvhData:t,triangles:r,originalToBvh:s,error:l,progress:u,treeletStats:d}=e.data;if(l){o.terminate(),a(Error(l));return}if(u!==void 0&&n){n(u);return}o.terminate(),i({bvhData:t,bvhRoot:!0,reorderedTriangles:c?new Uint32Array(c):r,originalToBvh:s||null,splitStats:d||{}})},o.onerror=e=>{o.terminate(),a(e)};let l=e.buffer;o.postMessage({triangleData:l,triangleByteOffset:e.byteOffset,triangleByteLength:e.byteLength,triangleCount:s,depth:t,reportProgress:!!n,sharedReorderBuffer:c,treeletOptimization:r.treeletOptimization,reinsertionOptimization:r.reinsertionOptimization},[l])})().catch(e=>{Eo.warn(`single worker fallback failed:`,e),a(e)})})}function No(e){return typeof Worker<`u`&&typeof SharedArrayBuffer<`u`&&e>=Oo}var Po=Float64Array.from([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function Fo(e,t){return e[t]*(e[t+5]*e[t+10]-e[t+6]*e[t+9])-e[t+4]*(e[t+1]*e[t+10]-e[t+2]*e[t+9])+e[t+8]*(e[t+1]*e[t+6]-e[t+2]*e[t+5])}function Io(e,t,n){let r=Fo(e,t);if(!Number.isFinite(r)||Math.abs(r)<1e-20)return n.set(Po),n;let i=1/r;return n[0]=(e[t+5]*e[t+10]-e[t+6]*e[t+9])*i,n[1]=(e[t+2]*e[t+9]-e[t+1]*e[t+10])*i,n[2]=(e[t+1]*e[t+6]-e[t+2]*e[t+5])*i,n[3]=0,n[4]=(e[t+6]*e[t+8]-e[t+4]*e[t+10])*i,n[5]=(e[t]*e[t+10]-e[t+2]*e[t+8])*i,n[6]=(e[t+2]*e[t+4]-e[t]*e[t+6])*i,n[7]=0,n[8]=(e[t+4]*e[t+9]-e[t+5]*e[t+8])*i,n[9]=(e[t+1]*e[t+8]-e[t]*e[t+9])*i,n[10]=(e[t]*e[t+5]-e[t+1]*e[t+4])*i,n[11]=0,n[12]=-(n[0]*e[t+12]+n[4]*e[t+13]+n[8]*e[t+14]),n[13]=-(n[1]*e[t+12]+n[5]*e[t+13]+n[9]*e[t+14]),n[14]=-(n[2]*e[t+12]+n[6]*e[t+13]+n[10]*e[t+14]),n[15]=1,n}function Lo(e,t,n,r){for(let i=0;i<4;i++){let a=n+i*4,o=t[a],s=t[a+1],c=t[a+2],l=t[a+3];for(let t=0;t<4;t++)r[i*4+t]=e[t]*o+e[4+t]*s+e[8+t]*c+e[12+t]*l}return r}function Ro(e){for(let t=0;t<16;t++)if(e[t]!==Po[t])return!1;return!0}function zo(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=0;i<8;i++){let a=e[t+(i&1?3:0)],f=e[t+(i&2?4:1)],p=e[t+(i&4?5:2)],m=n[r]*a+n[r+4]*f+n[r+8]*p+n[r+12],h=n[r+1]*a+n[r+5]*f+n[r+9]*p+n[r+13],g=n[r+2]*a+n[r+6]*f+n[r+10]*p+n[r+14];m<o&&(o=m),m>l&&(l=m),h<s&&(s=h),h>u&&(u=h),g<c&&(c=g),g>d&&(d=g)}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}function Bo(e,t){for(let n=0;n<16;n++)if(e[t+n]!==Po[n])return!1;return!0}var Vo=class{constructor(){this.count=0,this.templateCount=0,this.totalBLASNodes=0,this.tlasNodeCount=0,this.allocate(0)}allocate(e,t=e,n=null,r=null){this.count=e,this.templateCount=t,this.isSet=new Uint8Array(e),this.sourceMesh=r&&r.length>=e?r:new Int32Array(e),this.tlasLeafIndex=new Int32Array(e).fill(-1),this.visible=new Uint8Array(e).fill(1),this.flipWinding=new Uint8Array(e),this.tplBakeInverse=null,n&&n.length>=e*16?(this.world=n,this.worldPooled=!0):(this.world=new Float32Array(e*16),this.worldPooled=!1),this.tplTriOffset=new Int32Array(t),this.tplTriCount=new Int32Array(t),this.tplExpandedStart=new Int32Array(t),this.tplNodeCount=new Int32Array(t),this.tplBlasOffset=new Int32Array(t),this.tplOwner=new Int32Array(t).fill(-1),this.tplObjectAABB=new Float32Array(t*6),this._placementRuns=null,this.originalToBvhMap=new Map,this.bvhToOriginal=new Map,this.blasData=new Map}_place(e,t,n,r){this.isSet[e]=1,this.sourceMesh[e]=t;let i=e*16;if(!n){this.world.set(Po,i),this.flipWinding[e]=0;return}if(n!==this.world)for(let e=0;e<16;e++)this.world[i+e]=n[r+e];this.flipWinding[e]=+(Fo(this.world,i)<0)}setEntry({meshIndex:e,blasNodeCount:t,triOffset:n,triCount:r,originalToBvhMap:i,bvhData:a,matrixWorld:o=null,matrixOffset:s=0,expandedStart:c=null,sourceMesh:l=null}){let u=l??e;this._place(e,u,o,s),this.tplTriOffset[u]=n,this.tplTriCount[u]=r,this.tplExpandedStart[u]=c??n,this.tplNodeCount[u]=t,this.tplOwner[u]=e,i&&this.originalToBvhMap.set(u,i),a&&this.blasData.set(u,a)}setAlias(e,t,n=null,r=null,i=null,a=0){if(!this.isSet[t])throw Error(`InstanceTable.setAlias: owner ${t} not built`);let o=i??e,s=this.sourceMesh[t];this._place(e,o,n,a),o!==s&&(this.tplTriOffset[o]=this.tplTriOffset[s],this.tplTriCount[o]=this.tplTriCount[s],this.tplNodeCount[o]=this.tplNodeCount[s],this.tplExpandedStart[o]=r??this.tplExpandedStart[s],this.tplOwner[o]=this.tplOwner[s])}get setCount(){let e=0;for(let t=0;t<this.count;t++)e+=this.isSet[t];return e}setPlacementMatrix(e,t,n=0){this._place(e,this.sourceMesh[e],t,n)}placementRunOf(e){if(!this._placementRuns){let e=this._placementRuns=new Map;for(let t=0;t<this.count;t++){let n=this.sourceMesh[t],r=e.get(n);r?r.count++:e.set(n,{start:t,count:1})}}return this._placementRuns.get(e)??null}isOwner(e){return this.tplOwner[this.sourceMesh[e]]===e}triOffsetOf(e){return this.tplTriOffset[this.sourceMesh[e]]}triCountOf(e){return this.tplTriCount[this.sourceMesh[e]]}expandedStartOf(e){return this.tplExpandedStart[this.sourceMesh[e]]}blasOffsetOf(e){return this.tplBlasOffset[this.sourceMesh[e]]}blasNodeCountOf(e){return this.tplNodeCount[this.sourceMesh[e]]}setBlasNodeCount(e,t){this.tplNodeCount[this.sourceMesh[e]]=t}setBvhToOriginal(e,t){this.bvhToOriginal.set(this.sourceMesh[e],t)}bvhToOriginalOf(e){let t=this.sourceMesh[e],n=this.bvhToOriginal.get(t);if(n)return n;let r=this.tplOwner[t];return(r>=0?this.bvhToOriginal.get(this.sourceMesh[r]):null)||null}matrixWorldOf(e){return this.world.subarray(e*16,e*16+16)}matrixInverseOf(e){return Io(this.world,e*16,new Float64Array(16))}writeWorldAABB(e,t,n){if(!this.isSet[e]){for(let e=0;e<6;e++)t[n+e]=0;return}zo(this.tplObjectAABB,this.sourceMesh[e]*6,this.world,e*16,t,n)}writeWorldAABBs(e){let t=this.tplObjectAABB,n=this.world,r=this.sourceMesh,i=this.isSet;for(let a=0;a<this.count;a++){let o=a*6;if(!i[a]){e[o]=0,e[o+1]=0,e[o+2]=0,e[o+3]=0,e[o+4]=0,e[o+5]=0;continue}zo(t,r[a]*6,n,a*16,e,o)}}entryAt(e){if(!this.isSet[e])return null;let t=this.sourceMesh[e],n=this.tplOwner[t];return{meshIndex:e,blasOffset:this.tplBlasOffset[t],blasNodeCount:this.tplNodeCount[t],triOffset:this.tplTriOffset[t],triCount:this.tplTriCount[t],expandedStart:this.tplExpandedStart[t],sourceMesh:t,sharedFrom:n===e?null:n,matrixWorld:this.matrixWorldOf(e),matrixInverse:this.matrixInverseOf(e),flipWinding:!!this.flipWinding[e],bvhToOriginal:this.bvhToOriginal.get(t)||null,visible:!!this.visible[e],tlasLeafIndex:this.tlasLeafIndex[e]}}setVisibility(e,t){this.isSet[e]&&(this.visible[e]=+!!t)}computeAABBs(e){for(let t=0;t<this.templateCount;t++){if(this.tplOwner[t]<0)continue;let n=this.blasData.get(t);n&&this._readRootAABB(n,t,e,this.tplObjectAABB,t*6)}for(let e=0;e<this.templateCount;e++){let t=this.tplOwner[e];if(t<0||this.blasData.has(e))continue;let n=this.sourceMesh[t];n!==e&&this.tplObjectAABB.copyWithin(e*6,n*6,n*6+6)}}recomputeAABB(e,t,n){let r=this.sourceMesh[e],i=this.tplBlasOffset[r],a=t.chunks?t.chunkFor(i).subarray(t.baseOf(i),t.baseOf(i)+16):t.subarray(i*16,i*16+16);this._readRootAABB(a,r,n,this.tplObjectAABB,r*6)}_readRootAABB(e,t,n,r,i){if(!e||rt(e)[3]===nt.TRIANGLE_LEAF){this._computeAABBFromTriangles(t,n,r,i);return}r[i]=Math.min(e[0],e[8]),r[i+1]=Math.min(e[1],e[9]),r[i+2]=Math.min(e[2],e[10]),r[i+3]=Math.max(e[4],e[12]),r[i+4]=Math.max(e[5],e[13]),r[i+5]=Math.max(e[6],e[14])}_computeAABBFromTriangles(e,t,n,r){let i=K.FLOATS_PER_TRIANGLE,a=t&&t.chunks?t.viewAs(Float32Array):null,o=a?null:t instanceof Float32Array?t:new Float32Array(t.buffer,t.byteOffset,t.length),s=1/0,c=1/0,l=1/0,u=-1/0,d=-1/0,f=-1/0,p=this.tplTriOffset[e],m=this.tplTriCount[e];for(let e=0;e<m;e++){let t=p+e,n=a?a.chunkFor(t):o,r=a?a.baseOf(t):t*i;for(let e=0;e<=8;e+=4){let t=n[r+e],i=n[r+e+1],a=n[r+e+2];t<s&&(s=t),i<c&&(c=i),a<l&&(l=a),t>u&&(u=t),i>d&&(d=i),a>f&&(f=a)}}n[r]=s,n[r+1]=c,n[r+2]=l,n[r+3]=u,n[r+4]=d,n[r+5]=f}assignOffsets(e){this.tlasNodeCount=e;let t=e;for(let e=0;e<this.templateCount;e++){let n=this.tplOwner[e];n<0||this.sourceMesh[n]!==e||(this.tplBlasOffset[e]=t,t+=this.tplNodeCount[e])}for(let e=0;e<this.templateCount;e++){let t=this.tplOwner[e];if(t<0)continue;let n=this.sourceMesh[t];n!==e&&(this.tplBlasOffset[e]=this.tplBlasOffset[n])}this.totalBLASNodes=t-e,it(t,`combined TLAS + BLAS node count`)}get totalNodeCount(){return this.tlasNodeCount+this.totalBLASNodes}clear(){this.allocate(0),this.totalBLASNodes=0,this.tlasNodeCount=0}},Ho=16,Uo=32,Wo=e=>e<Uo?e:Uo,Go=8,Ko=64,qo=new Float64Array(16),Jo=class e{constructor(){this._flatBuffer=null,this._flatBufferCapacity=0,this._binCounts=new Int32Array(Uo*3),this._binBounds=new Float64Array(Uo*6*3),this._binSuffix=new Float64Array(Uo),this._binSuffixCount=new Int32Array(Uo),this._order=null,this._stackI=null,this._stackB=null,this._stackFrames=0,this._sortScratch=[],this._suffix=null,this._bounds=new Float64Array(12),this._extent=new Float64Array(3),this._cMin=new Float64Array(3)}static nodeCountFor(e){return e>0?e*2-1:0}releaseFlattenBuffer(){this._flatBuffer=null,this._flatBufferCapacity=0}build(t){let n=new Float64Array(t.count*6);t.writeWorldAABBs(n);let r=this.buildStructure(n,t.count);return e.fillLeaves(r.data,r.nodeCount,t),r}buildStructure(t,n){let r=e.nodeCountFor(n);if(n===0)return{data:new Float32Array,nodeCount:0};it(r,`TLAS node count`);let i=r*Ho;i>this._flatBufferCapacity&&(this._flatBuffer=new Float32Array(i),this._flatBufferCapacity=i);let a=this._flatBuffer,o=rt(a);(!this._order||this._order.length<n)&&(this._order=new Int32Array(n));let s=this._order;for(let e=0;e<n;e++)s[e]=e;this._ensureStack(Ko);let c=0,l=0,u=0,d=n,f=this._bounds;this._rangeBounds(t,s,u,d,f,0);let p=f[0],m=f[1],h=f[2],g=f[3],_=f[4],v=f[5];for(;;){if(d-u===1){let e=l*Ho;o[e]=0,o[e+1]=s[u],a[e+2]=0,o[e+3]=nt.BLAS_POINTER_LEAF}else{let e=this._partition(t,s,u,d,p,m,h,g,_,v),n=e-u,r=l+1,i=r+(n*2-1),y=l*Ho;a[y]=f[0],a[y+1]=f[1],a[y+2]=f[2],o[y+3]=r,a[y+4]=f[3],a[y+5]=f[4],a[y+6]=f[5],o[y+7]=i,a[y+8]=f[6],a[y+9]=f[7],a[y+10]=f[8],a[y+11]=0,a[y+12]=f[9],a[y+13]=f[10],a[y+14]=f[11],a[y+15]=0;let b=n<=d-e,x=b?0:6,S=b?6:0;c=this._push(c,b?i:r,b?e:u,b?d:e,f,S),l=b?r:i,b?d=e:u=e,p=f[x],m=f[x+1],h=f[x+2],g=f[x+3],_=f[x+4],v=f[x+5];continue}if(c===0)break;c--;let e=c*3,n=c*6;l=this._stackI[e],u=this._stackI[e+1],d=this._stackI[e+2],p=this._stackB[n],m=this._stackB[n+1],h=this._stackB[n+2],g=this._stackB[n+3],_=this._stackB[n+4],v=this._stackB[n+5]}return{data:a.subarray(0,i),nodeCount:r}}_push(e,t,n,r,i,a){e>=this._stackFrames&&this._ensureStack(this._stackFrames*2);let o=e*3,s=e*6;this._stackI[o]=t,this._stackI[o+1]=n,this._stackI[o+2]=r;for(let e=0;e<6;e++)this._stackB[s+e]=i[a+e];return e+1}_ensureStack(e){if(this._stackFrames>=e)return;let t=new Int32Array(e*3),n=new Float64Array(e*6);this._stackI&&(t.set(this._stackI),n.set(this._stackB)),this._stackI=t,this._stackB=n,this._stackFrames=e}static fillLeaves(t,n,r){let i=r.world,a=r.sourceMesh,o=r.tplBlasOffset,s=r.visible,c=r.tlasLeafIndex,l=rt(t);for(let r=0;r<n;r++){let n=r*Ho;if(l[n+3]!==nt.BLAS_POINTER_LEAF)continue;let u=l[n+1]&tt;l[n]=o[a[u]],t[n+2]=+!!s[u],e.writeLeafMatrix(t,l,n,i,u),c[u]=r}}static writeLeafMatrix(e,t,n,r,i){let a=qo;Io(r,i*16,a),e[n+4]=a[0],e[n+5]=a[4],e[n+6]=a[8],e[n+7]=a[12],e[n+8]=a[1],e[n+9]=a[5],e[n+10]=a[9],e[n+11]=a[13],e[n+12]=a[2],e[n+13]=a[6],e[n+14]=a[10],e[n+15]=a[14],t[n+1]=(i|(Bo(r,i*16)?et:0))>>>0}_partition(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=0;if(u===2)d=n+1;else if(u<=Go)d=n+(u>>1),this._insertionSortRange(e,t,n,r,this._widestCentroidAxis(e,t,n,r));else{if(d=this._binnedSplit(e,t,n,r,i,a,o,s,c,l),d>n&&d<r)return d;if(d=this._sweepSplit(e,t,n,r,i,a,o,s,c,l),!(d>n&&d<r)){let f=s-i,p=c-a,m=l-o,h=p>f&&p>m?1:m>f?2:0;this._sortRange(e,t,n,r,h),d=n+(u>>1)}}let f=this._bounds;return this._rangeBounds(e,t,n,d,f,0),this._rangeBounds(e,t,d,r,f,6),d}_binnedSplit(e,t,n,r,i,a,o,s,c,l){let u=this._surfaceArea(i,a,o,s,c,l);if(!(u>0)||!isFinite(u))return n;let d=1/0,f=1/0,p=1/0,m=-1/0,h=-1/0,g=-1/0;for(let i=n;i<r;i++){let n=t[i]*6,r=(e[n]+e[n+3])*.5,a=(e[n+1]+e[n+4])*.5,o=(e[n+2]+e[n+5])*.5;r<d&&(d=r),r>m&&(m=r),a<f&&(f=a),a>h&&(h=a),o<p&&(p=o),o>g&&(g=o)}let _=this._extent,v=this._cMin;_[0]=m-d,_[1]=h-f,_[2]=g-p,v[0]=d,v[1]=f,v[2]=p;let y=1/0,b=-1,x=-1,S=this._binCounts,C=this._binBounds,w=_[0]>1e-12,T=_[1]>1e-12,E=_[2]>1e-12;if(!w&&!T&&!E)return n;let D=Wo(r-n),O=w?D/_[0]:0,k=T?D/_[1]:0,A=E?D/_[2]:0;S.fill(0,0,D*3);for(let e=0;e<D*3;e++){let t=e*6;C[t]=C[t+1]=C[t+2]=1/0,C[t+3]=C[t+4]=C[t+5]=-1/0}for(let i=n;i<r;i++){let n=t[i]*6,r=e[n],a=e[n+1],o=e[n+2],s=e[n+3],c=e[n+4],l=e[n+5];for(let e=0;e<3;e++){let t=e===0?O:e===1?k:A;if(t===0)continue;let n=((e===0?(r+s)*.5:e===1?(a+c)*.5:(o+l)*.5)-v[e])*t|0;n<0?n=0:n>=D&&(n=D-1),n+=e*D,S[n]++;let i=n*6;r<C[i]&&(C[i]=r),a<C[i+1]&&(C[i+1]=a),o<C[i+2]&&(C[i+2]=o),s>C[i+3]&&(C[i+3]=s),c>C[i+4]&&(C[i+4]=c),l>C[i+5]&&(C[i+5]=l)}}for(let e=0;e<3;e++){if(!(_[e]>1e-12))continue;let t=e*D,n=this._binSuffix,r=this._binSuffixCount,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0,d=0;for(let e=D-1;e>=1;e--){let u=(t+e)*6;C[u]<i&&(i=C[u]),C[u+1]<a&&(a=C[u+1]),C[u+2]<o&&(o=C[u+2]),C[u+3]>s&&(s=C[u+3]),C[u+4]>c&&(c=C[u+4]),C[u+5]>l&&(l=C[u+5]),d+=S[t+e],n[e]=d?this._surfaceArea(i,a,o,s,c,l):0,r[e]=d}let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,v=-1/0,w=0;for(let i=1;i<D;i++){let a=(t+i-1)*6;if(C[a]<f&&(f=C[a]),C[a+1]<p&&(p=C[a+1]),C[a+2]<m&&(m=C[a+2]),C[a+3]>h&&(h=C[a+3]),C[a+4]>g&&(g=C[a+4]),C[a+5]>v&&(v=C[a+5]),w+=S[t+i-1],w===0||r[i]===0)continue;let o=1+(this._surfaceArea(f,p,m,h,g,v)*w+n[i]*r[i])/u;o<y&&(y=o,b=e,x=i)}}if(b<0)return n;let j=D/_[b],M=v[b],N=this._bounds;N[0]=N[1]=N[2]=N[6]=N[7]=N[8]=1/0,N[3]=N[4]=N[5]=N[9]=N[10]=N[11]=-1/0;let P=n,F=r-1;for(;P<=F;){let n=t[P]*6,r=((e[n+b]+e[n+3+b])*.5-M)*j|0;r<0?r=0:r>=D&&(r=D-1);let i=r<x?0:6;if(e[n]<N[i]&&(N[i]=e[n]),e[n+1]<N[i+1]&&(N[i+1]=e[n+1]),e[n+2]<N[i+2]&&(N[i+2]=e[n+2]),e[n+3]>N[i+3]&&(N[i+3]=e[n+3]),e[n+4]>N[i+4]&&(N[i+4]=e[n+4]),e[n+5]>N[i+5]&&(N[i+5]=e[n+5]),i===0)P++;else{let e=t[P];t[P]=t[F],t[F]=e,F--}}return P}_sweepSplit(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=this._surfaceArea(i,a,o,s,c,l);if(!(d>0)||!isFinite(d))return n;let f=this._suffixBuffer(u),p=1/0,m=-1,h=-1;for(let i=0;i<3;i++){this._sortRange(e,t,n,r,i);let a=1/0,o=1/0,s=1/0,c=-1/0,l=-1/0,g=-1/0;for(let r=u-1;r>=1;r--){let i=t[n+r]*6;e[i]<a&&(a=e[i]),e[i+1]<o&&(o=e[i+1]),e[i+2]<s&&(s=e[i+2]),e[i+3]>c&&(c=e[i+3]),e[i+4]>l&&(l=e[i+4]),e[i+5]>g&&(g=e[i+5]);let u=r*6;f[u]=a,f[u+1]=o,f[u+2]=s,f[u+3]=c,f[u+4]=l,f[u+5]=g}let _=1/0,v=1/0,y=1/0,b=-1/0,x=-1/0,S=-1/0;for(let r=1;r<u;r++){let a=t[n+r-1]*6;e[a]<_&&(_=e[a]),e[a+1]<v&&(v=e[a+1]),e[a+2]<y&&(y=e[a+2]),e[a+3]>b&&(b=e[a+3]),e[a+4]>x&&(x=e[a+4]),e[a+5]>S&&(S=e[a+5]);let o=r*6,s=this._surfaceArea(_,v,y,b,x,S),c=this._surfaceArea(f[o],f[o+1],f[o+2],f[o+3],f[o+4],f[o+5]),l=1+(s*r+c*(u-r))/d;l<p&&(p=l,m=i,h=r)}}return m<0||h<=0?n:(m!==2&&this._sortRange(e,t,n,r,m),n+h)}_widestCentroidAxis(e,t,n,r){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let u=n;u<r;u++){let n=t[u]*6,r=(e[n]+e[n+3])*.5,d=(e[n+1]+e[n+4])*.5,f=(e[n+2]+e[n+5])*.5;r<i&&(i=r),r>s&&(s=r),d<a&&(a=d),d>c&&(c=d),f<o&&(o=f),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o;return d>u&&d>f?1:f>u?2:0}_insertionSortRange(e,t,n,r,i){let a=i,o=3+i;for(let i=n+1;i<r;i++){let r=t[i],s=e[r*6+a]+e[r*6+o],c=i-1;for(;c>=n&&e[t[c]*6+a]+e[t[c]*6+o]>s;)t[c+1]=t[c],c--;t[c+1]=r}}_sortRange(e,t,n,r,i){let a=r-n,o=this._sortScratch;o.length=a;for(let e=0;e<a;e++)o[e]=t[n+e];let s=i,c=3+i;o.sort((t,n)=>e[t*6+s]+e[t*6+c]-(e[n*6+s]+e[n*6+c]));for(let e=0;e<a;e++)t[n+e]=o[e]}_suffixBuffer(e){let t=e*6;return(!this._suffix||this._suffix.length<t)&&(this._suffix=new Float64Array(t)),this._suffix}_rangeBounds(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=n;i<r;i++){let n=t[i]*6;e[n]<o&&(o=e[n]),e[n+1]<s&&(s=e[n+1]),e[n+2]<c&&(c=e[n+2]),e[n+3]>l&&(l=e[n+3]),e[n+4]>u&&(u=e[n+4]),e[n+5]>d&&(d=e[n+5])}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}_surfaceArea(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}},Yo=64*1024*1024,Xo=typeof SharedArrayBuffer<`u`,Zo=null;function Qo(e){Zo=e}function $o(e,t,n){let r=n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t);return Zo&&r.byteLength>0&&Zo(r.byteLength,n),r}var es=class e{constructor(e,t,n,r=Yo,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push($o(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push($o(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=Yo,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=$o(this.LaneType,n,this.shared);for(let t of this._views)t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)this.chunks[e]||this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0;return this.chunks[t]??this._materialize(t)}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,this._views&&(r._owner=this,this._views.push(r)),r}},ts=K.FLOATS_PER_TRIANGLE*4,ns=64,rs=.9,is=64,as=4,os=7040*1024*1024,ss=9216*1024*1024,cs=1.15,ls=12*1024*1024*1024;function us({triangles:e,placements:t,geometryBytes:n=0}){let r={triangles:e*ts,bvh:Math.ceil(e*rs)*ns,geometry:n,placements:t*is,orderMaps:e*as};return r.total=r.triangles+r.bvh+r.geometry+r.placements+r.orderMaps,r}function ds(e,{chunkBytes:t=Yo,shared:n=!1,allocate:r=null}={}){let i=Math.min(e,ls),a=r??(n?e=>new SharedArrayBuffer(e):e=>new ArrayBuffer(e)),o=[],s=0;try{for(;s<i;){let e=Math.min(t,i-s);o.push(a(e)),s+=e}}catch{}for(let e=o.length-1;e>=0;e--)o[e]=null;return o.length=0,{placed:s,want:i,exhausted:s<i,capped:e>i}}var fs=class{constructor(){this.reset()}reset(){this.phase=`idle`,this.events=[],this.samples=[],this.allocatedBytes=0,this.peakLiveBytes=0,this.byPhase=Object.create(null)}mark(e){return this.phase=e,this.byPhase[e]??={allocated:0,chunks:0},this}alloc(e,t=`chunk`){if(!(e>0))return;let n=this.byPhase[this.phase]??={allocated:0,chunks:0};n.allocated+=e,n.chunks++,this.allocatedBytes+=e,this.events.push({phase:this.phase,bytes:e,what:t,at:performance.now()})}sample(e,t){let n=0;for(let e in t)n+=t[e]||0;return n>this.peakLiveBytes&&(this.peakLiveBytes=n),this.samples.push({label:e,phase:this.phase,total:n,parts:t,at:performance.now()}),n}get report(){return{allocatedBytes:this.allocatedBytes,peakLiveBytes:this.peakLiveBytes,byPhase:{...this.byPhase},samples:this.samples.slice()}}},ps="let e,t;const n={MAX_BYTES_PER_TEXTURE:256*1024*1024,MAX_TEXTURE_DIMENSION:8192,CHUNK_SIZE:8,ADAPTIVE_CHUNK_SIZE:!0,MEMORY_SAFETY_FACTOR:.8};self.onmessage=async function(t){let{textures:n,maxTextureSize:a,method:o=`direct-transfer`}=t.data;try{e||r(a);let t=await i(n,a,o);self.postMessage(t,[t.data])}catch(e){console.error(`Worker processing failed:`,e),self.postMessage({error:e.message})}};function r(r){let i=Math.min(r,n.MAX_TEXTURE_DIMENSION);e=new OffscreenCanvas(i,i),t=e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0})}async function i(e,t,r){let i=h(e,t),o=i.maxWidth*i.maxHeight*e.length*4;if(o>n.MAX_BYTES_PER_TEXTURE)return console.log(`Large texture array detected (${(o/1024/1024).toFixed(2)}MB), using chunked processing`),await a(e,t,r);switch(r){case`direct-transfer`:return await d(e,t);case`offscreen-optimized`:return await p(e,t);case`imageBitmap-batch`:return await m(e,t);default:return await d(e,t)}}async function a(e,t,n){let{maxWidth:r,maxHeight:i}=h(e,t),a=e.length,c=o(r,i,a),l=Math.ceil(a/c);console.log(`Processing ${a} textures in ${l} chunks of up to ${c} textures each`),console.log(`Texture dimensions: ${r}x${i}, Est. memory per chunk: ${(r*i*c*4/1024/1024).toFixed(2)}MB`);let u;try{u=new Uint8Array(r*i*a*4)}catch{return console.warn(`Failed to allocate full texture array, reducing dimensions`),await f(e,g(e,t),n)}let d=r*i*c*4,p;try{p=new Uint8Array(d)}catch{return console.warn(`Failed to allocate chunk buffer, reducing dimensions`),await f(e,g(e,t),n)}for(let t=0;t<l;t++){let n=t*c,o=Math.min(n+c,a),l=o-n,d=await s(e.slice(n,o),r,i,p.subarray(0,r*i*l*4)),f=n*r*i*4,m=l*r*i*4;u.set(new Uint8Array(d.data.slice(0,m)),f),t%2==1&&await new Promise(e=>setTimeout(e,0))}return{data:u.buffer,width:r,height:i,depth:a}}function o(e,t,r){if(!n.ADAPTIVE_CHUNK_SIZE)return Math.min(n.CHUNK_SIZE,r);let i=e*t*4/(1024*1024),a;return a=i<=1?16:i<=4?8:i<=16?4:2,Math.min(a,r,n.CHUNK_SIZE*2)}async function s(n,r,i,a){(e.width!==r||e.height!==i)&&(e.width=r,e.height=i);let o=r*i*4;t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await c(t,a,e*o,r,i)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=e*o;a.fill(0,n,n+o)}}return{data:a.buffer,width:r,height:i,depth:n.length}}async function c(e,n,r,i,a){let o;if(e.isDirect&&e.bitmap)o=e.bitmap;else if(e.isImageData&&e.data){let t=new ImageData(new Uint8ClampedArray(e.data),e.width,e.height);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else if(e.isBlob){let t=new Blob([e.data]);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else throw Error(`Unknown texture data format`);t.clearRect(0,0,i,a),t.drawImage(o,0,0,i,a);let s=t.getImageData(0,0,i,a);n.set(s.data,r),(e.isImageData||e.isBlob)&&o.close()}async function l(e,t,n){let r;try{r=new Uint8Array(t*n*e.length*4)}catch(r){console.warn(`Failed to allocate texture array in processTextureChunk, reducing dimensions`);let i=Math.max(1,Math.floor(t/2)),a=Math.max(1,Math.floor(n/2));if(i===t&&a===n)throw r;return await l(e,i,a)}return await s(e,t,n,r)}async function u(e,t,n,r,i){await c(e,n,r*i*4*t,r,i)}async function d(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`direct-transfer`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await u(t,e,c,i,o)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function f(e,t,n){let{maxWidth:r,maxHeight:i}=t;return console.log(`Using reduced dimensions: ${r}x${i}`),await l(e,r,i,n)}async function p(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`offscreen-optimized`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let r=n[e];try{let n;if(r.isBlob){let e=new Blob([r.data]);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(r.data),r.width,r.height);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}t.clearRect(0,0,i,o),t.drawImage(n,0,0);let a=t.getImageData(0,0,i,o),s=i*o*4*e;c.set(a.data,s),n.close()}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function m(n,r){let{maxWidth:i,maxHeight:s}=h(n,r),c=n.length,l;try{l=new Uint8Array(i*s*c*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`imageBitmap-batch`)}let u=Math.min(o(i,s,n.length),n.length);for(let r=0;r<n.length;r+=u){let a=Math.min(r+u,n.length),o=[];for(let e=r;e<a;e++){let t=n[e],r;if(t.isBlob){let e=new Blob([t.data]);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(t.data),t.width,t.height);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}o.push(r.then(t=>({bitmap:t,index:e})))}let c=await Promise.all(o);e.width=i,e.height=s,t.imageSmoothingEnabled=!1;for(let{bitmap:e,index:n}of c){t.clearRect(0,0,i,s),t.drawImage(e,0,0);let r=t.getImageData(0,0,i,s),a=i*s*4*n;l.set(r.data,a),e.close()}}return{data:l.buffer,width:i,height:s,depth:c}}function h(e,t){let r=0,i=0;for(let t of e)r=Math.max(r,t.width||0),i=Math.max(i,t.height||0);let a=Math.min(t,n.MAX_TEXTURE_DIMENSION),o=Math.max(r,i);if(o>a){let e=a/o;r=Math.round(r*e),i=Math.round(i*e)}return r=Math.min(a,Math.max(4,Math.ceil(Math.max(1,r)/64)*64)),{maxWidth:r,maxHeight:Math.max(1,i)}}function g(e,t){let n=h(e,t);return{maxWidth:Math.max(64,Math.ceil(n.maxWidth/128)*64),maxHeight:Math.max(1,Math.floor(n.maxHeight/2))}}",ms=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,ps],{type:`text/javascript;charset=utf-8`});function hs(e){let t;try{if(t=ms&&(self.URL||self.webkitURL).createObjectURL(ms),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(ps),{type:`module`,name:e?.name})}}var gs=Object.freeze({ADAPTER_SOFTWARE:`adapter.software`,ASSET_UNREACHABLE:`asset.unreachable`,ASSET_AMBIGUOUS_ENTRY:`asset.ambiguous_entry`,ASSET_ARCHIVE_TOO_LARGE:`asset.archive_too_large`,ASSET_ENTRY_TOO_LARGE:`asset.entry_too_large`,TEXTURE_BUILD_FAILED:`texture.build_failed`,TEXTURE_PROCESSING_FALLBACK:`texture.processing_fallback`,TEXTURE_LIMIT_EXCEEDED:`texture.limit_exceeded`,ENVIRONMENT_LOAD_FAILED:`environment.load_failed`,SETTING_UNKNOWN_KEY:`setting.unknown_key`,RENDER_SIZE_DECLINED:`render.size_declined`,STAGE_RENDER_FAILED:`stage.render_failed`,RENDER_RESERVE_CAPPED:`render.reserve_capped`,SCENE_MEMORY_BUDGET:`scene.memory_budget`,EMISSIVE_INSTANCES_COLLAPSED:`emissive.instances_collapsed`,REFIT_SHARED_GEOMETRY:`refit.shared_geometry`}),_s=Object.freeze({ERROR:`error`,WARNING:`warning`}),vs=class extends Error{constructor(e){super(`[${e.code}] ${e.message}`),this.name=`EngineIssueError`,this.code=e.code,this.detail=e.detail}},ys=class{constructor({strict:e=!1,onIssue:t=null}={}){this.strict=e===!0,this._onIssue=t,this._entries=[]}record(e,t,n={},r=_s.ERROR){let i=Object.freeze({code:e,message:t,detail:n,severity:r,at:Date.now()});if(this._entries.push(i),this._onIssue?.(i),this.strict&&r===_s.ERROR)throw new vs(i);return i}warn(e,t,n){return this.record(e,t,n,_s.WARNING)}get list(){return this._entries.slice()}get errors(){return this._entries.filter(e=>e.severity===_s.ERROR)}clear(){this._entries.length=0}detach(){this._onIssue=null,this.strict=!1}},bs=e=>Math.min(Math.max(e,0),1);function xs(e,t,n,r,i){i[0]=bs(e),i[1]=bs(t),i[2]=bs(n)}function Ss(e,t,n,r,i){i[0]=bs(e*r),i[1]=bs(t*r),i[2]=bs(n*r)}function Cs(e,t,n,r,i){e*=r,t*=r,n*=r,i[0]=bs(e/(e+1)),i[1]=bs(t/(t+1)),i[2]=bs(n/(n+1))}function ws(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 Ts(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]=bs(1.60475*a-.53108*o-.07367*s),i[1]=bs(-.10208*a+1.10813*o-.00605*s),i[2]=bs(-.00327*a-.07276*o+1.07602*s)}function Es(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=bs((Math.log2(Math.max(c,1e-10))-d)/f),l=bs((Math.log2(Math.max(l,1e-10))-d)/f),u=bs((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]=bs(1.6605*m-.5876*h-.0728*g),i[1]=bs(-.1246*m+1.1329*h-.0083*g),i[2]=bs(-.0182*m-.1006*h+1.1187*g)}function Ds(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 Os=e=>(t,n,r,i,a)=>e(t>0?t:0,n>0?n:0,r>0?r:0,i,a),ks=new Map([[r.NoToneMapping,Os(xs)],[r.LinearToneMapping,Os(Ss)],[r.ReinhardToneMapping,Os(Cs)],[r.CineonToneMapping,Os(ws)],[r.ACESFilmicToneMapping,Os(Ts)],[r.AgXToneMapping,Os(Es)],[r.NeutralToneMapping,Os(Ds)]]),As=1/2.2;function js(e){return e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055}function Ms(e,t){return t===r.NoToneMapping?1:e}var Ns=.2126,Ps=.7152,Fs=.0722;function Is(e,t){if(t===1)return;let n=e[0]*Ns+e[1]*Ps+e[2]*Fs;e[0]=n+(e[0]-n)*t,e[1]=n+(e[1]-n)*t,e[2]=n+(e[2]-n)*t}function Ls(e,{exposure:t,toneMapping:n,saturation:i=1,preserveAlpha:a=!1}){let o=ks.get(n)??ks.get(r.NoToneMapping),s=Ms(t,n),c=new Uint8ClampedArray(e.length),l=[0,0,0];for(let t=0;t<e.length;t+=4)l[0]=e[t]*s,l[1]=e[t+1]*s,l[2]=e[t+2]*s,Is(l,i),o(l[0],l[1],l[2],1,l),c[t]=js(l[0])*255+.5,c[t+1]=js(l[1])*255+.5,c[t+2]=js(l[2])*255+.5,c[t+3]=a?e[t+3]*255+.5:255;return c}var Rs=It(`textures`),zs={toSRGB:null,toLinear:null};function Bs(e){if(!zs[e]){let t=new Uint8Array(256);for(let n=0;n<256;n++){let r=n/255,i=e===`toSRGB`?js(r):r<=.04045?r/12.92:((r+.055)/1.055)**2.4;t[n]=Math.max(0,Math.min(255,Math.round(i*255)))}zs[e]=t}return zs[e]}var Vs=class{constructor(){this.canvasContextPairs=[],this.maxPoolSize=at.CANVAS_POOL_SIZE}getCanvasWithContext(e,t,n=!1,r={}){let i={willReadFrequently:!0,alpha:!0,desynchronized:!0,...r},a=this.canvasContextPairs.pop();if(!a){let r;r=n&&typeof OffscreenCanvas<`u`?new OffscreenCanvas(e,t):document.createElement(`canvas`);let o=r.getContext(`2d`,i);a={canvas:r,context:o}}return a.canvas.width=e,a.canvas.height=t,a}releaseCanvasWithContext(e){this.canvasContextPairs.length<this.maxPoolSize&&(e.context.globalAlpha=1,e.context.globalCompositeOperation=`source-over`,e.context.imageSmoothingEnabled=!0,e.context.clearRect(0,0,e.canvas.width,e.canvas.height),e.canvas.width=1,e.canvas.height=1,this.canvasContextPairs.push(e))}getCanvas(e,t,n=!1){return this.getCanvasWithContext(e,t,n).canvas}getContext(e,t={}){let n=this.canvasContextPairs.find(t=>t.canvas===e);return n?n.context:e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0,...t})}dispose(){this.canvasContextPairs=[]}},Hs=class{constructor(e={}){this.pools=new Map,this.memoryUsage=0,this.maxMemoryUsage=e.maxMemory||bt.MAX_BUFFER_MEMORY,this.allocatedBuffers=new WeakMap,this.sizeStrategy=e.sizeStrategy||`adaptive`}getOptimalSize(e){switch(this.sizeStrategy){case`exact`:return e;case`power2`:return 2**Math.ceil(Math.log2(e));default:return e<1024?e:e<1024*1024?Math.ceil(e/1024)*1024:2**Math.ceil(Math.log2(e))}}getBuffer(e,t=Float32Array){let n=this.getOptimalSize(e),r=`${t.name}-${n}`,i=(this.pools.get(r)||[]).pop();if(!i)try{i=new t(n),this.memoryUsage+=i.byteLength,this.allocatedBuffers.set(i,!0)}catch{this.cleanup();try{i=new t(n),this.memoryUsage+=i.byteLength,this.allocatedBuffers.set(i,!0)}catch(e){let r=n*t.BYTES_PER_ELEMENT/(1024*1024),i=this.memoryUsage/(1024*1024);throw Error(`Buffer allocation failed: requested ${r.toFixed(1)}MB, current usage: ${i.toFixed(1)}MB, max: ${(this.maxMemoryUsage/(1024*1024)).toFixed(1)}MB. Original error: ${e.message}`)}}return this.memoryUsage>this.maxMemoryUsage*bt.CLEANUP_THRESHOLD&&this.cleanup(),this.checkMemoryHealth(),i.byteOffset+e*t.BYTES_PER_ELEMENT>i.buffer.byteLength&&(i=new t(e),this.memoryUsage+=i.byteLength),new t(i.buffer,i.byteOffset,e)}releaseBuffer(e,t=Float32Array){let n=(e.buffer.byteLength-e.byteOffset)/t.BYTES_PER_ELEMENT,r=this.getOptimalSize(n),i=`${t.name}-${r}`,a=this.pools.get(i)||[];a.length<at.BUFFER_POOL_SIZE?(a.push(new t(e.buffer,e.byteOffset,n)),this.pools.set(i,a)):this.allocatedBuffers.has(e)&&(this.memoryUsage-=e.byteLength,this.allocatedBuffers.delete(e))}cleanup(){let e=Array.from(this.pools.entries());e.slice(0,Math.floor(e.length/2)).forEach(([e,t])=>{t.forEach(e=>{this.allocatedBuffers.has(e)&&(this.memoryUsage-=e.byteLength,this.allocatedBuffers.delete(e))}),this.pools.delete(e)})}dispose(){this.pools.forEach(e=>{e.forEach(e=>{this.allocatedBuffers.has(e)&&this.allocatedBuffers.delete(e)})}),this.pools.clear(),this.memoryUsage=0}getMemoryStats(){return{currentUsage:this.memoryUsage,maxUsage:this.maxMemoryUsage,utilizationPercentage:this.memoryUsage/this.maxMemoryUsage*100,poolCount:this.pools.size,allocatedBufferCount:this.allocatedBuffers&&this.allocatedBuffers.size||0}}checkMemoryHealth(){let e=this.getMemoryStats();return e.utilizationPercentage>90?(console.warn(`Memory pool critical: ${e.utilizationPercentage.toFixed(1)}% used (${(e.currentUsage/(1024*1024)).toFixed(1)}MB / ${(e.maxUsage/(1024*1024)).toFixed(1)}MB)`),`critical`):e.utilizationPercentage>70?(console.warn(`Memory pool high: ${e.utilizationPercentage.toFixed(1)}% used (${(e.currentUsage/(1024*1024)).toFixed(1)}MB / ${(e.maxUsage/(1024*1024)).toFixed(1)}MB)`),`high`):`normal`}},Us=class{constructor(e=at.CACHE_SIZE_LIMIT){this.cache=new Map,this.accessOrder=[],this.maxSize=e}generateHash(e){let t=``;for(let n of e)if(n?.image){let e=n.image.width||0,r=n.image.height||0,i=n.image.src||n.uuid||``,a=n.flipY===!1?`n`:`f`;t+=`${e}x${r}_${i.slice(-8)}_${a}_`}return t+e.length}get(e){if(this.cache.has(e)){let t=this.cache.get(e);if(t?.userData&&t.userData.buffer===null){this.cache.delete(e);let t=this.accessOrder.indexOf(e);return t>-1&&this.accessOrder.splice(t,1),null}let n=this.accessOrder.indexOf(e);return n>-1&&this.accessOrder.splice(n,1),this.accessOrder.push(e),t}return null}set(e,t){if(this.cache.has(e)){let t=this.accessOrder.indexOf(e);t>-1&&this.accessOrder.splice(t,1)}else this.cache.size>=this.maxSize&&this.evictLRU();this.cache.set(e,t),this.accessOrder.push(e)}evictLRU(){if(this.accessOrder.length>0){let e=this.accessOrder.shift(),t=this.cache.get(e);t&&t.dispose&&t.dispose(),this.cache.delete(e)}}dispose(){this.cache.forEach(e=>{e&&e.dispose&&e.dispose()}),this.cache.clear(),this.accessOrder=[]}},Ws=class{constructor(e={}){this.useWorkers=typeof Worker<`u`,this.maxConcurrentWorkers=at.MAX_CONCURRENT_WORKERS,this.activeWorkers=0,this._issues=e.issues??null,this.maxTextureSize=this._clampTextureSize(e.maxTextureSize??at.DEFAULT_MAX_TEXTURE_SIZE),this.canvasPool=new Vs,this.bufferPool=new Hs({maxMemory:e.maxBufferMemory||bt.MAX_BUFFER_MEMORY,sizeStrategy:e.bufferSizeStrategy||`adaptive`}),this.textureCache=new Us,this.capabilities=this.detectCapabilities(),this.optimalMethod=this.selectOptimalMethod()}_reportTextureFailure(e,t){this._issues?.record(gs.TEXTURE_BUILD_FAILED,`${e} texture array failed to build — those surfaces render untextured`,{map:e,cause:String(t?.message??t)})}_clampTextureSize(e){let t=Math.floor(Number(e)||at.DEFAULT_MAX_TEXTURE_SIZE);return Math.max(at.MIN_TEXTURE_WIDTH,Math.min(t,at.MAX_TEXTURE_SIZE))}setMaxTextureSize(e){let t=this._clampTextureSize(e);return t===this.maxTextureSize?t:(this.maxTextureSize=t,this.textureCache?.dispose(),this.textureCache=new Us,this.maxTextureSize)}detectCapabilities(){return{offscreenCanvas:typeof OffscreenCanvas<`u`,imageBitmap:typeof createImageBitmap<`u`,workers:typeof Worker<`u`,hardwareConcurrency:navigator.hardwareConcurrency||4}}selectOptimalMethod(){return this.capabilities.workers&&this.capabilities.offscreenCanvas?`worker-offscreen`:this.capabilities.imageBitmap?`imageBitmap`:`canvas`}_harmonizeTransfer(e,t,n){let i=e?.image?.data;if(!i)return;let a=t.filter(e=>e?.image),o=n?r.SRGBColorSpace:r.LinearSRGBColorSpace,s=e.image.width*e.image.height*4,c=[];for(let e=0;e<a.length;e++){let t=a[e].colorSpace;if(t!==r.SRGBColorSpace&&t!==r.LinearSRGBColorSpace||t===o)continue;let l=Bs(n?`toSRGB`:`toLinear`),u=e*s,d=Math.min(u+s,i.length);for(let e=u;e<d;e+=4)i[e]=l[i[e]],i[e+1]=l[i[e+1]],i[e+2]=l[i[e+2]];c.push(a[e].name||a[e].source?.uuid?.slice(0,8)||`layer ${e}`)}if(c.length===0)return;e.needsUpdate=!0;let l=c.slice(0,4).join(`, `)+(c.length>4?`, +${c.length-4} more`:``);n?Rs.info(`re-encoded ${c.length}/${a.length} linear-declared colour map(s) to sRGB so the GPU decode round-trips: ${l}`):Rs.warn(`decoded ${c.length}/${a.length} sRGB-declared data map(s) to linear — precision is lost in the darks, check the asset: ${l}`)}async createTexturesToDataTexture(e,{srgbPool:t=!1}={}){if(!e||e.length===0)return null;let n=`${t?`s`:`l`}:${this.textureCache.generateHash(e)}`,r=this.textureCache.get(n);if(r)return r;let{normalized:i,bitmapsToClose:a}=await this._normalizeTexturesForProcessing(e),o=this.selectProcessingStrategy(i),s;try{switch(o.method){case`worker-direct`:s=await this.processWithWorkerDirect(i);break;case`main-batch`:s=await this.processOnMainThreadBatch(i,o.batchSize);break;case`main-streaming`:s=await this.processOnMainThreadStreaming(i);break;default:s=await this.processOnMainThreadSync(i)}return s&&(this._harmonizeTransfer(s,e,t),this.textureCache.set(n,s)),s}catch(n){this._issues?.warn(gs.TEXTURE_PROCESSING_FALLBACK,`worker texture processing failed — retrying on the main thread`,{cause:String(n?.message??n)});let r=await this.processOnMainThreadSync(i);return this._harmonizeTransfer(r,e,t),r}finally{for(let e of a)e.close()}}selectProcessingStrategy(e){let t=e.reduce((e,t)=>e+(t.image?.width||0)*(t.image?.height||0),0),n=t*4;return this.capabilities.workers&&n>bt.MAX_TEXTURE_MEMORY?{method:`main-streaming`}:this.capabilities.workers&&t>2097152?{method:`worker-direct`}:t>524288?{method:`main-batch`,batchSize:Math.min(4,e.length)}:e.length>8?{method:`main-streaming`}:{method:`main-sync`}}async processWithWorkerDirect(e){for(;this.activeWorkers>=this.maxConcurrentWorkers;)await new Promise(e=>setTimeout(e,10));this.activeWorkers++;try{let t=new hs,n=await this.prepareTexturesForWorkerDirect(e),r=await new Promise((e,r)=>{t.onmessage=t=>{t.data.error?r(Error(t.data.error)):e(t.data)},t.onerror=r;let i=[];n.forEach(e=>{e.data instanceof ArrayBuffer?i.push(e.data):e.bitmap&&i.push(e.bitmap)}),t.postMessage({textures:n,maxTextureSize:this.maxTextureSize,method:`direct-transfer`},i)});return t.terminate(),this.createDataArrayTextureFromResult(r)}finally{this.activeWorkers--}}async prepareTexturesForWorkerDirect(e){let t=[];for(let n of e){if(!n?.image)continue;let e=n.flipY!==!1;try{let r=n.image;if(typeof createImageBitmap<`u`&&(r instanceof HTMLImageElement||typeof ImageBitmap<`u`&&r instanceof ImageBitmap||typeof HTMLCanvasElement<`u`&&r instanceof HTMLCanvasElement||typeof OffscreenCanvas<`u`&&r instanceof OffscreenCanvas)){let r=await createImageBitmap(n.image,{imageOrientation:e?`flipY`:`none`});t.push({bitmap:r,width:n.image.width,height:n.image.height,isDirect:!0})}else{let r=n.image.width,i=n.image.height,a=await createImageBitmap(n.image,{imageOrientation:e?`flipY`:`none`}),o=this.canvasPool.getCanvasWithContext(r,i);o.context.drawImage(a,0,0),a.close();let s=o.context.getImageData(0,0,r,i);t.push({data:s.data.buffer,width:r,height:i,isImageData:!0}),this.canvasPool.releaseCanvasWithContext(o)}}catch(e){console.warn(`Failed to prepare texture for worker:`,e)}}return t}async processOnMainThreadBatch(e,t){let n=e.filter(e=>e?.image);if(n.length===0)return this.createFallbackTexture();let{maxWidth:r,maxHeight:i}=this.calculateOptimalDimensions(n),a=n.length,o=this.bufferPool.getBuffer(r*i*a*4,Uint8Array);for(let e=0;e<n.length;e+=t){let a=Math.min(e+t,n.length),s=[];for(let t=e;t<a;t++){let e=n[t],a=e.flipY!==!1,o=createImageBitmap(e.image,{resizeWidth:r,resizeHeight:i,resizeQuality:`high`,imageOrientation:a?`flipY`:`none`});s.push(o.then(e=>({bitmap:e,index:t})))}let c=await Promise.all(s),l=this.canvasPool.getCanvasWithContext(r,i);l.context.imageSmoothingEnabled=!1;for(let{bitmap:e,index:t}of c){l.context.clearRect(0,0,r,i),l.context.drawImage(e,0,0);let n=l.context.getImageData(0,0,r,i),a=r*i*4*t;o.set(n.data,a),e.close()}this.canvasPool.releaseCanvasWithContext(l)}return this.createDataArrayTextureFromBuffer(o,r,i,a)}async processOnMainThreadStreaming(e){let t=e.filter(e=>e?.image);if(t.length===0)return this.createFallbackTexture();let{maxWidth:n,maxHeight:r}=this.calculateOptimalDimensions(t),i=t.length,a=this.bufferPool.getBuffer(n*r*i*4,Uint8Array),o=this.canvasPool.getCanvasWithContext(n,r);o.context.imageSmoothingEnabled=!0,o.context.imageSmoothingQuality=`high`;for(let e=0;e<t.length;e++){let i=t[e],s=await createImageBitmap(i.image,{resizeWidth:n,resizeHeight:r,resizeQuality:`high`,imageOrientation:i.flipY===!1?`none`:`flipY`});o.context.clearRect(0,0,n,r),o.context.drawImage(s,0,0),s.close();let c=o.context.getImageData(0,0,n,r),l=n*r*4*e;a.set(c.data,l),e%bt.STREAM_BATCH_SIZE===0&&await new Promise(e=>setTimeout(e,0))}return this.canvasPool.releaseCanvasWithContext(o),this.createDataArrayTextureFromBuffer(a,n,r,i)}async processOnMainThreadSync(e){let t=e.filter(e=>e?.image);if(t.length===0)return this.createFallbackTexture();let{maxWidth:n,maxHeight:r}=this.calculateOptimalDimensions(t),i=t.length,a=this.bufferPool.getBuffer(n*r*i*4,Uint8Array),o=this.canvasPool.getCanvasWithContext(n,r);o.context.imageSmoothingEnabled=!0,o.context.imageSmoothingQuality=`high`;for(let e=0;e<t.length;e++){let i=t[e],s=await createImageBitmap(i.image,{resizeWidth:n,resizeHeight:r,resizeQuality:`high`,imageOrientation:i.flipY===!1?`none`:`flipY`});o.context.clearRect(0,0,n,r),o.context.drawImage(s,0,0),s.close();let c=o.context.getImageData(0,0,n,r),l=n*r*4*e;a.set(c.data,l)}return this.canvasPool.releaseCanvasWithContext(o),this.createDataArrayTextureFromBuffer(a,n,r,i)}createMaterialRawData(e){let t=q.FLOATS_PER_MATERIAL,n=e.length,r=n*t,i=new Float32Array(r);for(let r=0;r<n;r++){let n=e[r],a=r*t,o=n.mapMatrix??_t,s=n.normalMapMatrices??_t,c=n.roughnessMapMatrices??_t,l=n.metalnessMapMatrices??_t,u=n.emissiveMapMatrices??_t,d=n.bumpMapMatrices??_t,f=n.displacementMapMatrices??_t,p=[n.ior,n.transmission,n.thickness,n.emissiveIntensity,n.attenuationColor.r,n.attenuationColor.g,n.attenuationColor.b,J(n.attenuationDistance),n.opacity,n.side,n.transparent,n.alphaTest,n.alphaMode,n.depthWrite,n.normalScale?.x??1,n.normalScale?.y??1,n.color.r,n.color.g,n.color.b,n.metalness,n.emissive.r,n.emissive.g,n.emissive.b,n.roughness,n.map,n.normalMap,n.roughnessMap,n.metalnessMap,n.emissiveMap,n.bumpMap,n.clearcoat,n.clearcoatRoughness,n.dispersion,n.visible,n.sheen,n.sheenRoughness,n.sheenColor.r,n.sheenColor.g,n.sheenColor.b,1,n.specularIntensity,n.specularColor.r,n.specularColor.g,n.specularColor.b,n.iridescence,n.iridescenceIOR,n.iridescenceThicknessRange[0],n.iridescenceThicknessRange[1],n.bumpScale,n.displacementScale,n.displacementMap,0,o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7],s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],n.subsurfaceColor?.r??1,n.subsurfaceColor?.g??1,n.subsurfaceColor?.b??1,n.subsurface??0,n.subsurfaceRadius?.[0]??1,n.subsurfaceRadius?.[1]??.2,n.subsurfaceRadius?.[2]??.1,n.subsurfaceRadiusScale??1,n.subsurfaceAnisotropy??0,n.anisotropy??0,n.anisotropyRotation??0,n.anisotropyMap??-1,n.transmissionMap??-1,n.clearcoatMap??-1,n.clearcoatRoughnessMap??-1,n.sheenColorMap??-1,n.sheenRoughnessMap??-1,n.iridescenceMap??-1,n.iridescenceThicknessMap??-1,n.specularIntensityMap??-1,n.specularColorMap??-1,0,0,0];i.set(p,a)}return i}createBVHRawData(e){let t=[],n=e=>{let r=t.length;if(t.push(e),e.leftChild){let t=n(e.leftChild),r=n(e.rightChild);e.leftChild=t,e.rightChild=r}return r};n(e);let r=at.VEC4_PER_BVH_NODE*at.FLOATS_PER_VEC4;it(t.length,`BVH node count`);let i=t.length*r,a=new Float32Array(i),o=rt(a);for(let e=0;e<t.length;e++){let n=e*r,i=t[e];if(i.leftChild!==null){let e=i.leftChild,r=i.rightChild,s=t[e],c=t[r];a[n]=s.boundsMin.x,a[n+1]=s.boundsMin.y,a[n+2]=s.boundsMin.z,o[n+3]=e,a[n+4]=s.boundsMax.x,a[n+5]=s.boundsMax.y,a[n+6]=s.boundsMax.z,o[n+7]=r,a[n+8]=c.boundsMin.x,a[n+9]=c.boundsMin.y,a[n+10]=c.boundsMin.z,a[n+12]=c.boundsMax.x,a[n+13]=c.boundsMax.y,a[n+14]=c.boundsMax.z}else o[n]=i.triangleOffset,o[n+1]=i.triangleCount,o[n+3]=nt.TRIANGLE_LEAF}return a}async createMaterialTextures(e){let{materials:t,maps:n,normalMaps:i,bumpMaps:a,roughnessMaps:o,metalnessMaps:s,emissiveMaps:c,displacementMaps:l}=e;console.log(`[TextureCreator] Creating material textures only`);let u=performance.now();try{if(!t||t.length===0)throw Error(`No materials provided for texture creation`);this.textureCache.dispose(),this.textureCache=new Us;let e=[];for(let[t,r]of[[`albedo`,n],[`normal`,i],[`bump`,a],[`roughness`,o],[`metalness`,s],[`emissive`,c],[`displacement`,l]])!r||r.length===0||e.push(this.createTexturesToDataTexture(r).then(e=>({type:t,texture:e})).catch(e=>(this._reportTextureFailure(t,e),{type:t,texture:null})));let d=await Promise.allSettled(e),f=d.find(e=>e.status===`rejected`);if(f)throw f.reason;let p={};d.forEach(e=>{if(e.status===`fulfilled`&&e.value){let{type:t,texture:n}=e.value;if(n)switch(t){case`albedo`:n.colorSpace=r.SRGBColorSpace,p.albedoTexture=n;break;case`normal`:p.normalTexture=n;break;case`bump`:p.bumpTexture=n;break;case`roughness`:p.roughnessTexture=n;break;case`metalness`:p.metalnessTexture=n;break;case`emissive`:n.colorSpace=r.SRGBColorSpace,p.emissiveTexture=n;break;case`displacement`:p.displacementTexture=n;break}}});let m=performance.now()-u;return console.log(`[TextureCreator] Material texture creation complete (${m.toFixed(2)}ms)`),p}catch(e){throw console.error(`[TextureCreator] Material texture creation error:`,e),Error(`Material texture creation failed: ${e.message}`)}}calculateOptimalDimensions(e){let t=0,n=0;for(let r of e)t=Math.max(t,r.image.width),n=Math.max(n,r.image.height);let r=Math.max(t,n);if(r>this.maxTextureSize){let e=this.maxTextureSize/r;t=Math.round(t*e),n=Math.round(n*e)}return{maxWidth:st(t,this.maxTextureSize),maxHeight:Math.max(1,n)}}createDataArrayTextureFromResult(e){let t=(e.data instanceof ArrayBuffer,new Uint8Array(e.data));return this.createDataArrayTextureFromBuffer(t,e.width,e.height,e.depth)}createDataArrayTextureFromBuffer(e,t,n,i){let a=new r.DataArrayTexture(e,t,n,i);a.minFilter=r.LinearFilter,a.magFilter=r.LinearFilter,a.wrapS=r.RepeatWrapping,a.wrapT=r.RepeatWrapping,a.format=r.RGBAFormat,a.type=r.UnsignedByteType,a.needsUpdate=!0,a.generateMipmaps=!1,a.userData={buffer:e,bufferType:Uint8Array};let o=a.dispose.bind(a);return a.dispose=()=>{a.userData.buffer&&(this.bufferPool.releaseBuffer(a.userData.buffer,a.userData.bufferType),a.userData.buffer=null),o()},a}async _normalizeTexturesForProcessing(e){let t=[],n=[],i=[];for(let n of e)if(n?.image){if(n.isCompressedTexture&&n.format===r.RGBAFormat&&n.mipmaps?.[0]?.data){let e=n.mipmaps[0],r=t.length;t.push(null),i.push({index:r,flipY:n.flipY,promise:Gs(e.data,e.width,e.height)});continue}if(n.isCompressedTexture){console.warn(`[TextureCreator] GPU-compressed texture in mixed group — using placeholder`),t.push(null);continue}if(n.image.data&&!(n.image instanceof HTMLImageElement)&&!(n.image instanceof HTMLCanvasElement)&&!(typeof ImageBitmap<`u`&&n.image instanceof ImageBitmap)){let e=t.length;t.push(null),i.push({index:e,flipY:n.flipY,promise:Gs(n.image.data,n.image.width,n.image.height)});continue}t.push(n)}if(i.length>0){let e=await Promise.allSettled(i.map(e=>e.promise));for(let r=0;r<i.length;r++){let{index:a,flipY:o}=i[r],s=e[r];if(s.status===`fulfilled`){let e=s.value;n.push(e),t[a]={image:e,flipY:o}}else console.warn(`[TextureCreator] Failed to create ImageBitmap:`,s.reason)}}for(let e=0;e<t.length;e++)if(t[e]===null){let r=new Uint8ClampedArray([255,255,255,255]),i=await createImageBitmap(new ImageData(r,1,1));n.push(i),t[e]={image:i,flipY:!1}}return{normalized:t,bitmapsToClose:n}}createFallbackTexture(){let e=new r.DataArrayTexture(new Uint8Array([255,255,255,255]),1,1,1);return e.minFilter=r.LinearFilter,e.magFilter=r.LinearFilter,e.format=r.RGBAFormat,e.type=r.UnsignedByteType,e.needsUpdate=!0,e.generateMipmaps=!1,e}dispose(){this.canvasPool.dispose(),this.bufferPool.dispose(),this.textureCache.dispose()}};function Gs(e,t,n){let r=new Uint8ClampedArray(e.buffer,e.byteOffset,e.byteLength);return createImageBitmap(new ImageData(r,t,n))}var Ks=It(`geometry`),qs=at.MAX_TEXTURES_LIMIT,Js=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];function Ys(e){for(let t=0;t<16;t++)if(e[t]!==Js[t])return!1;return!0}function Xs(e){if(e.userData?.gltfExtensions?.KHR_materials_unlit?.alphaMode){let t=e.userData.gltfExtensions.KHR_materials_unlit.alphaMode;return t===`BLEND`?2:+(t===`MASK`)}return e.alphaTest>0?1:e.transparent&&e.opacity<1||e.map&&e.map.format===r.RGBAFormat&&e.transparent?2:0}function Zs(e){let t=0,n=new Set,r=e=>{let i=e.isMesh&&e.material?e.geometry:null;if(i&&!n.has(i.uuid)){n.add(i.uuid);for(let e in i.attributes)t+=i.attributes[e].array?.byteLength??0;t+=i.index?.array?.byteLength??0}if(e.children)for(let t of e.children)r(t)};return r(e),t}function Qs(e,t){let n=e.x,r=e.y,i=e.z;e.x=t[0]*n+t[4]*r+t[8]*i+t[12],e.y=t[1]*n+t[5]*r+t[9]*i+t[13],e.z=t[2]*n+t[6]*r+t[10]*i+t[14]}function $s(e,t){let n=e.x,r=e.y,i=e.z;e.x=t[0]*n+t[3]*r+t[6]*i,e.y=t[1]*n+t[4]*r+t[7]*i,e.z=t[2]*n+t[5]*r+t[8]*i}var ec=1<<21;function tc(e){return!!(e.isSkinnedMesh||Object.keys(e.geometry?.morphAttributes??{}).length)}function nc(e){return e[0]*(e[5]*e[10]-e[9]*e[6])-e[4]*(e[1]*e[10]-e[9]*e[2])+e[8]*(e[1]*e[6]-e[5]*e[2])}var rc=class{constructor({issues:e=null}={}){this._issues=e,this._droppedTextures=0,this._vectorPool={vec3:Array(9).fill().map(()=>new r.Vector3),vec2:[,,,,,,].fill().map(()=>new r.Vector2)},this._geometryRanges=new Map,this.expandedTriangleCount=0,this._allocatePlacements(0),this._matrixPool={mat3:new r.Matrix3,mat4:new r.Matrix4},this.resetArrays(),this.triangleCount=0,this.currentTriangleIndex=0}_getVec3(e=0){return this._vectorPool.vec3[e%this._vectorPool.vec3.length]}_getVec2(e=0){return this._vectorPool.vec2[e%this._vectorPool.vec2.length]}extract(e){this.resetArrays();let t=this._countTriangles(e);return this._triangleCapacity=Math.max(1024,t),this._allocateTriangles(this._triangleCapacity),this.currentTriangleIndex=0,this._allocatePlacements(this._countPlacements(e)),this._geometryUses=this._countGeometryUses(e),this.bakeInverse=new Map,this.traverseObject(e),this._shareInstanceMatrices(),this._compressAttributes(e),this.logStats(),this.getExtractedData()}surveyScene(e){let t=0,n=e=>{if(e.isMesh&&e.geometry&&e.material&&t++,e.children)for(let t of e.children)n(t)};return n(e),{triangles:this._countTriangles(e),placements:this._countPlacements(e),meshes:t,geometryBytes:Zs(e)}}_countGeometryUses(e){let t=new Map;return e.traverse(e=>{if(!e.isMesh||!e.geometry||!e.material)return;let n=`${e.geometry.uuid}|${e.material.uuid}`;t.set(n,(t.get(n)??0)+1)}),t}_countPlacements(e){let t=0;if(e.isMesh&&e.geometry&&e.material&&(t+=e.isInstancedMesh&&e.instanceMatrix?e.count??e.instanceMatrix.array.length/16:1),e.children)for(let n of e.children)t+=this._countPlacements(n);return t}_allocatePlacements(e){this.instanceCount=0,this.instanceCapacity=e,this.instanceSource=new Int32Array(e),this.instanceMatrices=new Float32Array(e*16),this._shareable=[],this._compressed=new Set}_compressAttributes(e){let t=this._compressed,n=(e,t)=>{if(!e.userData?.__rayzeeExternal){t(e);for(let r of e.children)n(r,t)}};n(e,e=>{let n=e.geometry;if(!(!e.isMesh||!n||t.has(n.uuid))){t.add(n.uuid);for(let e of[`normal`,`tangent`,`color`]){let t=n.getAttribute(e);if(!t||t.normalized||!(t.array instanceof Float32Array)||n.morphAttributes?.[e]?.length)continue;let i=t.array,a=!0;for(let e=0;e<i.length;e++){let t=i[e];if(!(t>=-1.0001&&t<=1.0001)){a=!1;break}}if(!a)continue;let o=new Int16Array(i.length);for(let e=0;e<i.length;e++)o[e]=Math.round(Math.max(-1,Math.min(1,i[e]))*32767);n.setAttribute(e,new r.BufferAttribute(o,t.itemSize,!0))}}})}_shareInstanceMatrices(){for(let{mesh:e,start:t,count:n}of this._shareable){let r=e.instanceMatrix;!r||r.array.length!==n*16||(r.array=this.instanceMatrices.subarray(t*16,(t+n)*16))}this._shareable=[]}_countTriangles(e){let t=0;if(e.isMesh&&e.geometry&&e.material){let n=e.geometry.index,r=e.geometry.attributes.position;n?t+=Math.ceil(n.count/3):r&&(t+=Math.ceil(r.count/3))}if(e.children)for(let n of e.children)t+=this._countTriangles(n);return t}_ensureCapacity(e){if(e<=this._triangleCapacity)return;let t=this.triangles,n=this.currentTriangleIndex;this._allocateTriangles(e);for(let e=0;e<n;e++)this.triangles.chunkFor(e).set(t.chunkFor(e).subarray(t.baseOf(e),t.baseOf(e)+t.lanesPerRecord),this.triangles.baseOf(e));this._triangleCapacity=e}_allocateTriangles(e){this.triangles=new es(e,K.FLOATS_PER_TRIANGLE,Uint32Array,void 0,Xo),this.triangleFloatChunks=this.triangles.viewAs(Float32Array),this.triangleData=this.triangles.single,this.triangleFloats=this.triangleFloatChunks.single}traverseObject(e){if(e.isMesh?this.processMesh(e):e.isDirectionalLight?this.directionalLights.push(e):e.isCamera&&this.cameras.push(e),e.children)for(let t of e.children)this.traverseObject(t)}processMesh(e){if(!e.geometry||!e.material){console.warn(`Skipping mesh with missing geometry or material:`,e);return}let t=this.processMaterial(e.material);e.userData.materialIndex=t;let n=this.meshes.length;this.meshes.push(e),e.userData.meshIndex=n;let r=`${e.geometry.uuid}|${t}`,i=tc(e),a=!this._emissiveMaterial(t)&&!i,o=a?this._geometryRanges.get(r):null;if(o){let t={start:o.start,count:o.count,expandedStart:this.expandedTriangleCount,sharedFrom:o.meshIndex};this.expandedTriangleCount+=o.count,this.meshTriangleRanges.push(t),this._recordPlacements(e,n);return}let s=this.currentTriangleIndex,c=e.isInstancedMesh&&!i&&this._emissiveMaterial(t)&&this._canExpand(e),l=c||!e.isInstancedMesh&&!i&&(this._geometryUses.get(`${e.geometry.uuid}|${e.material?.uuid}`)===1||this._emissiveMaterial(t));this.extractGeometry(e,t,n,l,c);let u={start:s,count:this.currentTriangleIndex-s,expandedStart:this.expandedTriangleCount};this.expandedTriangleCount+=u.count,this.meshTriangleRanges.push(u),u.count>0&&!l&&a&&this._geometryRanges.set(r,{...u,meshIndex:n}),this._recordPlacements(e,n,l,c)}_recordPlacements(e,t,n=!1,r=!1){let i=e.matrixWorld.elements,a=this.instanceMatrices,o=this.instanceSource;if(!e.isInstancedMesh||!e.instanceMatrix||r){let r=this._nextPlacement();if(o[r]=t,n){for(let e=0;e<16;e++)a[r*16+e]=+(e%5==0);this.bakeInverse.set(t,Float32Array.from(this._matrixPool.mat4.copy(e.matrixWorld).invert().elements))}else for(let e=0;e<16;e++)a[r*16+e]=i[e];return}let s=e.instanceMatrix.array,c=e.count??s.length/16,l=Ys(i);l&&s.length===c*16&&this._shareable.push({mesh:e,start:this.instanceCount,count:c});for(let e=0;e<c;e++){let n=e*16,r=this._nextPlacement(),c=r*16;if(o[r]=t,l){for(let e=0;e<16;e++)a[c+e]=s[n+e];continue}for(let e=0;e<4;e++)for(let t=0;t<4;t++)a[c+e*4+t]=i[t]*s[n+e*4]+i[4+t]*s[n+e*4+1]+i[8+t]*s[n+e*4+2]+i[12+t]*s[n+e*4+3]}}_nextPlacement(){if(this.instanceCount>=this.instanceCapacity){let e=Math.max(16,this.instanceCapacity*2),t=new Int32Array(e),n=new Float32Array(e*16);t.set(this.instanceSource),n.set(this.instanceMatrices),this.instanceSource=t,this.instanceMatrices=n,this.instanceCapacity=e}return this.instanceCount++}_canExpand(e){let t=e.geometry,n=(t.index?t.index.count:t.attributes.position.count)/3,r=e.count??(e.instanceMatrix?.array.length??0)/16;return n*r<=ec?!0:(this._issues?.record(gs.EMISSIVE_INSTANCES_COLLAPSED,`"${e.name||`instanced mesh`}" would need ${Math.round(n*r).toLocaleString()} triangles to light every instance; lighting the first one only`,{instances:r,trianglesPerInstance:n,limit:ec}),!1)}_emissiveMaterial(e){let t=this.materials[e];if(!t||!(t.emissiveIntensity>0))return!1;let n=t.emissive;return!!n&&(n.r>0||n.g>0||n.b>0)}processMaterial(e){let t=this._materialUuidMap.get(e.uuid)??-1;if(t===-1){e.depthWrite===!1&&(e.depthWrite=!0,Rt(Ks,`depthWrite`,`material had depthWrite disabled — enabled for rastered rendering`));let n=this.createMaterialObject(e);this.materials.push(n),t=this.materials.length-1,this._materialUuidMap.set(e.uuid,t)}return t}getMaterialType(e){return e.isMeshPhysicalMaterial?`physical`:e.isMeshStandardMaterial?`standard`:e.isMeshPhongMaterial?`phong`:e.isMeshLambertMaterial?`lambert`:e.isMeshBasicMaterial?`basic`:e.isMeshToonMaterial?`toon`:`unknown`}getPhysicalDefaults(){return{emissive:new r.Color(0,0,0),emissiveIntensity:1,roughness:1,metalness:0,ior:1.5,opacity:1,transmission:0,thickness:.1,attenuationColor:new r.Color(16777215),attenuationDistance:1/0,dispersion:0,sheen:0,sheenRoughness:1,sheenColor:new r.Color(0),specularIntensity:1,specularColor:new r.Color(16777215),clearcoat:0,clearcoatRoughness:0,iridescence:0,iridescenceIOR:1.3,iridescenceThicknessRange:[100,400],normalScale:{x:1,y:1},bumpScale:1,displacementScale:1,alphaTest:0,subsurface:0,subsurfaceColor:new r.Color(16777215),subsurfaceRadius:[1,.2,.1],subsurfaceRadiusScale:1,subsurfaceAnisotropy:0,anisotropy:0,anisotropyRotation:0}}mapLegacyMaterialToPhysical(e,t){let n={};switch(t){case`basic`:n.emissive=e.color.clone(),n.emissiveIntensity=1,n.color=new r.Color(0),n.roughness=1,n.metalness=0;break;case`lambert`:n.roughness=1,n.metalness=0,n.specularIntensity=0;break;case`phong`:{let t=e.shininess||30;n.roughness=Math.sqrt(2/(t+2)),n.metalness=0}if(e.specular){let t=e.specular.r*.299+e.specular.g*.587+e.specular.b*.114;n.specularIntensity=Math.min(t*2,1),n.specularColor=e.specular.clone()}break;case`toon`:n.roughness=.9,n.metalness=0;break;case`standard`:case`physical`:break}return n}createMaterialObject(e){let t=this.getPhysicalDefaults(),n=this.getMaterialType(e),i=this.mapLegacyMaterialToPhysical(e,n),a=(e.transmission??0)>0,o=(e.metalness??i.metalness??0)>.1&&!a?2.5:t.ior,s=e.color||new r.Color(16777215);return n===`basic`&&!e.map&&(s=new r.Color(0)),{uuid:e.uuid,color:s,emissive:i.emissive??e.emissive??t.emissive,emissiveIntensity:i.emissiveIntensity??e.emissiveIntensity??t.emissiveIntensity,roughness:Math.max(.02,i.roughness??e.roughness??t.roughness),metalness:i.metalness??e.metalness??t.metalness,ior:e.ior??o,opacity:e.opacity??t.opacity,transmission:e.transmission??t.transmission,thickness:e.thickness??t.thickness,attenuationColor:e.attenuationColor??t.attenuationColor,attenuationDistance:e.attenuationDistance??t.attenuationDistance,dispersion:e.dispersion??t.dispersion,sheen:e.sheen??t.sheen,sheenRoughness:e.sheenRoughness??t.sheenRoughness,sheenColor:e.sheenColor??t.sheenColor,clearcoat:e.clearcoat??t.clearcoat,clearcoatRoughness:e.clearcoatRoughness??t.clearcoatRoughness,iridescence:e.iridescence??t.iridescence,iridescenceIOR:e.iridescenceIOR??t.iridescenceIOR,iridescenceThicknessRange:e.iridescenceThicknessRange??t.iridescenceThicknessRange,subsurface:e.subsurface??t.subsurface,subsurfaceColor:e.subsurfaceColor??t.subsurfaceColor,subsurfaceRadius:e.subsurfaceRadius??t.subsurfaceRadius,subsurfaceRadiusScale:e.subsurfaceRadiusScale??t.subsurfaceRadiusScale,subsurfaceAnisotropy:e.subsurfaceAnisotropy??t.subsurfaceAnisotropy,anisotropy:e.anisotropy??t.anisotropy,anisotropyRotation:e.anisotropyRotation??t.anisotropyRotation,specularIntensity:i.specularIntensity??e.specularIntensity??t.specularIntensity,specularColor:i.specularColor??e.specularColor??t.specularColor,normalScale:e.normalScale??t.normalScale,bumpScale:e.bumpScale??t.bumpScale,displacementScale:e.displacementScale??t.displacementScale,transparent:+!!e.transparent,alphaTest:e.alphaTest??t.alphaTest,alphaMode:Xs(e),side:this.getMaterialSide(e),depthWrite:e.depthWrite??!0?1:0,map:this.processTexture(e.map,this.maps),normalMap:this.processTexture(e.normalMap,this.normalMaps),bumpMap:this.processTexture(e.bumpMap,this.bumpMaps),roughnessMap:this.processTexture(e.roughnessMap,this.roughnessMaps),metalnessMap:this.processTexture(e.metalnessMap,this.metalnessMaps),emissiveMap:this.processTexture(e.emissiveMap,this.emissiveMaps),displacementMap:this.processTexture(e.displacementMap,this.displacementMaps),anisotropyMap:this.processTexture(e.anisotropyMap,this.anisotropyMaps),clearcoatMap:this.processTexture(e.clearcoatMap,this.clearcoatMaps),clearcoatRoughnessMap:this.processTexture(e.clearcoatRoughnessMap,this.clearcoatRoughnessMaps),transmissionMap:this.processTexture(e.transmissionMap,this.transmissionMaps),thicknessMap:this.processTexture(e.thicknessMap,[]),sheenColorMap:this.processTexture(e.sheenColorMap,this.sheenColorMaps),sheenRoughnessMap:this.processTexture(e.sheenRoughnessMap,this.sheenRoughnessMaps),specularIntensityMap:this.processTexture(e.specularIntensityMap,this.specularIntensityMaps),specularColorMap:this.processTexture(e.specularColorMap,this.specularColorMaps),iridescenceMap:this.processTexture(e.iridescenceMap,this.iridescenceMaps),iridescenceThicknessMap:this.processTexture(e.iridescenceThicknessMap,this.iridescenceThicknessMaps),mapMatrix:this.getTextureMatrix(e.map),normalMapMatrices:this.getTextureMatrix(e.normalMap),bumpMapMatrices:this.getTextureMatrix(e.bumpMap),roughnessMapMatrices:this.getTextureMatrix(e.roughnessMap),metalnessMapMatrices:this.getTextureMatrix(e.metalnessMap),emissiveMapMatrices:this.getTextureMatrix(e.emissiveMap),displacementMapMatrices:this.getTextureMatrix(e.displacementMap),originalType:n}}getTextureMatrix(e){return e?(e.matrixAutoUpdate&&e.updateMatrix(),e.matrix.elements):new r.Matrix3().elements}getMaterialSide(e){if(e.transmission>0)return 2;switch(e.side){case r.FrontSide:return 0;case r.BackSide:return 1;case r.DoubleSide:return 2;default:return 0}}processTexture(e,t){if(!e)return-1;let n=this._textureIndexCache.get(t);n||(n=new Map,this._textureIndexCache.set(t,n));let r=e.source.uuid,i=n.get(r);if(i!==void 0)return i;if(t.length<qs){t.push(e);let i=t.length-1;return n.set(r,i),i}return this._droppedTextures++,this._droppedTextures===1&&this._issues?.record(gs.TEXTURE_LIMIT_EXCEEDED,`scene needs more than ${qs} distinct textures for one map type; the rest render untextured`,{limit:qs,firstDropped:e.name||e.source?.uuid}),-1}extractGeometry(e,t,n,i=!1,a=!1){e.updateMatrix(),e.updateMatrixWorld();let o=e.geometry;o.attributes.normal||o.computeVertexNormals();let s=o.attributes.position,c=o.attributes.normal,l=o.attributes.uv,u=o.index?o.index.array:null,d=u?u.length/3:s.count/3;if(a){let i=e.count??e.instanceMatrix.array.length/16,a=this._matrixPool.mat4,o=new r.Matrix4;for(let f=0;f<i;f++){a.fromArray(e.instanceMatrix.array,f*16),o.multiplyMatrices(e.matrixWorld,a);let i=new r.Matrix3().getNormalMatrix(o);this.extractTrianglesInBatch(s,c,l,u,d,t,n,o,i,nc(o.elements)<0)}return}let f=i?this._matrixPool.mat4.copy(e.matrixWorld):null,p=i?this._matrixPool.mat3.getNormalMatrix(e.matrixWorld):null,m=i&&nc(f.elements)<0;this.extractTrianglesInBatch(s,c,l,u,d,t,n,f,p,m)}extractTrianglesInBatch(e,t,n,r,i,a,o,s=null,c=null,l=!1){for(;this.materialTriangleCounts.length<=a;)this.materialTriangleCounts.push(0);this.materialTriangleCounts[a]+=i;let u=this._getVec3(0),d=this._getVec3(1),f=this._getVec3(2),p=this._getVec3(3),m=this._getVec3(4),h=this._getVec3(5),g=this._getVec2(0),_=this._getVec2(1),v=this._getVec2(2);this._ensureCapacity(this.currentTriangleIndex+i);let y=s?.elements,b=c?.elements;for(let c=0;c<i;c++){let i=c*3,x=r?r[i+0]:i+0,S=l?2:1,C=l?1:2,w=r?r[i+S]:i+S,T=r?r[i+C]:i+C;this.getVertex(e,x,u),this.getVertex(e,w,d),this.getVertex(e,T,f),this.getVertex(t,x,p),this.getVertex(t,w,m),this.getVertex(t,T,h),n?(this.getVertex(n,x,g),this.getVertex(n,w,_),this.getVertex(n,T,v)):(g.set(0,0),_.set(0,0),v.set(0,0)),s&&(Qs(u,y),Qs(d,y),Qs(f,y),$s(p,b),$s(m,b),$s(h,b)),p.normalize(),m.normalize(),h.normalize(),this.packTriangleDataTextureFormat(this.currentTriangleIndex,u,d,f,p,m,h,g,_,v,a,o),this.currentTriangleIndex++}}packTriangleDataTextureFormat(e,t,n,r,i,a,o,s,c,l,u,d){let f=K,p=this.triangles.baseOf(e),m=this.triangleFloatChunks.chunkFor(e),h=this.triangles.chunkFor(e);m[p+f.POSITION_A_OFFSET+0]=t.x,m[p+f.POSITION_A_OFFSET+1]=t.y,m[p+f.POSITION_A_OFFSET+2]=t.z,h[p+f.NORMAL_A_PACKED_OFFSET]=Qe(i.x,i.y,i.z),m[p+f.POSITION_B_OFFSET+0]=n.x,m[p+f.POSITION_B_OFFSET+1]=n.y,m[p+f.POSITION_B_OFFSET+2]=n.z,h[p+f.NORMAL_B_PACKED_OFFSET]=Qe(a.x,a.y,a.z),m[p+f.POSITION_C_OFFSET+0]=r.x,m[p+f.POSITION_C_OFFSET+1]=r.y,m[p+f.POSITION_C_OFFSET+2]=r.z,h[p+f.NORMAL_C_PACKED_OFFSET]=Qe(o.x,o.y,o.z),m[p+f.UV_AB_OFFSET+0]=s.x,m[p+f.UV_AB_OFFSET+1]=s.y,m[p+f.UV_AB_OFFSET+2]=c.x,m[p+f.UV_AB_OFFSET+3]=c.y,m[p+f.UV_C_OFFSET+0]=l.x,m[p+f.UV_C_OFFSET+1]=l.y,h[p+f.MATERIAL_FLAGS_OFFSET]=Ze(u,this.materials[u]),h[p+f.MESH_INDEX_OFFSET]=d}getTriangleData(){return this.triangles?this.triangles.trimTo(this.currentTriangleIndex):null}getTriangleCount(){return this.currentTriangleIndex}getVertex(e,t,n){return e.itemSize===2?(n.x=e.getX(t),n.y=e.getY(t)):e.itemSize>=3&&(n.x=e.getX(t),n.y=e.getY(t),n.z=e.getZ(t)),n}logStats(){let e=this.currentTriangleIndex*K.FLOATS_PER_TRIANGLE*4;Ks.debug(Y.list([`${Y.count(this.currentTriangleIndex,`tri`)} (${Y.mb(e)})`,Y.count(this.materials.length,`material`),Y.count(this.maps.length,`map`)]))}extractMaterialsOnly(e){return this.resetArrays(),this._traverseMaterialsOnly(e),this.getExtractedData()}_traverseMaterialsOnly(e){if(e.isMesh&&e.geometry&&e.material){let t=this.processMaterial(e.material);e.userData.materialIndex=t;let n=this.meshes.length;this.meshes.push(e),e.userData.meshIndex=n}else e.isDirectionalLight?this.directionalLights.push(e):e.isCamera&&this.cameras.push(e);if(e.children)for(let t of e.children)this._traverseMaterialsOnly(t)}resetArrays(){this._droppedTextures=0,this.triangles=null,this.triangleData=null,this.triangleFloatChunks=null,this.triangleFloats=null,this.triangleCount=0,this.currentTriangleIndex=0,this.materials=[],this.materialTriangleCounts=[],this.meshes=[],this.meshTriangleRanges=[],this._geometryRanges=new Map,this.expandedTriangleCount=0,this._allocatePlacements(0),this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.roughnessMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this._materialUuidMap=new Map,this._textureIndexCache=new WeakMap}getExtractedData(){return{triangleData:this.getTriangleData(),triangleCount:this.getTriangleCount(),materials:this.materials,materialTriangleCounts:this.materialTriangleCounts,meshes:this.meshes,meshTriangleRanges:this.meshTriangleRanges,expandedTriangleCount:this.expandedTriangleCount,instanceSource:this.instanceSource.subarray(0,this.instanceCount),instanceMatrices:this.instanceMatrices.subarray(0,this.instanceCount*16),instanceCount:this.instanceCount,bakeInverse:this.bakeInverse,maps:this.maps,normalMaps:this.normalMaps,bumpMaps:this.bumpMaps,metalnessMaps:this.metalnessMaps,emissiveMaps:this.emissiveMaps,roughnessMaps:this.roughnessMaps,displacementMaps:this.displacementMaps,anisotropyMaps:this.anisotropyMaps,transmissionMaps:this.transmissionMaps,clearcoatMaps:this.clearcoatMaps,clearcoatRoughnessMaps:this.clearcoatRoughnessMaps,sheenColorMaps:this.sheenColorMaps,sheenRoughnessMaps:this.sheenRoughnessMaps,iridescenceMaps:this.iridescenceMaps,iridescenceThicknessMaps:this.iridescenceThicknessMaps,specularIntensityMaps:this.specularIntensityMaps,specularColorMaps:this.specularColorMaps,directionalLights:this.directionalLights,cameras:this.cameras}}},ic=class{constructor(){this.maxLeafSize=8}build(e){let t=e.length;if(t===0){let e=new Float32Array(16);return e[7]=1,e[14]=1,e[15]=-1,{nodeData:e,nodeCount:1,sortedPerm:new Int32Array,bitTrails:new Float32Array}}let n=new Int32Array(t);for(let e=0;e<t;e++)n[e]=e;let r=2*t+4,i=new Float32Array(r*16),a=0,o=new Float32Array(t),s=(t,r,c,l)=>{let u=a++,d=u*16,f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0,v=0,y=1/0,b=1/0,x=1/0,S=-1/0,C=-1/0,w=-1/0;for(let i=t;i<r;i++){let t=e[n[i]];f=Math.min(f,t.bMinX),p=Math.min(p,t.bMinY),m=Math.min(m,t.bMinZ),h=Math.max(h,t.bMaxX),g=Math.max(g,t.bMaxY),_=Math.max(_,t.bMaxZ),v+=t.power,y=Math.min(y,t.cx),b=Math.min(b,t.cy),x=Math.min(x,t.cz),S=Math.max(S,t.cx),C=Math.max(C,t.cy),w=Math.max(w,t.cz)}i[d+0]=f,i[d+1]=p,i[d+2]=m,i[d+3]=v,i[d+4]=h,i[d+5]=g,i[d+6]=_;let T=r-t,E;if(T<=this.maxLeafSize){i[d+7]=1,i[d+8]=t,i[d+9]=T,i[d+10]=0,i[d+11]=0,E=null;for(let i=t;i<r;i++){let t=e[n[i]];E=oc(E,ac(t)),o[i]=c}E||={ax:0,ay:0,az:1,cosO:-1}}else{let a=S-y,o=C-b,u=w-x,f;f=a>=o&&a>=u?0:o>=u?1:2;let p=[`cx`,`cy`,`cz`][f],m=t+r>>1;this._nthElement(n,e,t,r,m,p),i[d+7]=0;let h=s(t,m,c,l+1),g=s(m,r,c+2**l,l+1);i[d+8]=h.nodeIndex,i[d+9]=g.nodeIndex,i[d+10]=0,i[d+11]=0,E=oc(h.cone,g.cone)}return i[d+12]=E.ax,i[d+13]=E.ay,i[d+14]=E.az,i[d+15]=E.cosO,{nodeIndex:u,cone:E}};s(0,t,0,0);let c=new Int32Array(t);for(let e=0;e<t;e++)c[e]=n[e];let l=new Float32Array(a*16);return l.set(i.subarray(0,a*16)),console.log(`[LightBVHBuilder] Built BVH: ${a} nodes for ${t} emissive triangles`),{nodeData:l,nodeCount:a,sortedPerm:c,bitTrails:o}}_nthElement(e,t,n,r,i,a){for(;n<r-1;){let o=n+r>>1,s=t[e[o]][a],c=e[o];e[o]=e[r-1],e[r-1]=c;let l=n;for(let i=n;i<r-1;i++)t[e[i]][a]<s&&(c=e[i],e[i]=e[l],e[l]=c,l++);if(c=e[l],e[l]=e[r-1],e[r-1]=c,l===i)return;l<i?n=l+1:r=l}}};function ac(e){return e.twoSided?{ax:e.nx,ay:e.ny,az:e.nz,cosO:-1}:{ax:e.nx,ay:e.ny,az:e.nz,cosO:1}}function oc(e,t){if(!e)return t;if(!t||e.cosO<=-1)return e;if(t.cosO<=-1)return t;let n=Math.min(Math.max(e.cosO,-1),1),r=Math.min(Math.max(t.cosO,-1),1),i=Math.acos(n),a=Math.acos(r),o=Math.min(Math.max(e.ax*t.ax+e.ay*t.ay+e.az*t.az,-1),1),s=Math.acos(o);if(Math.min(s+a,Math.PI)<=i)return e;if(Math.min(s+i,Math.PI)<=a)return t;let c=(i+a+s)*.5;if(c>=Math.PI)return{ax:e.ax,ay:e.ay,az:e.az,cosO:-1};let l=c-i,u=e.ay*t.az-e.az*t.ay,d=e.az*t.ax-e.ax*t.az,f=e.ax*t.ay-e.ay*t.ax,p=Math.sqrt(u*u+d*d+f*f);if(p<1e-8)return{ax:e.ax,ay:e.ay,az:e.az,cosO:-1};u/=p,d/=p,f/=p;let m=Math.cos(l),h=Math.sin(l),g=u*e.ax+d*e.ay+f*e.az,_=d*e.az-f*e.ay,v=f*e.ax-u*e.az,y=u*e.ay-d*e.ax,b=e.ax*m+_*h+u*g*(1-m),x=e.ay*m+v*h+d*g*(1-m),S=e.az*m+y*h+f*g*(1-m),C=Math.sqrt(b*b+x*x+S*S)||1;return{ax:b/C,ay:x/C,az:S/C,cosO:Math.cos(c)}}var sc=It(`emissive`),cc=class{constructor(){this.emissiveTriangles=[],this.emissiveCount=0,this.totalEmissivePower=0,this.emissiveIndicesArray=null,this.emissivePowerArray=null,this.cdfArray=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._totalTriangleCount=0,this._hiddenMeshes=new Set}extractEmissiveTriangles(e,t,n,r=null){this.emissiveTriangles=[],this.totalEmissivePower=0,this._totalTriangleCount=n;let i=K.FLOATS_PER_TRIANGLE,a=K.MATERIAL_FLAGS_OFFSET,o=K.MESH_INDEX_OFFSET,s=e&&e.chunks?e:null,c=s?s.viewAs(Float32Array):null,l=s?null:e,u=s?null:new Float32Array(e.buffer,e.byteOffset,e.length);for(let e=0;e<n;e++){let n=s?s.chunkFor(e):l,d=s?c.chunkFor(e):u,f=s?s.baseOf(e):e*i,p=n[f+a]&Ye,m=n[f+o],h=t[p];if(!h)continue;let g=h.emissive||{r:0,g:0,b:0},_=h.emissiveIntensity||0;if(_>0&&(g.r>0||g.g>0||g.b>0)){let t=r?.placementRunOf?.(m)?.start??-1,n=t>=0&&r.isSet[t],i=n?r.world:null,a=n?t*16:0,o=(e,t,n)=>i?i[a]*e+i[a+4]*t+i[a+8]*n+i[a+12]:e,s=(e,t,n)=>i?i[a+1]*e+i[a+5]*t+i[a+9]*n+i[a+13]:t,c=(e,t,n)=>i?i[a+2]*e+i[a+6]*t+i[a+10]*n+i[a+14]:n,l=d[f+0],u=d[f+1],v=d[f+2],y=d[f+4],b=d[f+5],x=d[f+6],S=d[f+8],C=d[f+9],w=d[f+10],T=o(l,u,v),E=s(l,u,v),D=c(l,u,v),O=o(y,b,x),k=s(y,b,x),A=c(y,b,x),j=o(S,C,w),M=s(S,C,w),N=c(S,C,w),P=this._calculateTriangleArea(T,E,D,O,k,A,j,M,N),F=(.2126*g.r+.7152*g.g+.0722*g.b)*_*P,I=(k-E)*(N-D)-(A-D)*(M-E),L=(A-D)*(j-T)-(O-T)*(N-D),R=(O-T)*(M-E)-(k-E)*(j-T),ee=Math.sqrt(I*I+L*L+R*R)||1,z=h.side===1?-1:1;I=I/ee*z,L=L/ee*z,R=R/ee*z;let te=h.side===2,ne=(T+O+j)/3,B=(E+k+M)/3,re=(D+A+N)/3,ie=Math.min(T,O,j),ae=Math.min(E,k,M),oe=Math.min(D,A,N),se=Math.max(T,O,j),ce=Math.max(E,k,M),le=Math.max(D,A,N);this.emissiveTriangles.push({triangleIndex:e,materialIndex:p,meshIndex:m,instanceLeaf:n?r.tlasLeafIndex[t]:-1,power:F,area:P,emissive:{r:g.r,g:g.g,b:g.b},emissiveIntensity:_,cx:ne,cy:B,cz:re,bMinX:ie,bMinY:ae,bMinZ:oe,bMaxX:se,bMaxY:ce,bMaxZ:le,nx:I,ny:L,nz:R,twoSided:te}),this.totalEmissivePower+=F}}return this.emissiveCount=this.emissiveTriangles.length,this.emissiveCount>0&&sc.debug(`${Y.n(this.emissiveCount)} emissive tris (${(this.emissiveCount/n*100).toFixed(2)}%) · total power ${this.totalEmissivePower.toFixed(2)}`),this._buildDataArrays(),this.emissiveCount}_calculateTriangleArea(e,t,n,r,i,a,o,s,c){let l=r-e,u=i-t,d=a-n,f=o-e,p=s-t,m=c-n,h=u*m-d*p,g=d*f-l*m,_=l*p-u*f;return Math.sqrt(h*h+g*g+_*_)*.5}_buildDataArrays(){this.emissiveIndicesArray=new Int32Array(this.emissiveCount),this.emissivePowerArray=new Float32Array(this.emissiveCount);for(let e=0;e<this.emissiveCount;e++)this.emissiveIndicesArray[e]=this.emissiveTriangles[e].triangleIndex,this.emissivePowerArray[e]=this.emissiveTriangles[e].power;this._buildCDF()}_buildCDF(){if(this.emissiveCount===0){this.cdfArray=new Float32Array(1),this.cdfArray[0]=0;return}this.cdfArray=new Float32Array(this.emissiveCount);let e=0;for(let t=0;t<this.emissiveCount;t++)e+=this.emissivePowerArray[t],this.cdfArray[t]=e;if(e>0)for(let t=0;t<this.emissiveCount;t++)this.cdfArray[t]/=e}sampleCDF(e){if(this.emissiveCount===0)return-1;if(this.emissiveCount===1)return 0;let t=0,n=this.emissiveCount-1;for(;t<n;){let r=Math.floor((t+n)/2);this.cdfArray[r]<e?t=r+1:n=r}return t}getGPUData(){return{emissiveIndices:this.emissiveIndicesArray,emissivePower:this.emissivePowerArray,emissiveCDF:this.cdfArray,emissiveCount:this.emissiveCount,totalPower:this.totalEmissivePower}}createEmissiveTexture(){if(this.emissiveCount===0)return new r.DataTexture(new Float32Array(4),1,1,r.RGBAFormat,r.FloatType);let e=new Float32Array(this.emissiveCount*4);for(let t=0;t<this.emissiveCount;t++){let n=t*4;e[n+0]=this.emissiveIndicesArray[t],e[n+1]=this.emissivePowerArray[t],e[n+2]=this.cdfArray[t],e[n+3]=0}let t=Math.ceil(Math.sqrt(this.emissiveCount)),n=Math.ceil(this.emissiveCount/t),i=t*n*4,a=new Float32Array(i);a.set(e);let o=new r.DataTexture(a,t,n,r.RGBAFormat,r.FloatType);return o.needsUpdate=!0,o.generateMipmaps=!1,o.minFilter=r.NearestFilter,o.magFilter=r.NearestFilter,sc.debug(`emissive texture ${Y.px(t,n)} · ${Y.n(this.emissiveCount)} entries`),o}createEmissiveRawData(){if(this.emissiveCount===0)return new Float32Array(8);let e=new Float32Array(this.emissiveCount*8);for(let t=0;t<this.emissiveCount;t++){let n=this.emissiveTriangles[t],r=t*8;e[r+0]=n.triangleIndex,e[r+1]=n.power,e[r+2]=this.cdfArray[t],e[r+3]=n.instanceLeaf,e[r+4]=n.emissive.r*n.emissiveIntensity,e[r+5]=n.emissive.g*n.emissiveIntensity,e[r+6]=n.emissive.b*n.emissiveIntensity,e[r+7]=n.area}return sc.debug(`emissive raw data ${Y.n(this.emissiveCount)} entries (${Y.mb(e.byteLength)})`),e}getStats(){if(this.emissiveCount===0)return{count:0,totalPower:0,averagePower:0,minPower:0,maxPower:0};let e=1/0,t=-1/0;for(let n=0;n<this.emissiveCount;n++){let r=this.emissivePowerArray[n];e=Math.min(e,r),t=Math.max(t,r)}return{count:this.emissiveCount,totalPower:this.totalEmissivePower,averagePower:this.totalEmissivePower/this.emissiveCount,minPower:e,maxPower:t}}updateMaterialEmissive(e,t,n,r,i){let a=t.emissive||{r:0,g:0,b:0},o=t.emissiveIntensity||0,s=o>0&&(a.r>0||a.g>0||a.b>0);if(s!==this.emissiveTriangles.some(t=>t.materialIndex===e))return this.extractEmissiveTriangles(n,r,i),!0;if(!s)return!1;let c=.2126*a.r+.7152*a.g+.0722*a.b;for(let t of this.emissiveTriangles)t.materialIndex===e&&(t.power=c*o*t.area,t.emissive={r:a.r,g:a.g,b:a.b},t.emissiveIntensity=o);return!0}setHiddenMeshes(e){let t=new Set;for(let e of this.emissiveTriangles)t.add(e.meshIndex);let n=new Set;for(let r of e)t.has(r)&&n.add(r);let r=this._hiddenMeshes,i=n.size!==r.size;if(!i){for(let e of n)if(!r.has(e)){i=!0;break}}return this._hiddenMeshes=n,i}buildLightBVH(){let e=this._hiddenMeshes.size===0?this.emissiveTriangles:this.emissiveTriangles.filter(e=>!this._hiddenMeshes.has(e.meshIndex));this.emissiveCount=e.length,this.totalEmissivePower=0;for(let t of e)this.totalEmissivePower+=t.power;if(e.length===0)return this.lightBVHNodeData=new Float32Array(16),this.lightBVHNodeData[7]=1,this.lightBVHNodeData[14]=1,this.lightBVHNodeData[15]=-1,this.lightBVHNodeCount=1,this.emissiveBitTrailMap=new Float32Array(Math.max(this._totalTriangleCount,1)).fill(-1),this.emissiveIndicesArray=new Int32Array,this.emissivePowerArray=new Float32Array,this._buildCDF(),this.emissiveTriangleData=new Float32Array(8),1;let{nodeData:t,nodeCount:n,sortedPerm:r,bitTrails:i}=new ic().build(e);this.lightBVHNodeData=t,this.lightBVHNodeCount=n,this._rebuildSortedEmissiveData(r,e),this.emissiveBitTrailMap=new Float32Array(Math.max(this._totalTriangleCount,1)).fill(-1);for(let t=0;t<r.length;t++){let n=e[r[t]].triangleIndex;this.emissiveBitTrailMap[n]=i[t]}return n}_rebuildSortedEmissiveData(e,t){let n=e.length;this.emissiveIndicesArray=new Int32Array(n),this.emissivePowerArray=new Float32Array(n);for(let r=0;r<n;r++){let n=e[r];this.emissiveIndicesArray[r]=t[n].triangleIndex,this.emissivePowerArray[r]=t[n].power}this._buildCDF();let r=new Float32Array(n*8);for(let i=0;i<n;i++){let n=t[e[i]],a=i*8;r[a+0]=n.triangleIndex,r[a+1]=n.power,r[a+2]=this.cdfArray[i],r[a+3]=n.instanceLeaf,r[a+4]=n.emissive.r*n.emissiveIntensity,r[a+5]=n.emissive.g*n.emissiveIntensity,r[a+6]=n.emissive.b*n.emissiveIntensity,r[a+7]=n.area}this.emissiveTriangleData=r,sc.debug(`rebuilt sorted emissive data · ${Y.n(n)} entries`)}clear(){this.emissiveTriangles=[],this.emissiveCount=0,this.totalEmissivePower=0,this.emissiveIndicesArray=null,this.emissivePowerArray=null,this.cdfArray=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._totalTriangleCount=0,this._hiddenMeshes=new Set}},lc=class{constructor(e=`Build`,{namespace:t=`build`,level:n=`debug`}={}){this.label=e,this.level=n,this.logger=It(t),this.entries=new Map,this.order=[],this.totalStart=performance.now()}start(e){return this.entries.set(e,{start:performance.now(),end:null}),this.order.includes(e)||this.order.push(e),this}end(e){let t=this.entries.get(e);return t&&(t.end=performance.now(),t.duration=t.end-t.start),this}getDuration(e){return this.entries.get(e)?.duration??0}print(e=[]){let t=performance.now()-this.totalStart,n=this.order.map(e=>{let t=this.entries.get(e)?.duration??0;return t>=1?`${e} ${Math.round(t)}ms`:null}).filter(Boolean),r=Y.list([this.label,...e,Y.ms(t)]);return this.level===`info`?this.logger.summary(r,n):this.logger.debug(Y.list([r,n.join(` · `)])),{steps:Object.fromEntries(this.order.map(e=>[e,Math.round(this.entries.get(e)?.duration??0)])),total:Math.round(t)}}},uc="const e={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11},t=e.FLOATS_PER_TRIANGLE,n=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),r=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),i=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):r(e)}},a=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,o=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,s=(e,t)=>e.chunked?e.chunked.baseOf(t):t*u,c=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):n(e),u:t?e:r(e)}};function l(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}const u=16,d=1073741824;function f(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=1e-12*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>z&&(z=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=z}var p=class{constructor(){this._bounds=null,this._boundsNodeCount=0}updateTrianglePositions(n,r,i){let a=i.length,o=c(n);for(let n=0;n<a;n++){let a=i[n],s=o.chunked?o.f.chunkFor(n):o.f,c=o.chunked?o.u.chunkFor(n):o.u,u=o.chunked?o.chunked.baseOf(n):n*t,d=a*9,f=r[d],p=r[d+1],m=r[d+2],h=r[d+3],g=r[d+4],_=r[d+5],v=r[d+6],y=r[d+7],b=r[d+8];s[u+e.POSITION_A_OFFSET]=f,s[u+e.POSITION_A_OFFSET+1]=p,s[u+e.POSITION_A_OFFSET+2]=m,s[u+e.POSITION_B_OFFSET]=h,s[u+e.POSITION_B_OFFSET+1]=g,s[u+e.POSITION_B_OFFSET+2]=_,s[u+e.POSITION_C_OFFSET]=v,s[u+e.POSITION_C_OFFSET+1]=y,s[u+e.POSITION_C_OFFSET+2]=b;let x=h-f,S=g-p,C=_-m,w=v-f,T=y-p,E=b-m,D=l(S*E-C*T,C*w-x*E,x*T-S*w);c[u+e.NORMAL_A_PACKED_OFFSET]=D,c[u+e.NORMAL_B_PACKED_OFFSET]=D,c[u+e.NORMAL_C_PACKED_OFFSET]=D}}refitRange(n,r,l,u){let f=c(r);u>this._boundsNodeCount&&(this._bounds=new Float32Array(u*6),this._boundsNodeCount=u);let p=this._bounds,m=l+u,h=i(n);for(let n=m-1;n>=l;n--){let r=a(h,n),i=o(h,n),c=s(h,n),u=(n-l)*6;if(i[c+3]===d){let n=i[c],r=i[c+1],a=1/0,o=1/0,s=1/0,l=-1/0,d=-1/0,m=-1/0;for(let i=0;i<r;i++){let r=n+i,c=f.chunked?f.f.chunkFor(r):f.f,u=f.chunked?f.chunked.baseOf(r):r*t,p=c[u+e.POSITION_A_OFFSET],h=c[u+e.POSITION_A_OFFSET+1],g=c[u+e.POSITION_A_OFFSET+2],_=c[u+e.POSITION_B_OFFSET],v=c[u+e.POSITION_B_OFFSET+1],y=c[u+e.POSITION_B_OFFSET+2],b=c[u+e.POSITION_C_OFFSET],x=c[u+e.POSITION_C_OFFSET+1],S=c[u+e.POSITION_C_OFFSET+2];a=Math.min(a,p,_,b),o=Math.min(o,h,v,x),s=Math.min(s,g,y,S),l=Math.max(l,p,_,b),d=Math.max(d,h,v,x),m=Math.max(m,g,y,S)}p[u]=a,p[u+1]=o,p[u+2]=s,p[u+3]=l,p[u+4]=d,p[u+5]=m}else{let e=i[c+3],t=i[c+7],n=(e-l)*6,a=(t-l)*6,o=p[n],s=p[n+1],d=p[n+2],f=p[n+3],m=p[n+4],h=p[n+5],g=p[a],_=p[a+1],v=p[a+2],y=p[a+3],b=p[a+4],x=p[a+5];r[c]=o,r[c+1]=s,r[c+2]=d,r[c+4]=f,r[c+5]=m,r[c+6]=h,r[c+8]=g,r[c+9]=_,r[c+10]=v,r[c+12]=y,r[c+13]=b,r[c+14]=x,p[u]=Math.min(o,g),p[u+1]=Math.min(s,_),p[u+2]=Math.min(d,v),p[u+3]=Math.max(f,y),p[u+4]=Math.max(m,b),p[u+5]=Math.max(h,x)}}}refit(n,r,l){let u=c(r);l!==this._boundsNodeCount&&(this._bounds=new Float32Array(l*6),this._boundsNodeCount=l);let p=this._bounds,m=i(n);for(let n=l-1;n>=0;n--){let r=a(m,n),i=o(m,n),c=s(m,n),l=n*6,h=i[c+3];if(h===d){let n=i[c],r=i[c+1],a=1/0,o=1/0,s=1/0,d=-1/0,f=-1/0,m=-1/0;for(let i=0;i<r;i++){let r=n+i,c=u.chunked?u.f.chunkFor(r):u.f,l=u.chunked?u.chunked.baseOf(r):r*t,p=c[l+e.POSITION_A_OFFSET],h=c[l+e.POSITION_A_OFFSET+1],g=c[l+e.POSITION_A_OFFSET+2],_=c[l+e.POSITION_B_OFFSET],v=c[l+e.POSITION_B_OFFSET+1],y=c[l+e.POSITION_B_OFFSET+2],b=c[l+e.POSITION_C_OFFSET],x=c[l+e.POSITION_C_OFFSET+1],S=c[l+e.POSITION_C_OFFSET+2];a=Math.min(a,p,_,b),o=Math.min(o,h,v,x),s=Math.min(s,g,y,S),d=Math.max(d,p,_,b),f=Math.max(f,h,v,x),m=Math.max(m,g,y,S)}p[l]=a,p[l+1]=o,p[l+2]=s,p[l+3]=d,p[l+4]=f,p[l+5]=m}else if(h===1073741825)f(r,c,p,i[c]*6,p,l);else{let e=i[c+3],t=i[c+7],n=e*6,a=t*6,o=p[n],s=p[n+1],u=p[n+2],d=p[n+3],f=p[n+4],m=p[n+5],h=p[a],g=p[a+1],_=p[a+2],v=p[a+3],y=p[a+4],b=p[a+5];r[c]=o,r[c+1]=s,r[c+2]=u,r[c+4]=d,r[c+5]=f,r[c+6]=m,r[c+8]=h,r[c+9]=g,r[c+10]=_,r[c+12]=v,r[c+13]=y,r[c+14]=b,p[l]=Math.min(o,h),p[l+1]=Math.min(s,g),p[l+2]=Math.min(u,_),p[l+3]=Math.max(d,v),p[l+4]=Math.max(f,y),p[l+5]=Math.max(m,b)}}}};const m=64*1024*1024;function h(e,t,n){return n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t)}var g=class e{constructor(e,t,n,r=m,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push(h(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push(h(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=m,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=h(this.LaneType,n,this.shared);for(let t of this._views)t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)this.chunks[e]||this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0;return this.chunks[t]??this._materialize(t)}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,this._views&&(r._owner=this,this._views.push(r)),r}};const _=new p;let v=null,y=null,b=0;self.onmessage=function(e){let{type:t}=e.data;if(t===`init`){v=g.adopt(e.data.sharedBvhBufs.map(e=>new Float32Array(e)),e.data.bvhRecordCount,16,e.data.bvhRecordsPerChunk),y=g.adopt(e.data.sharedTriBufs.map(e=>new Uint32Array(e)),e.data.triRecordCount,e.data.triLanesPerRecord,e.data.triRecordsPerChunk),b=v.recordCount;return}if(t===`refit`)try{let e=performance.now();_.refit(v,y,b),self.postMessage({type:`refitComplete`,refitTimeMs:performance.now()-e})}catch(e){console.error(`[BVHRefitWorker] Refit error:`,e),self.postMessage({type:`error`,error:e.message})}};",dc=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,uc],{type:`text/javascript;charset=utf-8`});function fc(e){let t;try{if(t=dc&&(self.URL||self.webkitURL).createObjectURL(dc),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(uc),{type:`module`,name:e?.name})}}var pc="const e=Object.freeze({viewer:Object.freeze({areaLightIntensityScale:.1,environmentRotation:270,toneMapping:4,saturation:1.2}),physical:Object.freeze({areaLightIntensityScale:1,environmentRotation:0,toneMapping:6,saturation:1})}),t={resolution:512,canvasWidth:512,canvasHeight:512,maxTextureSize:4096,toneMapping:e.viewer.toneMapping,exposure:1,saturation:e.viewer.saturation,enableEnvironment:!0,showBackground:!0,transparentBackground:!1,environmentIntensity:1,backgroundIntensity:1,backgroundColor:`#000000`,backgroundBlurriness:0,backgroundBlurSamples:8,environmentRotation:e.viewer.environmentRotation,groundProjectionEnabled:!1,groundProjectionRadius:100,groundProjectionHeight:15,groundProjectionLevel:0,enableGroundCatcher:!1,groundCatcherHeight:0,globalIlluminationIntensity:1,environmentMode:`hdri`,gradientZenithColor:`#0077BE`,gradientHorizonColor:`#87CEEB`,gradientGroundColor:`#654321`,solidSkyColor:`#87CEEB`,skySunAzimuth:90,skySunElevation:20,skySunIntensity:15,skyRayleighDensity:.9,skyTurbidity:.8,skyMieAnisotropy:.76,skyPreset:`clearMorning`,cameraProjection:`perspective`,panoramaLonRange:[-180,180],panoramaLatRange:[-90,90],panoramaLevelHorizon:!0,enableDOF:!1,fov:55,focusDistance:.8,aperture:5.6,focalLength:50,apertureScale:1,anamorphicRatio:1,autoFocusMode:`auto`,afScreenPoint:{x:.5,y:.5},afSmoothingFactor:.15,enablePathTracer:!0,enableAccumulation:!0,pauseRendering:!1,maxSamples:60,bounces:3,transmissiveBounces:5,maxSubsurfaceSteps:8,maxTransparentBounces:32,useAdaptiveSampling:!0,noiseThreshold:.1,adaptiveMinSamples:8,adaptiveStopFraction:.9,usePixelFreeze:!0,pixelFreezeThreshold:.02,pixelFreezeStability:8,convergenceOverlay:!1,samplingTechnique:2,enableEmissiveTriangleSampling:!1,emissiveBoost:1,fireflyThreshold:3,wavefrontSortMaterials:!0,renderLimitMode:`frames`,renderTimeLimit:30,renderMode:0,enableAlphaShadows:!1,tilesHelper:!0,showLightHelper:!1,directionalLightIntensity:0,directionalLightColor:`#ffffff`,directionalLightPosition:[1,1,1],directionalLightAngle:0,filterStrength:1,edgeAtrousIterations:5,edgePhiLuminance:4,edgePhiNormal:64,edgePhiDepth:.1,enableOIDN:!1,oidnQuality:`fast`,continuousDenoise:!1,continuousDenoiseInterval:8,enableUpscaler:!1,upscalerScale:2,upscalerQuality:`fast`,upscalerHdr:!0,debugMode:0,debugThreshold:100,debugModel:0,enableBloom:!1,bloomStrength:.2,bloomRadius:.15,bloomThreshold:.85,interactionModeEnabled:!0,debugVisScale:100,denoiserStrategy:`none`,enableASVGF:!1,asvgfTemporalAlpha:.1,asvgfAtrousIterations:8,asvgfPhiColor:10,asvgfPhiNormal:128,asvgfPhiDepth:1,asvgfVarianceBoost:1,asvgfMaxAccumFrames:32,asvgfGradientStrength:1,asvgfGradientSigmaScale:2,asvgfGradientNoiseFloor:0,asvgfDebugMode:0,asvgfQualityPreset:`medium`,showAsvgfHeatmap:!1,nrdQualityPreset:`medium`,nrdDebugMode:0,autoExposure:!1,autoExposureKeyValue:.18,autoExposureMinExposure:.1,autoExposureMaxExposure:20,autoExposureAdaptSpeedBright:3,autoExposureAdaptSpeedDark:.5};t.fov,t.focusDistance,t.aperture,t.focalLength;const n={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826};function r(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function i(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}Math.min(typeof navigator<`u`&&navigator.hardwareConcurrency||4,6),t.maxSamples,t.bounces,t.renderMode,t.enableAlphaShadows,t.transmissiveBounces,t.maxSubsurfaceSteps;const a=Float64Array.from([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);function o(e,t){return e[t]*(e[t+5]*e[t+10]-e[t+6]*e[t+9])-e[t+4]*(e[t+1]*e[t+10]-e[t+2]*e[t+9])+e[t+8]*(e[t+1]*e[t+6]-e[t+2]*e[t+5])}function s(e,t,n){let r=o(e,t);if(!Number.isFinite(r)||Math.abs(r)<1e-20)return n.set(a),n;let i=1/r;return n[0]=(e[t+5]*e[t+10]-e[t+6]*e[t+9])*i,n[1]=(e[t+2]*e[t+9]-e[t+1]*e[t+10])*i,n[2]=(e[t+1]*e[t+6]-e[t+2]*e[t+5])*i,n[3]=0,n[4]=(e[t+6]*e[t+8]-e[t+4]*e[t+10])*i,n[5]=(e[t]*e[t+10]-e[t+2]*e[t+8])*i,n[6]=(e[t+2]*e[t+4]-e[t]*e[t+6])*i,n[7]=0,n[8]=(e[t+4]*e[t+9]-e[t+5]*e[t+8])*i,n[9]=(e[t+1]*e[t+8]-e[t]*e[t+9])*i,n[10]=(e[t]*e[t+5]-e[t+1]*e[t+4])*i,n[11]=0,n[12]=-(n[0]*e[t+12]+n[4]*e[t+13]+n[8]*e[t+14]),n[13]=-(n[1]*e[t+12]+n[5]*e[t+13]+n[9]*e[t+14]),n[14]=-(n[2]*e[t+12]+n[6]*e[t+13]+n[10]*e[t+14]),n[15]=1,n}function c(e,t){for(let n=0;n<16;n++)if(e[t+n]!==a[n])return!1;return!0}const l=e=>e<32?e:32,u=new Float64Array(16);var d=class e{constructor(){this._flatBuffer=null,this._flatBufferCapacity=0,this._binCounts=new Int32Array(96),this._binBounds=new Float64Array(576),this._binSuffix=new Float64Array(32),this._binSuffixCount=new Int32Array(32),this._order=null,this._stackI=null,this._stackB=null,this._stackFrames=0,this._sortScratch=[],this._suffix=null,this._bounds=new Float64Array(12),this._extent=new Float64Array(3),this._cMin=new Float64Array(3)}static nodeCountFor(e){return e>0?e*2-1:0}releaseFlattenBuffer(){this._flatBuffer=null,this._flatBufferCapacity=0}build(t){let n=new Float64Array(t.count*6);t.writeWorldAABBs(n);let r=this.buildStructure(n,t.count);return e.fillLeaves(r.data,r.nodeCount,t),r}buildStructure(t,a){let o=e.nodeCountFor(a);if(a===0)return{data:new Float32Array,nodeCount:0};i(o,`TLAS node count`);let s=o*16;s>this._flatBufferCapacity&&(this._flatBuffer=new Float32Array(s),this._flatBufferCapacity=s);let c=this._flatBuffer,l=r(c);(!this._order||this._order.length<a)&&(this._order=new Int32Array(a));let u=this._order;for(let e=0;e<a;e++)u[e]=e;this._ensureStack(64);let d=0,f=0,p=0,m=a,h=this._bounds;this._rangeBounds(t,u,p,m,h,0);let g=h[0],_=h[1],v=h[2],y=h[3],b=h[4],x=h[5];for(;;){if(m-p===1){let e=f*16;l[e]=0,l[e+1]=u[p],c[e+2]=0,l[e+3]=n.BLAS_POINTER_LEAF}else{let e=this._partition(t,u,p,m,g,_,v,y,b,x),n=e-p,r=f+1,i=r+(n*2-1),a=f*16;c[a]=h[0],c[a+1]=h[1],c[a+2]=h[2],l[a+3]=r,c[a+4]=h[3],c[a+5]=h[4],c[a+6]=h[5],l[a+7]=i,c[a+8]=h[6],c[a+9]=h[7],c[a+10]=h[8],c[a+11]=0,c[a+12]=h[9],c[a+13]=h[10],c[a+14]=h[11],c[a+15]=0;let o=n<=m-e,s=o?0:6,S=o?6:0;d=this._push(d,o?i:r,o?e:p,o?m:e,h,S),f=o?r:i,o?m=e:p=e,g=h[s],_=h[s+1],v=h[s+2],y=h[s+3],b=h[s+4],x=h[s+5];continue}if(d===0)break;d--;let e=d*3,r=d*6;f=this._stackI[e],p=this._stackI[e+1],m=this._stackI[e+2],g=this._stackB[r],_=this._stackB[r+1],v=this._stackB[r+2],y=this._stackB[r+3],b=this._stackB[r+4],x=this._stackB[r+5]}return{data:c.subarray(0,s),nodeCount:o}}_push(e,t,n,r,i,a){e>=this._stackFrames&&this._ensureStack(this._stackFrames*2);let o=e*3,s=e*6;this._stackI[o]=t,this._stackI[o+1]=n,this._stackI[o+2]=r;for(let e=0;e<6;e++)this._stackB[s+e]=i[a+e];return e+1}_ensureStack(e){if(this._stackFrames>=e)return;let t=new Int32Array(e*3),n=new Float64Array(e*6);this._stackI&&(t.set(this._stackI),n.set(this._stackB)),this._stackI=t,this._stackB=n,this._stackFrames=e}static fillLeaves(t,i,a){let o=a.world,s=a.sourceMesh,c=a.tplBlasOffset,l=a.visible,u=a.tlasLeafIndex,d=r(t);for(let r=0;r<i;r++){let i=r*16;if(d[i+3]!==n.BLAS_POINTER_LEAF)continue;let a=d[i+1]&1073741823;d[i]=c[s[a]],t[i+2]=+!!l[a],e.writeLeafMatrix(t,d,i,o,a),u[a]=r}}static writeLeafMatrix(e,t,n,r,i){let a=u;s(r,i*16,a),e[n+4]=a[0],e[n+5]=a[4],e[n+6]=a[8],e[n+7]=a[12],e[n+8]=a[1],e[n+9]=a[5],e[n+10]=a[9],e[n+11]=a[13],e[n+12]=a[2],e[n+13]=a[6],e[n+14]=a[10],e[n+15]=a[14],t[n+1]=(i|(c(r,i*16)?1073741824:0))>>>0}_partition(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=0;if(u===2)d=n+1;else if(u<=8)d=n+(u>>1),this._insertionSortRange(e,t,n,r,this._widestCentroidAxis(e,t,n,r));else{if(d=this._binnedSplit(e,t,n,r,i,a,o,s,c,l),d>n&&d<r)return d;if(d=this._sweepSplit(e,t,n,r,i,a,o,s,c,l),!(d>n&&d<r)){let f=s-i,p=c-a,m=l-o,h=p>f&&p>m?1:m>f?2:0;this._sortRange(e,t,n,r,h),d=n+(u>>1)}}let f=this._bounds;return this._rangeBounds(e,t,n,d,f,0),this._rangeBounds(e,t,d,r,f,6),d}_binnedSplit(e,t,n,r,i,a,o,s,c,u){let d=this._surfaceArea(i,a,o,s,c,u);if(!(d>0)||!isFinite(d))return n;let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0;for(let i=n;i<r;i++){let n=t[i]*6,r=(e[n]+e[n+3])*.5,a=(e[n+1]+e[n+4])*.5,o=(e[n+2]+e[n+5])*.5;r<f&&(f=r),r>h&&(h=r),a<p&&(p=a),a>g&&(g=a),o<m&&(m=o),o>_&&(_=o)}let v=this._extent,y=this._cMin;v[0]=h-f,v[1]=g-p,v[2]=_-m,y[0]=f,y[1]=p,y[2]=m;let b=1/0,x=-1,S=-1,C=this._binCounts,w=this._binBounds,T=v[0]>1e-12,E=v[1]>1e-12,D=v[2]>1e-12;if(!T&&!E&&!D)return n;let O=l(r-n),k=T?O/v[0]:0,A=E?O/v[1]:0,j=D?O/v[2]:0;C.fill(0,0,O*3);for(let e=0;e<O*3;e++){let t=e*6;w[t]=w[t+1]=w[t+2]=1/0,w[t+3]=w[t+4]=w[t+5]=-1/0}for(let i=n;i<r;i++){let n=t[i]*6,r=e[n],a=e[n+1],o=e[n+2],s=e[n+3],c=e[n+4],l=e[n+5];for(let e=0;e<3;e++){let t=e===0?k:e===1?A:j;if(t===0)continue;let n=((e===0?(r+s)*.5:e===1?(a+c)*.5:(o+l)*.5)-y[e])*t|0;n<0?n=0:n>=O&&(n=O-1),n+=e*O,C[n]++;let i=n*6;r<w[i]&&(w[i]=r),a<w[i+1]&&(w[i+1]=a),o<w[i+2]&&(w[i+2]=o),s>w[i+3]&&(w[i+3]=s),c>w[i+4]&&(w[i+4]=c),l>w[i+5]&&(w[i+5]=l)}}for(let e=0;e<3;e++){if(!(v[e]>1e-12))continue;let t=e*O,n=this._binSuffix,r=this._binSuffixCount,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0,u=0;for(let e=O-1;e>=1;e--){let d=(t+e)*6;w[d]<i&&(i=w[d]),w[d+1]<a&&(a=w[d+1]),w[d+2]<o&&(o=w[d+2]),w[d+3]>s&&(s=w[d+3]),w[d+4]>c&&(c=w[d+4]),w[d+5]>l&&(l=w[d+5]),u+=C[t+e],n[e]=u?this._surfaceArea(i,a,o,s,c,l):0,r[e]=u}let f=1/0,p=1/0,m=1/0,h=-1/0,g=-1/0,_=-1/0,y=0;for(let i=1;i<O;i++){let a=(t+i-1)*6;if(w[a]<f&&(f=w[a]),w[a+1]<p&&(p=w[a+1]),w[a+2]<m&&(m=w[a+2]),w[a+3]>h&&(h=w[a+3]),w[a+4]>g&&(g=w[a+4]),w[a+5]>_&&(_=w[a+5]),y+=C[t+i-1],y===0||r[i]===0)continue;let o=1+(this._surfaceArea(f,p,m,h,g,_)*y+n[i]*r[i])/d;o<b&&(b=o,x=e,S=i)}}if(x<0)return n;let M=O/v[x],N=y[x],P=this._bounds;P[0]=P[1]=P[2]=P[6]=P[7]=P[8]=1/0,P[3]=P[4]=P[5]=P[9]=P[10]=P[11]=-1/0;let F=n,I=r-1;for(;F<=I;){let n=t[F]*6,r=((e[n+x]+e[n+3+x])*.5-N)*M|0;r<0?r=0:r>=O&&(r=O-1);let i=r<S?0:6;if(e[n]<P[i]&&(P[i]=e[n]),e[n+1]<P[i+1]&&(P[i+1]=e[n+1]),e[n+2]<P[i+2]&&(P[i+2]=e[n+2]),e[n+3]>P[i+3]&&(P[i+3]=e[n+3]),e[n+4]>P[i+4]&&(P[i+4]=e[n+4]),e[n+5]>P[i+5]&&(P[i+5]=e[n+5]),i===0)F++;else{let e=t[F];t[F]=t[I],t[I]=e,I--}}return F}_sweepSplit(e,t,n,r,i,a,o,s,c,l){let u=r-n,d=this._surfaceArea(i,a,o,s,c,l);if(!(d>0)||!isFinite(d))return n;let f=this._suffixBuffer(u),p=1/0,m=-1,h=-1;for(let i=0;i<3;i++){this._sortRange(e,t,n,r,i);let a=1/0,o=1/0,s=1/0,c=-1/0,l=-1/0,g=-1/0;for(let r=u-1;r>=1;r--){let i=t[n+r]*6;e[i]<a&&(a=e[i]),e[i+1]<o&&(o=e[i+1]),e[i+2]<s&&(s=e[i+2]),e[i+3]>c&&(c=e[i+3]),e[i+4]>l&&(l=e[i+4]),e[i+5]>g&&(g=e[i+5]);let u=r*6;f[u]=a,f[u+1]=o,f[u+2]=s,f[u+3]=c,f[u+4]=l,f[u+5]=g}let _=1/0,v=1/0,y=1/0,b=-1/0,x=-1/0,S=-1/0;for(let r=1;r<u;r++){let a=t[n+r-1]*6;e[a]<_&&(_=e[a]),e[a+1]<v&&(v=e[a+1]),e[a+2]<y&&(y=e[a+2]),e[a+3]>b&&(b=e[a+3]),e[a+4]>x&&(x=e[a+4]),e[a+5]>S&&(S=e[a+5]);let o=r*6,s=this._surfaceArea(_,v,y,b,x,S),c=this._surfaceArea(f[o],f[o+1],f[o+2],f[o+3],f[o+4],f[o+5]),l=1+(s*r+c*(u-r))/d;l<p&&(p=l,m=i,h=r)}}return m<0||h<=0?n:(m!==2&&this._sortRange(e,t,n,r,m),n+h)}_widestCentroidAxis(e,t,n,r){let i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let u=n;u<r;u++){let n=t[u]*6,r=(e[n]+e[n+3])*.5,d=(e[n+1]+e[n+4])*.5,f=(e[n+2]+e[n+5])*.5;r<i&&(i=r),r>s&&(s=r),d<a&&(a=d),d>c&&(c=d),f<o&&(o=f),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o;return d>u&&d>f?1:f>u?2:0}_insertionSortRange(e,t,n,r,i){let a=i,o=3+i;for(let i=n+1;i<r;i++){let r=t[i],s=e[r*6+a]+e[r*6+o],c=i-1;for(;c>=n&&e[t[c]*6+a]+e[t[c]*6+o]>s;)t[c+1]=t[c],c--;t[c+1]=r}}_sortRange(e,t,n,r,i){let a=r-n,o=this._sortScratch;o.length=a;for(let e=0;e<a;e++)o[e]=t[n+e];let s=i,c=3+i;o.sort((t,n)=>e[t*6+s]+e[t*6+c]-(e[n*6+s]+e[n*6+c]));for(let e=0;e<a;e++)t[n+e]=o[e]}_suffixBuffer(e){let t=e*6;return(!this._suffix||this._suffix.length<t)&&(this._suffix=new Float64Array(t)),this._suffix}_rangeBounds(e,t,n,r,i,a){let o=1/0,s=1/0,c=1/0,l=-1/0,u=-1/0,d=-1/0;for(let i=n;i<r;i++){let n=t[i]*6;e[n]<o&&(o=e[n]),e[n+1]<s&&(s=e[n+1]),e[n+2]<c&&(c=e[n+2]),e[n+3]>l&&(l=e[n+3]),e[n+4]>u&&(u=e[n+4]),e[n+5]>d&&(d=e[n+5])}i[a]=o,i[a+1]=s,i[a+2]=c,i[a+3]=l,i[a+4]=u,i[a+5]=d}_surfaceArea(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const f={silent:0,error:1,warn:2,info:3,debug:4},p=`info`,m=`rayzeeLogLevel`,h=`rayzeeLogNamespaces`,g=`color:#7c8494`,_=`color:inherit`;let v=null,y=null;function b(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function x(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function S(){if(v!==null)return v;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in f?(v=f[e],v):(v=f[b(m)]??f[p],v)}function C(){if(y!==null)return y;let e=globalThis.__RAYZEE_LOG_NS__??b(h);return y=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],y}function w(e,t){if(t<f.debug)return!0;let n=C();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function T(e,t,n){if(e>S()||!w(t,e))return;let r=e===f.error?console.error:e===f.warn?console.warn:console.log,i=`[${t}]`;typeof n[0]==`string`?r(`%c${i}%c ${n[0]}`,g,_,...n.slice(1)):r(`%c${i}`,g,...n)}const E={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${E.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},D={levels:f,setLevel(e){return e in f?(globalThis.__RAYZEE_LOG_LEVEL__=e,v=f[e],x(m,e===p?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(f).join(`, `)}`),this.getLevel())},getLevel(){let e=S();return Object.keys(f).find(t=>f[t]===e)},isEnabled(e){return(f[e]??f.debug)<=S()},only(...e){let t=e.flat().filter(Boolean);return y=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),x(h,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return v=null,y=null,this.getLevel()}};function O(e){return{namespace:e,error:(...t)=>T(f.error,e,t),warn:(...t)=>T(f.warn,e,t),info:(...t)=>T(f.info,e,t),debug:(...t)=>T(f.debug,e,t),isEnabled:e=>D.isEnabled(e),summary(t,n=[]){let r=n.filter(Boolean);if(r.length===0||!console.groupCollapsed){T(f.info,e,[t]),r.forEach(t=>T(f.debug,e,[t]));return}f.info>S()||((S()>=f.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,g,_),r.forEach(e=>console.log(e)),console.groupEnd())}}}function k(e){e&&e in f&&(globalThis.__RAYZEE_LOG_LEVEL__=e,v=f[e])}const A=O(`bvh`);self.onmessage=function(e){let{aabbs:t,count:n,logLevel:r}=e.data;k(r);try{let e=performance.now(),{data:r,nodeCount:i}=new d().buildStructure(new Float64Array(t),n);A.debug(`TLAS ${E.n(i)} nodes in ${E.ms(performance.now()-e)}`),self.postMessage({tlasData:r,nodeCount:i},[r.buffer])}catch(e){A.error(`TLAS build failed:`,e),self.postMessage({error:e.message})}};",mc=typeof self<`u`&&self.Blob&&new Blob([`URL.revokeObjectURL(import.meta.url);`,pc],{type:`text/javascript;charset=utf-8`});function hc(e){let t;try{if(t=mc&&(self.URL||self.webkitURL).createObjectURL(mc),!t)throw``;let n=new Worker(t,{type:`module`,name:e?.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch{return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(pc),{type:`module`,name:e?.name})}}var gc=5e4,_c=It(`scene`),vc=class{constructor(e={}){this.config={useWorkers:!0,bvhDepth:30,maxLeafSize:4,verbose:!1,useFloat32Array:!0,textureQuality:`adaptive`,maxTextureSize:at.DEFAULT_MAX_TEXTURE_SIZE,enableTextureCache:!0,maxConcurrentTextureTasks:Math.min(navigator.hardwareConcurrency||4,6),maxSceneBytes:ss,enableTreeletOptimization:!1,treeletSize:7,treeletOptimizationPasses:1,treeletMinImprovement:.01,treeletComplexityThreshold:5e4,...e},this.triangleData=null,this.triangleFloats=null,this.triangleCount=0,this.materials=[],this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.roughnessMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this.spheres=[],this.bvhRoot=null,this.bvh=null,this.bvhData=null,this.bvhIndexChunks=null,this.bvhIndex=null,this.materialData=null,this.instanceTable=null,this._refitWorker=null,this._refitSharedBuffers=null,this._rebuildGeneration=0,this._pendingRebuilds=new Map,this.srgbBucketTextures=null,this.linearBucketTextures=null,this.emissiveTriangleData=null,this.emissiveTriangleCount=0,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this._initProcessors(),this.isProcessing=!1,this.processingStage=null,this.memory=new fs,this.memoryPreflight=null,this.performanceMetrics={textureCreationTime:0,geometryExtractionTime:0,bvhBuildTime:0,blasBuildTime:0,blasWorkerTime:0,tlasBuildTime:0,bvhAssembleTime:0,totalProcessingTime:0}}setMaxTextureSize(e){return this.config.maxTextureSize=e,this.textureCreator?.setMaxTextureSize(e)}_initProcessors(){this.geometryExtractor=new rc({issues:this.config.issues}),this.bvhBuilder=new no,this.bvhBuilder.maxLeafSize=this.config.maxLeafSize,this.bvhBuilder.setTreeletConfig({enabled:this.config.enableTreeletOptimization,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold}),this.textureCreator=new Ws({maxTextureSize:this.config.maxTextureSize,issues:this.config.issues}),this.emissiveTriangleBuilder=new cc,this.tlasBuilder=new Jo,this._tlasWorker=null,this._tlasWorkerFailed=!1}_log(e,t){t===void 0?_c.debug(e):_c.debug(e,t)}_preflightMemory(e){let t=this.config.maxSceneBytes??9663676416,n=this.geometryExtractor.surveyScene(e),r=us(n),i={...n,estimate:r,safeBytes:os,maxBytes:t,fits:r.total<=os};if(this.memoryPreflight=i,r.total<1610612736)return i;if(_c.debug(Y.list([`memory preflight: ${Y.mb(r.total)} estimated`,`triangles ${Y.mb(r.triangles)} · bvh ${Y.mb(r.bvh)} · geometry ${Y.mb(r.geometry)}`,`${Y.n(n.triangles)} tris · ${Y.n(n.placements)} placements`])),r.total>t){let e=`Scene needs about ${Y.mb(r.total)} of CPU memory, past the ${Y.mb(t)} a browser tab can hold — loading it would crash the tab rather than fail. Reduce the scene (it has ${Y.n(n.triangles)} triangles), or raise maxSceneBytes to try anyway.`;throw this.config.issues?.record(gs.SCENE_MEMORY_BUDGET,e,{...n,estimate:r,maxBytes:t}),Error(e)}return i.fits||this.config.issues?.warn(gs.SCENE_MEMORY_BUDGET,`Scene needs about ${Y.mb(r.total)} of CPU memory, above the ${Y.mb(os)} a fresh browser session can usually place. It may still load, but a long-running session will probably fail during BVH assembly; restarting the browser recovers the address space.`,{...n,estimate:r,safeBytes:os}),i}_checkAssemblyHeadroom(e){let t=e*64;if(t<1610612736)return!0;let n=ds(Math.ceil(t*cs),{shared:Xo});return this.memoryPreflight&&(this.memoryPreflight.assemblyProbed=n.placed),n.exhausted&&this.config.issues?.warn(gs.SCENE_MEMORY_BUDGET,`BVH assembly needs ${Y.mb(t)} but only ${Y.mb(n.placed)} could be allocated. Restarting the browser usually recovers the address space.`,{totalNodes:e,need:t,placeable:n.placed}),!n.exhausted}_liveMemoryParts(){let e=this.instanceTable,t={triangles:this.triangles?.byteLength??0,bvh:this.bvh?.byteLength??0,geometry:this._geometryBytes??this.memoryPreflight?.geometryBytes??0,placements:e?.world?.byteLength??0,blasScratch:0,orderMaps:0};if(e){for(let n of e.blasData.values())t.blasScratch+=n?.byteLength??0;for(let n of e.bvhToOriginal.values())t.orderMaps+=n?.byteLength??0;for(let n of e.originalToBvhMap.values())t.orderMaps+=n?.byteLength??0}return t}sceneBounds(){if(!this.bvh||this.bvh.recordCount===0)return null;let e=this.bvh.chunkFor(0),t=this.bvh.baseOf(0),n=[],r=[];for(let i=0;i<3;i++)n.push(Math.min(e[t+i],e[t+8+i])),r.push(Math.max(e[t+4+i],e[t+12+i]));return{min:n,max:r}}_sampleMemory(e){this.memory.sample(e,this._liveMemoryParts())}_logMemoryReport(){let{allocatedBytes:e,peakLiveBytes:t,byPhase:n}=this.memory;if(e===0)return;let r=Object.keys(n).filter(e=>n[e].allocated>0).map(e=>`${e} ${Y.mb(n[e].allocated)}`),i=this.memoryPreflight?.estimate?.total;_c.debug(Y.list([`memory: peak live ${Y.mb(t)}`,`allocated ${Y.mb(e)}`,i?`predicted ${Y.mb(i)}`:null,r.join(` · `)]))}async buildBVH(e){if(this.isProcessing)throw Error(`Already processing a scene. Call dispose() first.`);this.isProcessing=!0,this.processingStage=`init`,this.memory.reset(),this._geometryBytes=0,Qo(e=>this.memory.alloc(e));let t=new lc(e.name??``,{namespace:`scene`});try{this._reset(),this._log(`Starting scene processing`),this.memory.mark(`preflight`),this._preflightMemory(e),this.processingStage=`extraction`,this.memory.mark(`extraction`),t.start(`Geometry extraction`),await this._extractGeometry(e),t.end(`Geometry extraction`),this.performanceMetrics.geometryExtractionTime=t.getDuration(`Geometry extraction`),this._geometryBytes=Zs(e),this._sampleMemory(`after extraction`),this.processingStage=`bvh`,t.start(`BVH construction (worker)`),t.start(`Material textures (parallel)`);let n=!1,r=this._buildBVH().then(()=>t.end(`BVH construction (worker)`)),i=this._createMaterialTextures().then(()=>{t.end(`Material textures (parallel)`),n=!0});return await r,H({status:`Building light data...`,progress:77}),t.start(`Emissive extraction + Light BVH`),this._buildEmissiveData(),t.end(`Emissive extraction + Light BVH`),n||H({status:`Processing material textures...`,progress:80}),await i,this.performanceMetrics.bvhBuildTime=t.getDuration(`BVH construction (worker)`),this.performanceMetrics.textureCreationTime=t.getDuration(`Material textures (parallel)`),this.processingStage=`finalize`,t.start(`BVH data packing`),this.bvhRoot&&!this.bvh&&this._setBVHData(this.textureCreator.createBVHRawData(this.bvhRoot)),t.end(`BVH data packing`),this.spheres=this._createSpheres(),this.performanceMetrics.totalProcessingTime=performance.now()-t.totalStart,t.print(),this.processingStage=`complete`,H({status:`Scene data ready`,progress:85}),this}catch(e){throw this.processingStage=`error`,_c.error(`processing failed:`,e),H({status:`Error: ${e.message}`,failed:!0,progress:100}),e}finally{Qo(null),this._sampleMemory(`at ${this.processingStage}`),this._logMemoryReport(),this.isProcessing=!1}}async _extractGeometry(e){H({isLoading:!0,title:`Processing`,status:`Extracting geometry...`,progress:15}),await new Promise(e=>setTimeout(e,0)),this._log(`Extracting geometry`);let t=performance.now();try{let n=this.geometryExtractor.extract(e);this._setTriangleData(n.triangleData),this.triangleCount=it(n.triangleCount,`triangle count`),this.expandedTriangleCount=n.expandedTriangleCount??n.triangleCount,this.instanceSource=n.instanceSource||null,this.instanceMatrices=n.instanceMatrices||null,this.instanceCount=n.instanceCount||0,this.bakeInverse=n.bakeInverse||null,this._log(`Using Float32Array format: ${this.triangleCount} triangles, ${(this.triangles.byteLength/(1024*1024)).toFixed(2)}MB`),this.materials=n.materials,this.materialTriangleCounts=n.materialTriangleCounts,this.meshes=n.meshes,this.meshTriangleRanges=n.meshTriangleRanges,this.maps=n.maps,this.normalMaps=n.normalMaps,this.bumpMaps=n.bumpMaps,this.roughnessMaps=n.roughnessMaps,this.metalnessMaps=n.metalnessMaps,this.emissiveMaps=n.emissiveMaps,this.displacementMaps=n.displacementMaps,this.anisotropyMaps=n.anisotropyMaps,this.transmissionMaps=n.transmissionMaps,this.clearcoatMaps=n.clearcoatMaps,this.clearcoatRoughnessMaps=n.clearcoatRoughnessMaps,this.sheenColorMaps=n.sheenColorMaps,this.sheenRoughnessMaps=n.sheenRoughnessMaps,this.iridescenceMaps=n.iridescenceMaps,this.iridescenceThicknessMaps=n.iridescenceThicknessMaps,this.specularIntensityMaps=n.specularIntensityMaps,this.specularColorMaps=n.specularColorMaps,this.directionalLights=n.directionalLights,this.cameras=n.cameras;let r=performance.now()-t;this._log(`Geometry extraction complete (${r.toFixed(2)}ms)`,{triangleCount:this.triangleCount,materials:this.materials.length}),H({status:`Extracted ${this.triangleCount.toLocaleString()} triangles`,progress:25})}catch(e){throw _c.error(`geometry extraction failed:`,e),H({status:`Extraction error: ${e.message}`,failed:!0,progress:25}),e}}async _buildBVH(){if(H({status:`Building BVH...`,progress:25}),this.triangleCount===0)throw Error(`No triangles to build BVH from`);this._log(`Building two-level BVH (TLAS/BLAS)`),this.memory.mark(`blas`);let e=performance.now();try{let t=this.meshTriangleRanges;if(!t||t.length===0)throw Error(`No mesh triangle ranges available for TLAS/BLAS build`);let n=this.instanceCount>0,r=n?this.instanceCount:t.length,i=this.instanceSource,a=n?this.instanceMatrices:null,o=e=>n?i[e]:e;this.instanceTable=new Vo,this.instanceTable.allocate(r,t.length,a,n?i:null),this.instanceTable.tplBakeInverse=this.bakeInverse;let s=this.config.enableTreeletOptimization,c=[],l=[],u=new Map,d=new Map;for(let e=0;e<r;e++){let n=t[o(e)];if(!n||n.count===0)continue;let r=d.get(n.start);if(r!==void 0){u.set(e,r);continue}d.set(n.start,e),n.count>=2e5&&No(n.count)?l.push({m:e,range:n}):c.push({m:e,range:n})}let f={depth:this.config.bvhDepth,treeletOptimization:{enabled:s!==!1,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold},reinsertionOptimization:{enabled:this.bvhBuilder.enableReinsertionOptimization,batchSizeRatio:this.bvhBuilder.reinsertionBatchSizeRatio,maxIterations:this.bvhBuilder.reinsertionMaxIterations},maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,logLevel:zt()},p=c.length+l.length,m=0,h=()=>{m++,H({status:`Building BLAS ${m}/${p}...`,progress:25+Math.floor(m/p*45)})},g=this._buildBLASesWithPool(c,f,h),_=[],v=(async()=>{for(let{m:e,range:t}of l){let n=await Ao(this.triangles.copyOf(t.start,t.count),this.config.bvhDepth,null,{maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,...f});n.reorderedTriangles&&(this.triangles.setRecords(t.start,n.reorderedTriangles),delete n.reorderedTriangles),_.push({m:e,range:t,result:n}),h()}})(),[y]=await Promise.all([g,v]),b={sah:0,objMed:0,spatMed:0,failed:0,treeletsImproved:0,treeletsProcessed:0};for(let{m:e,range:t,result:r}of[...y,..._]){let i=r.splitStats;i&&(b.sah+=i.sahSplits??0,b.objMed+=i.objectMedianSplits??0,b.spatMed+=i.spatialMedianSplits??0,b.failed+=i.failedSplits??0,b.treeletsImproved+=i.treeletsImproved??0,b.treeletsProcessed+=i.treeletsProcessed??0,this.performanceMetrics.blasWorkerTime+=i.totalBuildTime??0),this.instanceTable.setEntry({meshIndex:e,blasNodeCount:r.bvhData.length/16,triOffset:t.start,triCount:t.count,originalToBvhMap:r.originalToBvh||null,bvhData:r.bvhData,matrixWorld:n?a:this.meshes?.[e]?.matrixWorld?.elements??null,matrixOffset:n?e*16:0,expandedStart:t.expandedStart,sourceMesh:o(e)})}for(let[e,r]of u)this.instanceTable.setAlias(e,r,n?a:this.meshes?.[e]?.matrixWorld?.elements??null,t[o(e)].expandedStart,o(e),n?e*16:0);H({status:`Built all BLASes`,progress:70}),this.performanceMetrics.blasBuildTime=performance.now()-e,H({status:`Building TLAS...`,progress:72}),this._sampleMemory(`BLASes built`),this.memory.mark(`tlas`);let x=performance.now(),S=this.instanceTable;this.instanceTable.computeAABBs(this.triangles),this.instanceTable.assignOffsets(Jo.nodeCountFor(S.count));let C=this.instanceTable.totalNodeCount,w=await this._buildTLAS(S);this.performanceMetrics.tlasBuildTime=performance.now()-x,this.memory.mark(`assemble`);let T=performance.now();this._checkAssemblyHeadroom(C),this._setBVHData(es.lazy(C,16,Float32Array,void 0,Xo)),this.bvh.setRecords(0,w),w=null,this.tlasBuilder.releaseFlattenBuffer();let E=Math.max(1,Math.ceil(S.templateCount/32));for(let e=0;e<S.templateCount;e++){let t=S.blasData.get(e);if(!t)continue;let n=S.tplBlasOffset[e];this.bvh.setRecords(n,t),this._offsetBLASInPlace(n,t.length/16,n,S.tplTriOffset[e]),S.blasData.delete(e),e%E===0&&this._sampleMemory(`assembling ${e}/${S.templateCount}`)}this._setBVHData(this.bvh.materializeAll()),this._buildBvhToOriginalMaps(),this.performanceMetrics.bvhAssembleTime=performance.now()-T,S.originalToBvhMap.clear(),S.blasData.clear(),this.bvhRoot=!0,this._disposeRefitWorker();let D=performance.now()-e;_c.debug(Y.list([`${Y.n(S.setCount)} BLASes + TLAS`,`${Y.n(this.bvh.recordCount)} nodes`,`SAH ${Y.n(b.sah)} · objMed ${b.objMed} · spatMed ${b.spatMed} · failed ${b.failed}`,b.treeletsProcessed?`treelets ${b.treeletsImproved}/${b.treeletsProcessed} improved`:null,Y.ms(D)])),H({status:`BVH construction complete`,progress:75})}catch(e){throw _c.error(`BVH build failed:`,e),H({status:`BVH error: ${e.message}`,failed:!0,progress:75}),e}}_offsetBLASInPlace(e,t,n,r){let i=this.bvhIndexChunks;for(let a=0;a<t;a++){let t=e+a,o=i.chunkFor(t),s=i.baseOf(t);o[s+3]===nt.TRIANGLE_LEAF?o[s]+=r:(o[s+3]+=n,o[s+7]+=n)}}_buildBLASesWithPool(e,t,n){if(e.length===0)return Promise.resolve([]);let r=Math.min(e.length,this.config.maxConcurrentTextureTasks||4),i=[],a=0,o=0;return new Promise((s,c)=>{let l=[],u=n=>{if(a>=e.length){n.terminate(),l.splice(l.indexOf(n),1),l.length===0&&s(i);return}let{m:r,range:o}=e[a++],c=this.triangles.copyOf(o.start,o.count),u=o.count,d=u<=500?{...t.treeletOptimization,enabled:!1}:t.treeletOptimization;n._currentTask={m:r,range:o},n.postMessage({triangleData:c.buffer,triangleByteOffset:c.byteOffset,triangleByteLength:c.byteLength,triangleCount:u,depth:t.depth,reportProgress:!1,sharedReorderBuffer:null,treeletOptimization:d,reinsertionOptimization:t.reinsertionOptimization,maxLeafSize:t.maxLeafSize,numBins:t.numBins,maxBins:t.maxBins,minBins:t.minBins,logLevel:t.logLevel},[c.buffer])},d=(e,t)=>{let r=t.data;if(r.error){l.forEach(e=>e.terminate()),c(Error(r.error));return}if(r.progress!==void 0)return;let{m:a,range:s}=e._currentTask;r.triangles&&this.triangles.setRecords(s.start,r.triangles),i.push({m:a,range:s,result:{bvhData:r.bvhData,originalToBvh:r.originalToBvh||null,splitStats:r.treeletStats||null}}),o++,n?.(o),u(e)};(async()=>{for(let e=0;e<r;e++){let e;try{e=new So}catch(e){c(e);return}e.onmessage=t=>d(e,t),e.onerror=e=>{l.forEach(e=>e.terminate()),c(e)},l.push(e),u(e)}})().catch(c)})}_buildBvhToOriginalMaps(){let e=this.instanceTable;for(let t=0;t<e.count;t++){if(!e.isSet[t]||!e.isOwner(t))continue;let n=e.sourceMesh[t],r=e.tplTriCount[n],i=e.originalToBvhMap.get(n),a=new Uint32Array(r);if(i)for(let e=0;e<r;e++)a[i[e]]=e;else for(let e=0;e<r;e++)a[e]=e;e.bvhToOriginal.set(n,a),e.originalToBvhMap.delete(n)}}async _createMaterialTextures(){this._log(`Creating material textures (parallel with BVH)`);try{let{srgbLists:e,linearLists:t,remap:n}=this._bucketTextures();this._remapMaterialTextureIndices(n),this.materials?.length&&(this.materialData=this.textureCreator.createMaterialRawData(this.materials));let i=(e,t)=>e.length===0?Promise.resolve(null):this.textureCreator.createTexturesToDataTexture(e,{srgbPool:t}).then(e=>(e&&t&&(e.colorSpace=r.SRGBColorSpace),e)),[a,o]=await Promise.all([Promise.all(e.map(e=>i(e,!0))),Promise.all(t.map(e=>i(e,!1)))]);this.srgbBucketTextures=a,this.linearBucketTextures=o,this._log(`Material textures complete`,{materialData:!!this.materialData,srgbBuckets:a.map(e=>e?`${e.image.width}x${e.image.height}x${e.image.depth}`:`-`).join(`,`),linearBuckets:o.map(e=>e?`${e.image.width}x${e.image.height}x${e.image.depth}`:`-`).join(`,`)})}catch(e){throw _c.error(`texture creation failed:`,e),e}}_bucketTextures(){let e=this.config.maxTextureSize,t=at.MATERIAL_BUCKET_COUNT,n=at.BUCKET_LAYER_STRIDE,r=e=>{let t=new Set,n=[];for(let r of e)for(let e of r||[]){if(!e?.image)continue;let r=e.source?.uuid??e.uuid;t.has(r)||(t.add(r),n.push({width:e.image.width,height:e.image.height}))}return n},i=[this.maps,this.emissiveMaps,this.sheenColorMaps,this.specularColorMaps],a=[this.normalMaps,this.bumpMaps,this.roughnessMaps,this.metalnessMaps,this.displacementMaps,this.anisotropyMaps,this.transmissionMaps,this.clearcoatMaps,this.clearcoatRoughnessMaps,this.sheenRoughnessMaps,this.iridescenceMaps,this.iridescenceThicknessMaps,this.specularIntensityMaps],o=mt(r(i),e,t),s=mt(r(a),e,t);this._srgbBucketShapes=o,this._linearBucketShapes=s;let c=Array.from({length:t},()=>[]),l=Array.from({length:t},()=>[]),u=Array.from({length:t},()=>new Map),d=Array.from({length:t},()=>new Map);this._srgbTexPacked=new Map,this._linearTexPacked=new Map;let f=!1,p=!1,m=(e,t,r,i,a)=>{if(!e)return-1;if(!e.image)return p||this.config.issues?.record(gs.TEXTURE_BUILD_FAILED,`a material map had not finished decoding when the scene was packed; it renders untextured`,{texture:e.name||e.source?.uuid||e.uuid}),p=!0,-1;let o=ht(e.image.width,e.image.height,a),s=e.source?.uuid??e.uuid,c=r[o].get(s);if(c!==void 0)return gt(o,c);if(t[o].length>=n)return _c.warn(`texture bucket ${o} full (${n}); dropping a map`),f||this.config.issues?.record(gs.TEXTURE_LIMIT_EXCEEDED,`texture bucket ${o} full (${n} layers); the rest render untextured`,{bucket:o,limit:n}),f=!0,-1;t[o].push(e);let l=t[o].length-1;r[o].set(s,l);let u=gt(o,l);return i.set(s,u),u},h=(e,t,n,r,i)=>(e||[]).map(e=>m(e,t,n,r,i));return{srgbLists:c,linearLists:l,remap:{albedo:h(this.maps,c,u,this._srgbTexPacked,o),emissive:h(this.emissiveMaps,c,u,this._srgbTexPacked,o),normal:h(this.normalMaps,l,d,this._linearTexPacked,s),bump:h(this.bumpMaps,l,d,this._linearTexPacked,s),roughness:h(this.roughnessMaps,l,d,this._linearTexPacked,s),metalness:h(this.metalnessMaps,l,d,this._linearTexPacked,s),displacement:h(this.displacementMaps,l,d,this._linearTexPacked,s),anisotropy:h(this.anisotropyMaps,l,d,this._linearTexPacked,s),transmission:h(this.transmissionMaps,l,d,this._linearTexPacked,s),clearcoat:h(this.clearcoatMaps,l,d,this._linearTexPacked,s),clearcoatRoughness:h(this.clearcoatRoughnessMaps,l,d,this._linearTexPacked,s),sheenColor:h(this.sheenColorMaps,c,u,this._srgbTexPacked,o),sheenRoughness:h(this.sheenRoughnessMaps,l,d,this._linearTexPacked,s),iridescence:h(this.iridescenceMaps,l,d,this._linearTexPacked,s),iridescenceThickness:h(this.iridescenceThicknessMaps,l,d,this._linearTexPacked,s),specularIntensity:h(this.specularIntensityMaps,l,d,this._linearTexPacked,s),specularColor:h(this.specularColorMaps,c,u,this._srgbTexPacked,o)}}}_remapMaterialTextureIndices(e){let t=(e,t)=>e>=0&&e<t.length?t[e]:-1;for(let n of this.materials)n.map=t(n.map,e.albedo),n.emissiveMap=t(n.emissiveMap,e.emissive),n.normalMap=t(n.normalMap,e.normal),n.bumpMap=t(n.bumpMap,e.bump),n.roughnessMap=t(n.roughnessMap,e.roughness),n.metalnessMap=t(n.metalnessMap,e.metalness),n.displacementMap=t(n.displacementMap,e.displacement),n.anisotropyMap=t(n.anisotropyMap,e.anisotropy),n.transmissionMap=t(n.transmissionMap,e.transmission),n.clearcoatMap=t(n.clearcoatMap,e.clearcoat),n.clearcoatRoughnessMap=t(n.clearcoatRoughnessMap,e.clearcoatRoughness),n.sheenColorMap=t(n.sheenColorMap,e.sheenColor),n.sheenRoughnessMap=t(n.sheenRoughnessMap,e.sheenRoughness),n.iridescenceMap=t(n.iridescenceMap,e.iridescence),n.iridescenceThicknessMap=t(n.iridescenceThicknessMap,e.iridescenceThickness),n.specularIntensityMap=t(n.specularIntensityMap,e.specularIntensity),n.specularColorMap=t(n.specularColorMap,e.specularColor)}_buildEmissiveData(){this.emissiveTriangleCount=this.emissiveTriangleBuilder.extractEmissiveTriangles(this.triangles,this.materials,this.triangleCount,this.instanceTable??null),this.emissiveTriangleData=this.emissiveTriangleBuilder.createEmissiveRawData(),this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower,this._log(`Emissive triangle extraction complete`,this.emissiveTriangleBuilder.getStats()),this.emissiveTriangleBuilder.buildLightBVH(),this.lightBVHNodeData=this.emissiveTriangleBuilder.lightBVHNodeData,this.lightBVHNodeCount=this.emissiveTriangleBuilder.lightBVHNodeCount,this.emissiveTriangleData=this.emissiveTriangleBuilder.emissiveTriangleData||this.emissiveTriangleData,this.emissiveBitTrailMap=this.emissiveTriangleBuilder.emissiveBitTrailMap,this.emissiveTriangleCount=this.emissiveTriangleBuilder.emissiveCount,this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower}_createSpheres(){return[]}_reset(){this._disposeTextures(),this.triangles=[],this._setTriangleData(null),this.triangleCount=0,this.materials=[],this.meshTriangleRanges=null,this.maps=[],this.normalMaps=[],this.bumpMaps=[],this.roughnessMaps=[],this.metalnessMaps=[],this.emissiveMaps=[],this.displacementMaps=[],this.anisotropyMaps=[],this.transmissionMaps=[],this.clearcoatMaps=[],this.clearcoatRoughnessMaps=[],this.sheenColorMaps=[],this.sheenRoughnessMaps=[],this.iridescenceMaps=[],this.iridescenceThicknessMaps=[],this.specularIntensityMaps=[],this.specularColorMaps=[],this.directionalLights=[],this.cameras=[],this.spheres=[],this.bvhRoot=null,this.bvh=null,this.bvhData=null,this.bvhIndexChunks=null,this.bvhIndex=null,this.instanceTable=null,this.lightBVHNodeData=null,this.lightBVHNodeCount=0,this.emissiveBitTrailMap=null,this.performanceMetrics={textureCreationTime:0,geometryExtractionTime:0,bvhBuildTime:0,blasBuildTime:0,blasWorkerTime:0,tlasBuildTime:0,bvhAssembleTime:0,totalProcessingTime:0}}_disposeTextures(){this._disposeBucketTextures()}_disposeBucketTextures(){for(let e of[`srgbBucketTextures`,`linearBucketTextures`]){let t=this[e];if(t){for(let n of t)if(n&&typeof n.dispose==`function`)try{n.dispose()}catch(t){_c.warn(`error disposing ${e}:`,t)}this[e]=null}}}async rebuildMaterials(e){if(this.isProcessing)throw Error(`Already processing. Cannot rebuild materials during processing.`);this._log(`Rebuilding materials and textures`);let t=performance.now();try{this.isProcessing=!0;let n=this.geometryExtractor.extractMaterialsOnly(e);this._disposeMaterialTextures(),this.materials=n.materials,this.meshes=n.meshes,this.maps=n.maps,this.normalMaps=n.normalMaps,this.bumpMaps=n.bumpMaps,this.roughnessMaps=n.roughnessMaps,this.metalnessMaps=n.metalnessMaps,this.emissiveMaps=n.emissiveMaps,this.displacementMaps=n.displacementMaps,await this._createMaterialTextures();let r=performance.now()-t;return this._log(`Material rebuild complete (${r.toFixed(2)}ms)`,{materials:this.materials.length,textures:this.maps.length}),this}catch(e){throw _c.error(`material rebuild failed:`,e),e}finally{this.isProcessing=!1}}_disposeMaterialTextures(){this._disposeBucketTextures(),this.textureCreator&&this.textureCreator.textureCache&&(this.textureCreator.textureCache.dispose(),this.textureCreator.textureCache=new this.textureCreator.textureCache.constructor)}getStatistics(){let e={triangleCount:this.triangleCount,materialCount:this.materials.length,textureCount:this.maps.length,lightCount:this.directionalLights.length,cameraCount:this.cameras.length,processingComplete:this.processingStage===`complete`,hasBVH:!!this.bvhRoot,hasTextures:!!this.materialData&&!!this.bvh,useFloat32Array:this.config.useFloat32Array,triangleDataSize:this.triangles?(this.triangles.byteLength/(1024*1024)).toFixed(2)+`MB`:`0MB`};return this.performanceMetrics.totalProcessingTime>0&&(e.performance={totalTime:this.performanceMetrics.totalProcessingTime,textureTime:this.performanceMetrics.textureCreationTime,bvhTime:this.performanceMetrics.bvhBuildTime,extractionTime:this.performanceMetrics.geometryExtractionTime,texturePercentage:(this.performanceMetrics.textureCreationTime/this.performanceMetrics.totalProcessingTime*100).toFixed(1)+`%`}),this.textureCreator&&this.textureCreator.capabilities&&(e.textureCapabilities=this.textureCreator.capabilities),e}updateConfig(e){Object.assign(this.config,e),this.bvhBuilder&&(this.bvhBuilder.maxLeafSize=this.config.maxLeafSize,this.bvhBuilder.setTreeletConfig({enabled:this.config.enableTreeletOptimization,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold})),this._log(`Configuration updated`,this.config)}_adoptSharedChunks(e,t){let n=this[e];if(n.shared)return;let r=n.chunks.map(e=>{let n=new t(new SharedArrayBuffer(e.byteLength));return n.set(e),n}),i=es.adopt(r,n.recordCount,n.lanesPerRecord,n.recordsPerChunk);e===`bvh`?this._setBVHData(i):this._setTriangleData(i)}_meshSource(e,t){if(e==null)return null;let n=this.instanceTable;if(typeof e==`function`)return r=>{let i=n.sourceMesh[r],a=e(i,n.triCountOf(r)),o=n.triCountOf(r)*9;if(a&&a.length!==o)throw Error(`SceneProcessor: ${t}s for mesh ${i} must be ${o} floats (${n.triCountOf(r)} triangles × 9), got ${a.length}.`);return a??null};let r=(this.expandedTriangleCount??this.triangleCount)*9;if(e.length!==r)throw Error(`SceneProcessor: expected ${r} ${t} floats (${r/9} triangles × 9, full scene), got ${e.length}. Pass a per-mesh callback instead to avoid building one array for the whole scene.`);return t=>{let r=n.expandedStartOf(t)*9;return e.subarray(r,r+n.triCountOf(t)*9)}}async refitBVH(e,t){if(!this.bvh||!this.triangles||!this.instanceTable)throw Error(`No BVH data available for refit. Run buildBVH() first.`);let n=this._meshSource(e,`position`),r=this._meshSource(t,`normal`);if(!n)throw Error(`SceneProcessor.refitBVH: positions are required.`);if(this._refitWorker||=new fc,!this._refitSharedBuffers){this._adoptSharedChunks(`bvh`,Float32Array),this._adoptSharedChunks(`triangles`,Uint32Array);let e=this.bvh.chunks.map(e=>e.buffer),t=this.triangles.chunks.map(e=>e.buffer);this._refitSharedBuffers={bvhBufs:e,triBufs:t},this._refitWorker.postMessage({type:`init`,sharedBvhBufs:e,bvhRecordCount:this.bvh.recordCount,bvhRecordsPerChunk:this.bvh.recordsPerChunk,sharedTriBufs:t,triRecordCount:this.triangles.recordCount,triLanesPerRecord:this.triangles.lanesPerRecord,triRecordsPerChunk:this.triangles.recordsPerChunk})}let i=this.instanceTable;for(let e=0;e<i.count;e++){if(!i.isSet[e]||!i.isOwner(e))continue;let t=n(e);if(t&&(this._updateMeshTrianglePositions(e,t),r)){let t=r(e);t&&this._patchMeshSmoothNormals(e,t)}}return new Promise((e,t)=>{this._refitWorker.onmessage=n=>{let r=n.data;r.type===`refitComplete`?e({refitTimeMs:r.refitTimeMs}):r.type===`error`&&t(Error(r.error))},this._refitWorker.postMessage({type:`refit`})})}_patchSmoothNormals(e){let t=this.instanceTable;if(t)for(let n=0;n<t.count;n++){if(!t.isSet[n]||!t.isOwner(n))continue;let r=e(n);r&&this._patchMeshSmoothNormals(n,r)}}_placementOf(e){return this.instanceTable?.placementRunOf(e)?.start??-1}refitBLASes(e,t,n){if(!this.instanceTable||!this.bvh||!this.triangles)throw Error(`No TLAS/BLAS data available. Run buildBVH() first.`);let r=this._meshSource(t,`position`),i=this._meshSource(n,`normal`);if(!r)throw Error(`SceneProcessor.refitBLASes: positions are required.`);let a=performance.now();this._blasRefitter||=new yo;let o=this.instanceTable;for(let t of e){let e=this._placementOf(t);if(e<0||!o.isSet[e])continue;if(!o.isOwner(e)){let n=o.tplOwner[o.sourceMesh[e]];this.config.issues?.record(gs.REFIT_SHARED_GEOMETRY,`mesh ${t} shares its triangles with another placement; deforming it would move every copy, so it was skipped`,{meshIndex:t,owner:o.sourceMesh[n]??n});continue}let n=r(e);if(n){if(this._updateMeshTrianglePositions(e,n),i){let t=i(e);t&&this._patchMeshSmoothNormals(e,t)}this._blasRefitter.refitRange(this.bvh,this.triangles,o.blasOffsetOf(e),o.blasNodeCountOf(e)),this.instanceTable.recomputeAABB(e,this.bvh,this.triangles)}}return this._refitTLAS(),{refitTimeMs:performance.now()-a}}updateMeshTransforms(e){if(!this.instanceTable||!this.bvh)throw Error(`No TLAS/BLAS data available. Run buildBVH() first.`);let t=performance.now(),n=this.instanceTable,r=this._transformScratch??=new Float32Array(16),i=0;for(let t of e){let e=this.meshes?.[t],a=n.placementRunOf(t);if(!e||!a)continue;e.updateMatrixWorld(!0);let o=e.matrixWorld.elements,s=e.isInstancedMesh?this._ownInstanceMatrices(e):null,c=n.tplBakeInverse?.get(n.sourceMesh[a.start])??null;for(let e=0;e<a.count;e++){let t=a.start+e;n.isSet[t]&&(s?(Lo(o,s,e*16,r),n.setPlacementMatrix(t,r)):c?(Lo(o,c,0,r),n.setPlacementMatrix(t,r)):n.setPlacementMatrix(t,o),this._writeLeafMatrix(t),i++)}}return this._refitTLAS(),{refitTimeMs:performance.now()-t,placements:i}}_ownInstanceMatrices(e){let t=e.instanceMatrix;return t?.array?(t.array.buffer===this.instanceTable.world.buffer&&(t.array=t.array.slice(),t.needsUpdate=!0),t.array):null}_writeLeafMatrix(e){let t=this.instanceTable.tlasLeafIndex[e];t<0||Jo.writeLeafMatrix(this.bvh.chunkFor(t),this.bvhIndexChunks.chunkFor(t),this.bvh.baseOf(t),this.instanceTable.world,e)}computeTLASDirtyRange(){return{offset:0,count:this.instanceTable.tlasNodeCount*16}}computeBLASDirtyRanges(e){let t=K.FLOATS_PER_TRIANGLE,n=[],r=[];for(let i of e){let e=this.instanceTable,a=this._placementOf(i);a<0||!e.isSet[a]||(n.push({offset:e.triOffsetOf(a)*t,count:e.triCountOf(a)*t}),r.push({offset:e.blasOffsetOf(a)*16,count:e.blasNodeCountOf(a)*16}))}return r.push({offset:0,count:this.instanceTable.tlasNodeCount*16}),{triRanges:n,bvhRanges:r}}uploadToPathTracer(e,t,n,r){return this.triangles?(e.setTriangleData(this.triangles,this.triangleCount),this.bvh?(e.setBVHData(this.bvh),e.setInstanceTable(this.instanceTable),this.materialData?e.materialData.setMaterialData(this.materialData):_c.warn(`no material data, using defaults`),r&&e.environment.setEnvironmentTexture(r),e.materialData.setMaterialTextures({srgbBuckets:this.srgbBucketTextures,linearBuckets:this.linearBucketTextures}),e.materialData.setTexturePackMaps?.(this._srgbTexPacked,this._linearTexPacked),this.emissiveTriangleData&&e.setEmissiveTriangleData(this.emissiveTriangleData,this.emissiveTriangleCount,this.emissiveTotalPower,this.emissiveBitTrailMap),this.lightBVHNodeData&&e.setLightBVHData(this.lightBVHNodeData,this.lightBVHNodeCount),t.transferSceneLights(n),!0):(_c.error(`failed to get BVH data`),!1)):(_c.error(`failed to get triangle data`),!1)}updateMaterialEmissive(e,t,n){if(!this.emissiveTriangleBuilder)return null;let r=this.materials[e];return!r||(t===`emissive`?r.emissive=n:t===`emissiveIntensity`&&(r.emissiveIntensity=n),!this.emissiveTriangleBuilder.updateMaterialEmissive(e,r,this.triangles,this.materials,this.triangleCount))?null:this._collectEmissivePayload()}rebuildEmissiveForVisibility(e,t=!1){return!this.emissiveTriangleBuilder||!this.emissiveTriangleBuilder.setHiddenMeshes(e)&&!t?null:this._collectEmissivePayload()}_collectEmissivePayload(){return this.emissiveTriangleBuilder.buildLightBVH(),this.lightBVHNodeData=this.emissiveTriangleBuilder.lightBVHNodeData,this.lightBVHNodeCount=this.emissiveTriangleBuilder.lightBVHNodeCount,this.emissiveTriangleData=this.emissiveTriangleBuilder.emissiveTriangleData,this.emissiveBitTrailMap=this.emissiveTriangleBuilder.emissiveBitTrailMap,this.emissiveTriangleCount=this.emissiveTriangleBuilder.emissiveCount,this.emissiveTotalPower=this.emissiveTriangleBuilder.totalEmissivePower,{rawData:this.emissiveTriangleData,emissiveCount:this.emissiveTriangleCount,totalPower:this.emissiveTotalPower,bitTrailMap:this.emissiveBitTrailMap,lightBVHNodeData:this.lightBVHNodeData,lightBVHNodeCount:this.lightBVHNodeCount}}async _buildTLAS(e){let t=e.count;if(t>=gc&&!this._tlasWorkerFailed)try{let n=new Float64Array(t*6);e.writeWorldAABBs(n);let{tlasData:r,nodeCount:i}=await this._runTLASWorker(n,t);return Jo.fillLeaves(r,i,e),r}catch(e){this._tlasWorkerFailed=!0,_c.warn(`TLAS worker unavailable (${e.message}); building on the main thread`)}return this.tlasBuilder.build(e).data}_runTLASWorker(e,t){this._tlasWorker||=new hc;let n=this._tlasWorker;return new Promise((r,i)=>{let a=e=>{n.removeEventListener(`message`,a),n.removeEventListener(`error`,o),e.data?.error?i(Error(e.data.error)):r(e.data)},o=e=>{n.removeEventListener(`message`,a),n.removeEventListener(`error`,o),i(Error(e.message||`worker error`))};n.addEventListener(`message`,a),n.addEventListener(`error`,o),n.postMessage({aabbs:e.buffer,count:t,logLevel:zt()},[e.buffer])})}_setBVHData(e){let t=e?e instanceof es?e:es.adopt([e],e.length/16,16,e.length/16):null;this.bvh=t,this.bvhIndexChunks=t?t.viewAs(Uint32Array):null,this.bvhData=t?t.single:null,this.bvhIndex=this.bvhIndexChunks?this.bvhIndexChunks.single:null}_setTriangleData(e){let t=K.FLOATS_PER_TRIANGLE,n=e?e instanceof es?e:es.adopt([e],e.length/t,t,e.length/t):null;this.triangles=n,this.triangleFloatChunks=n?n.viewAs(Float32Array):null,this.triangleData=n?n.single:null,this.triangleFloats=this.triangleFloatChunks?this.triangleFloatChunks.single:null}_updateMeshTrianglePositions(e,t){let n=K.POSITION_A_OFFSET,r=K.POSITION_B_OFFSET,i=K.POSITION_C_OFFSET,a=K.NORMAL_A_PACKED_OFFSET,o=K.NORMAL_B_PACKED_OFFSET,s=K.NORMAL_C_PACKED_OFFSET,c=this.triangles,l=this.triangleFloatChunks,u=this.instanceTable,d=u.bvhToOriginalOf(e),f=u.triOffsetOf(e),p=u.triCountOf(e),m=u.matrixInverseOf(e),h=Ro(m);for(let e=0;e<p;e++){let u=d?d[e]:e,p=f+e,g=l.chunkFor(p),_=c.chunkFor(p),v=c.baseOf(p),y=u*9,b=t[y],x=t[y+1],S=t[y+2],C=t[y+3],w=t[y+4],T=t[y+5],E=t[y+6],D=t[y+7],O=t[y+8];if(!h){let e=(e,t,n)=>m[0]*e+m[4]*t+m[8]*n+m[12],t=(e,t,n)=>m[1]*e+m[5]*t+m[9]*n+m[13],n=(e,t,n)=>m[2]*e+m[6]*t+m[10]*n+m[14],r=[e(b,x,S),t(b,x,S),n(b,x,S)],i=[e(C,w,T),t(C,w,T),n(C,w,T)],a=[e(E,D,O),t(E,D,O),n(E,D,O)];b=r[0],x=r[1],S=r[2],C=i[0],w=i[1],T=i[2],E=a[0],D=a[1],O=a[2]}g[v+n]=b,g[v+n+1]=x,g[v+n+2]=S,g[v+r]=C,g[v+r+1]=w,g[v+r+2]=T,g[v+i]=E,g[v+i+1]=D,g[v+i+2]=O;let k=C-b,A=w-x,j=T-S,M=E-b,N=D-x,P=O-S,F=Qe(A*P-j*N,j*M-k*P,k*N-A*M);_[v+a]=F,_[v+o]=F,_[v+s]=F}}_patchMeshSmoothNormals(e,t){let n=this.instanceTable;this._patchNormalsRange(t,n.triOffsetOf(e),n.triCountOf(e),n.matrixWorldOf(e),n.bvhToOriginalOf(e))}_patchNormalsRange(e,t,n,r,i){let a=K.NORMAL_A_PACKED_OFFSET,o=K.NORMAL_B_PACKED_OFFSET,s=K.NORMAL_C_PACKED_OFFSET,c=r,l=!c||Ro(c),u=[a,o,s];for(let r=0;r<n;r++){let n=t+r,a=this.triangles.chunkFor(n),o=this.triangles.baseOf(n),s=(i?i[r]:r)*9;for(let t=0;t<3;t++){let n=s+t*3,r=e[n],i=e[n+1],d=e[n+2],f=r,p=i,m=d;if(!l){f=c[0]*r+c[1]*i+c[2]*d,p=c[4]*r+c[5]*i+c[6]*d,m=c[8]*r+c[9]*i+c[10]*d;let e=Math.hypot(f,p,m)||1;f/=e,p/=e,m/=e}a[o+u[t]]=Qe(f,p,m)}}}_refitTLAS(){let e=this.instanceTable.tlasNodeCount;(!this._tlasBounds||this._tlasBounds.length<e*6)&&(this._tlasBounds=new Float32Array(e*6));let t=this.instanceTable;for(let n=e-1;n>=0;n--){let e=this.bvhIndexChunks.chunkFor(n),r=this.bvh.chunkFor(n),i=this.bvh.baseOf(n),a=e[i+3];if(a===nt.BLAS_POINTER_LEAF){let r=e[i+1]&tt;r<t.count&&t.writeWorldAABB(r,this._tlasBounds,n*6)}else if(a<nt.TRIANGLE_LEAF){let t=a,o=e[i+7],s=t*6,c=o*6,l=this._tlasBounds;r[i]=l[s],r[i+1]=l[s+1],r[i+2]=l[s+2],r[i+4]=l[s+3],r[i+5]=l[s+4],r[i+6]=l[s+5],r[i+8]=l[c],r[i+9]=l[c+1],r[i+10]=l[c+2],r[i+12]=l[c+3],r[i+13]=l[c+4],r[i+14]=l[c+5];let u=n*6;l[u]=Math.min(l[s],l[c]),l[u+1]=Math.min(l[s+1],l[c+1]),l[u+2]=Math.min(l[s+2],l[c+2]),l[u+3]=Math.max(l[s+3],l[c+3]),l[u+4]=Math.max(l[s+4],l[c+4]),l[u+5]=Math.max(l[s+5],l[c+5])}}}scheduleBackgroundRebuild(e,t){if(!this.instanceTable||!this.triangles)return;this._rebuildGeneration++;let n=this._rebuildGeneration,r=(e,r,i)=>{let a=this.triangles.copyOf(r.triOffset,r.triCount);this._pendingRebuilds.set(e,i),i.onmessage=a=>{let o=a.data;if(i.terminate(),this._pendingRebuilds.delete(e),o.error){_c.error(`background BLAS rebuild failed (mesh ${e}):`,o.error);return}n===this._rebuildGeneration&&this._swapBLAS(e,r,o,t)},i.onerror=t=>{_c.error(`background BLAS rebuild worker failed (mesh ${e}):`,t),i.terminate(),this._pendingRebuilds.delete(e)};let o=r.triCount>500;i.postMessage({triangleData:a.buffer,triangleByteOffset:a.byteOffset,triangleByteLength:a.byteLength,triangleCount:r.triCount,depth:this.config.bvhDepth,maxLeafSize:this.bvhBuilder.maxLeafSize,numBins:this.bvhBuilder.numBins,maxBins:this.bvhBuilder.maxBins,minBins:this.bvhBuilder.minBins,reportProgress:!1,sharedReorderBuffer:null,treeletOptimization:{enabled:o,size:this.config.treeletSize,passes:this.config.treeletOptimizationPasses,minImprovement:this.config.treeletMinImprovement,complexityThreshold:this.config.treeletComplexityThreshold},reinsertionOptimization:{enabled:this.bvhBuilder.enableReinsertionOptimization,batchSizeRatio:this.bvhBuilder.reinsertionBatchSizeRatio,maxIterations:this.bvhBuilder.reinsertionMaxIterations}},[a.buffer])};for(let t of e){let e=this._placementOf(t);if(e<0)continue;let n=this.instanceTable.entryAt(e);if(!n||!this.instanceTable.isOwner(e))continue;let i=this._pendingRebuilds.get(e);i&&i.terminate(),r(e,n,new So)}}_swapBLAS(e,t,n,r){let i=n.bvhData,a=i.length/16;if(a>t.blasNodeCount){_c.warn(`background rebuild does not fit for mesh ${e} (${a} nodes vs ${t.blasNodeCount} reserved), skipping swap`);return}this.bvh.setRecords(t.blasOffset,i),this._offsetBLASInPlace(t.blasOffset,a,t.blasOffset,t.triOffset);let o=n.triangles;o&&this.triangles.setRecords(t.triOffset,o),this.instanceTable.setBlasNodeCount(e,a);let s=n.originalToBvh;if(s){let n=this.instanceTable.bvhToOriginalOf(e),r=new Uint32Array(t.triCount);for(let e=0;e<t.triCount;e++)r[s[e]]=n?n[e]:e;this.instanceTable.setBvhToOriginal(e,r)}this.instanceTable.recomputeAABB(e,this.bvh,this.triangles),this._refitTLAS(),this._log(`Background BLAS rebuild complete for mesh ${e}`),r?.(this.instanceTable.sourceMesh[e]??e)}cancelBackgroundRebuilds(){for(let e of this._pendingRebuilds.values())e.terminate();this._pendingRebuilds.clear()}_disposeRefitWorker(){this._refitWorker&&=(this._refitWorker.terminate(),null),this._refitSharedBuffers=null,this.cancelBackgroundRebuilds()}_disposeTLASWorker(){this._tlasWorker&&=(this._tlasWorker.terminate(),null)}dispose(){this._log(`Disposing resources`),this._disposeRefitWorker(),this._disposeTLASWorker(),this._disposeTextures(),this._reset(),this.textureCreator&&=(this.textureCreator.dispose(),null),this.geometryExtractor=null,this.bvhBuilder=null,this.tlasBuilder=null,this._blasRefitter=null}},yc=[[1619.19106,-.00205010916,5.02995757],[2488.45471,-.00111330907,3.22621544],[3341.43193,-.000486551192,1.76486769],[4094.61742,-.000127446582,.725731635],[4670.28036,291258199e-13,.126703442],[4595.09185,287495649e-13,.15034502],[3787.1745,935907826e-14,.399075871]],bc=[[-488.999748,.000604330754,-.0755807526],[-755.994277,.000316730098,.478306139],[-1023.63977,.00012022347,.936662319],[-1265.71316,487340896e-14,1.27054498],[-1425.29332,-401150431e-13,1.43972784],[-1175.54822,-216378048e-13,1.30408023],[-500.799571,-459832026e-14,1.09098763]],xc=[[596945309e-19,-4.85742887e-8,-970622247e-13,-.00407936148],[240430366e-19,5.55021075e-8,-.000198503712,.0289312858],[-140949732e-19,1.89878968e-7,-.000356632824,.0910767778],[-361460868e-19,2.84822009e-7,-.000493211319,.15672344],[-197075738e-19,1.75359352e-7,-.000250542825,-.0222783266],[-161997957e-21,-1.64216008e-8,.000386216271,-.738077418],[672650283e-21,-2.73078809e-8,.000424098264,-.752335691]];function Sc(e){let t,n,r;if(e>=12e3)t=.8262954810464208,n=.9945080501520986,r=1.566307710274283;else if(e<800)t=5.413294490189271,n=-.20319390035873933,r=-.0822535242887164;else{let i=e>=6365?6:e>=3315?5:e>=1902?4:e>=1449?3:e>=1167?2:+(e>=965),a=yc[i],o=bc[i],s=xc[i],c=1/e;t=a[0]*c+a[1]*e+a[2],n=o[0]*c+o[1]*e+o[2],r=((s[0]*e+s[1])*e+s[2])*e+s[3]}return[Math.max(0,t),Math.max(0,n),Math.max(0,r)]}var Cc=1/(4*Math.PI);function wc(e){let t=e.userData||{},n=Number.isFinite(t.exposure)?t.exposure:0,r=e.intensity*2**n,i=e.color.r,a=e.color.g,o=e.color.b;if(t.useTemperature){let[e,n,r]=Sc(t.temperature??6500);i*=e,a*=n,o*=r}return{r:i,g:a,b:o,intensity:r}}var Tc=class{constructor(){this.lightData={directional:[],rectArea:[],point:[],spot:[]},this.directionalLightCache=[],this.areaLightCache=[],this.pointLightCache=[],this.spotLightCache=[]}clear(){this.lightData.directional=[],this.lightData.rectArea=[],this.lightData.point=[],this.lightData.spot=[],this.directionalLightCache=[],this.areaLightCache=[],this.pointLightCache=[],this.spotLightCache=[]}calculateLightImportance(e,t=`directional`){let n=.2126*e.color.r+.7152*e.color.g+.0722*e.color.b,r=e.intensity*n;if(t===`area`){let t=e.width*e.height;r*=Math.sqrt(t)}else if(t===`point`)r*=Math.sqrt(e.distance||100);else if(t===`spot`){let t=Math.sin(e.angle||Math.PI/4);r*=Math.sqrt(e.distance||100)*t}return r}addDirectionalLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n;if(e.target){e.target.updateMatrixWorld();let i=e.target.getWorldPosition(new r.Vector3);n=t.sub(i).normalize()}else n=t.normalize();let i=this.calculateLightImportance(e,`directional`),a=e.userData.angle||e.angle||0,o=wc(e),s=e.userData?.gobo,c=s&&Number.isInteger(s.index)?s.index:-1,l=s&&typeof s.intensity==`number`?s.intensity:1,u=s&&s.inverted?-Math.abs(l):Math.abs(l),d=s&&typeof s.scale==`number`?s.scale:5;this.directionalLightCache.push({data:[n.x,n.y,n.z,o.r,o.g,o.b,o.intensity,a,c,u,d,0],importance:i,light:e})}addRectAreaLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=e.getWorldQuaternion(new r.Quaternion),i=e.getWorldScale(new r.Vector3),a=e.width*i.x*.5,o=e.height*i.y*.5,s=new r.Vector3(a,0,0).applyQuaternion(n),c=new r.Vector3(0,-o,0).applyQuaternion(n),l=this.calculateLightImportance(e,`area`),u=e.userData?.normalize??!0?1:0,d=Number.isFinite(e.userData?.spread)?e.userData.spread:Math.PI,f=+(e.userData?.shape===`ellipse`||e.userData?.shape===`disk`||e.userData?.shape===1),p=wc(e);this.areaLightCache.push({data:[t.x,t.y,t.z,s.x,s.y,s.z,c.x,c.y,c.z,p.r,p.g,p.b,p.intensity,u,d,f],importance:l,light:e})}addPointLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=this.calculateLightImportance(e,`point`),i=wc(e);this.pointLightCache.push({data:[t.x,t.y,t.z,i.r,i.g,i.b,i.intensity*Cc,e.distance||0,e.decay===void 0?2:e.decay],importance:n,light:e})}addSpotLight(e){if(!e.visible||e.intensity<=0)return;e.updateMatrixWorld();let t=e.getWorldPosition(new r.Vector3),n=(e.target?e.target.getWorldPosition(new r.Vector3):new r.Vector3(0,0,-1)).sub(t).normalize(),i=this.calculateLightImportance(e,`spot`),a=e.userData?.gobo,o=a&&Number.isInteger(a.index)?a.index:-1,s=a&&typeof a.intensity==`number`?a.intensity:1,c=a&&a.inverted?-Math.abs(s):Math.abs(s),l=e.userData?.ies,u=l&&Number.isInteger(l.index)?l.index:-1,d=l&&typeof l.intensity==`number`?l.intensity:1,f=wc(e);this.spotLightCache.push({data:[t.x,t.y,t.z,n.x,n.y,n.z,f.r,f.g,f.b,f.intensity*Cc,e.angle||Math.PI/4,e.penumbra||0,e.distance||0,e.decay===void 0?2:e.decay,o,c,u,d,0,0],importance:i,light:e})}preprocessLights(){this.directionalLightCache.sort((e,t)=>t.importance-e.importance),this.areaLightCache.sort((e,t)=>t.importance-e.importance),this.pointLightCache.sort((e,t)=>t.importance-e.importance),this.spotLightCache.sort((e,t)=>t.importance-e.importance),this.lightData.directional=[],this.lightData.rectArea=[],this.lightData.point=[],this.lightData.spot=[],this.directionalLightCache.forEach(e=>{this.lightData.directional.push(...e.data)}),this.areaLightCache.forEach(e=>{this.lightData.rectArea.push(...e.data)}),this.pointLightCache.forEach(e=>{this.lightData.point.push(...e.data)}),this.spotLightCache.forEach(e=>{this.lightData.spot.push(...e.data)}),this.areaLightCache.length>0&&console.log(`Preprocessed ${this.areaLightCache.length} area lights by importance`),this.pointLightCache.length>0&&console.log(`Preprocessed ${this.pointLightCache.length} point lights by importance`),this.spotLightCache.length>0&&console.log(`Preprocessed ${this.spotLightCache.length} spot lights by importance`)}updateShaderUniforms(e){let t=Math.floor(this.lightData.directional.length/12),n=Math.floor(this.lightData.rectArea.length/16),r=Math.floor(this.lightData.point.length/9),i=Math.floor(this.lightData.spot.length/20);e.defines.MAX_DIRECTIONAL_LIGHTS=t,e.defines.MAX_AREA_LIGHTS=n,e.defines.MAX_POINT_LIGHTS=r,e.defines.MAX_SPOT_LIGHTS=i,e.uniforms.directionalLights.value=new Float32Array(this.lightData.directional),e.uniforms.areaLights.value=new Float32Array(this.lightData.rectArea),e.uniforms.pointLights.value=new Float32Array(this.lightData.point),e.uniforms.spotLights.value=new Float32Array(this.lightData.spot),e.needsUpdate=!0}processSceneLights(e,t){this.clear(),e.traverse(e=>{e.isDirectionalLight?this.addDirectionalLight(e):e.isRectAreaLight?this.addRectAreaLight(e):e.isPointLight?this.addPointLight(e):e.isSpotLight&&this.addSpotLight(e)}),this.preprocessLights(),this.updateShaderUniforms(t)}getLightStatistics(){return{directionalLights:this.directionalLightCache.map(e=>({intensity:e.light.intensity,importance:e.importance,color:e.light.color})),areaLights:this.areaLightCache.map(e=>({intensity:e.light.intensity,importance:e.importance,color:e.light.color,size:e.light.width*e.light.height}))}}},Ec={stbnScalarAtlas:`https://assets.rayzee.atulmourya.com/noise/stbn_scalar_atlas.png`,stbnVec2Atlas:`https://assets.rayzee.atulmourya.com/noise/stbn_vec2_atlas.png`,ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,dracoDecoderPath:`https://www.gstatic.com/draco/v1/decoders/`,ktx2TranscoderPath:`https://cdn.jsdelivr.net/npm/three@0.183.2/examples/jsm/libs/basis/`,oidnWeightsBaseUrl:`https://cdn.jsdelivr.net/npm/denoiser/tzas/`,upscalerModelBaseUrl:`https://huggingface.co/notaneimu/onnx-image-models/resolve/main/`,cacheNamespace:`rayzee`};function Dc(e){e&&Object.assign(Ec,e)}function Oc(){return{...Ec}}var kc=It(`pathtracer`),Ac=100,jc=4,Mc=class extends _e{constructor(e,t,n,i={}){super(`PathTracer`,{...i,executionMode:ge.ALWAYS});let a=i.width||1920,o=i.height||1080;this.camera=n,this.width=a,this.height=o,this.renderer=e,this.scene=t,this.sdfs=new vc,this.lightSerializer=new Tc,this.accumulationEnabled=!0,this.isComplete=!1,this.cameras=[],this.performanceMonitor=je(),this.completionThreshold=0,this.renderLimitMode=`frames`,this._initDataTextures(),this.storageTextures=new Ut(0,0),this.uniforms=new Gt(a,o),this._defineUniformGetters(),this.materialData=new Zt(this.sdfs),this.materialData.callbacks.onReset=()=>this.reset(),this.materialData.callbacks.getTriangleData=()=>({array:this.triangleStorageAttr?.array,records:this._triangleRecords,count:this.triangleCount}),this.materialData.callbacks.onTriangleDataChanged=()=>{this.triangleStorageAttr&&(this._triangleRecords?x(this.renderer,this.triangleStorageAttr,this._triangleRecords.chunks):this.triangleStorageAttr.needsUpdate=!0)},this.environment=new jn(this.scene,this.uniforms),this.environment.callbacks.onReset=()=>this.reset(),this.environment.callbacks.getSceneTextureNodes=()=>this.shaderBuilder.getSceneTextureNodes(),this.shaderBuilder=new Ba,this._initRenderingState(),this.setupBlueNoise(),this.tempVector2=new r.Vector2,this.lastCameraMatrix=new r.Matrix4,this.lastProjectionMatrix=new r.Matrix4,this._seedTick=0,this._pinSeedToFrame=!1,this.lastRenderMode=-1,this.renderModeChangeTimeout=null,this.renderModeChangeDelay=50,this.pendingRenderMode=null,this.lastInteractionModeState=!1,this.cameraChanged=!1,this._lastViewChangeAt=-1/0,this.updateCompletionThreshold()}_initDataTextures(){this.triangleStorageAttr=null,this._triangleRecords=null,this.triangleStorageNode=null,this.triangleCount=0,this.bvhStorageAttr=null,this._bvhRecords=null,this.bvhStorageNode=null,this.bvhNodeCount=0,this.directionalLightsData=null,this.pointLightsData=null,this.spotLightsData=null,this.areaLightsData=null,this.goboMaps=null,this.iesProfiles=null,this.stbnScalarTexture=null,this.stbnVec2Texture=null,this.blueNoiseReady=Promise.resolve(),this.lightStorageAttr=new t.StorageInstancedBufferAttribute(new Float32Array(16),4),this.lightStorageNode=(0,n.storage)(this.lightStorageAttr,`vec4`,1).toReadOnly(),this._lightBufferRealloc=!1,this._lbvhDataCache=null,this._emissiveDataCache=null,this._bitTrailMapCache=null,this._instanceTable=null,this.spheres=[]}_defineUniformGetters(){let e=this.uniforms;for(let t of e.keys())Object.defineProperty(this,t,{get:()=>e.get(t),configurable:!0});let t=e.getLightBufferNodes();for(let[e,n]of Object.entries(t))Object.defineProperty(this,`${e}LightsBufferNode`,{get:()=>n,configurable:!0})}_initRenderingState(){this.isReady=!1,this.frameCount=0}_initCameraOptimizer(){let e=this;this.cameraOptimizer=new ve(this.renderer,{uniforms:{maxBounceCount:{get value(){return e.maxBounces.value},set value(t){e.maxBounces.value=t}},enableAccumulation:{get value(){return e.enableAccumulation.value},set value(t){e.enableAccumulation.value=t}},enableEmissiveTriangleSampling:{get value(){return e.enableEmissiveTriangleSampling.value},set value(t){e.enableEmissiveTriangleSampling.value=t}},cameraIsMoving:{get value(){return e.cameraIsMoving.value},set value(t){e.cameraIsMoving.value=t}}}},{enabled:W.interactionModeEnabled,qualitySettings:{maxBounceCount:1,enableAccumulation:!1,enableEmissiveTriangleSampling:!1},onReset:()=>{this.reset(),this.emit(`pathtracer:viewpointChanged`)}})}setupBlueNoise(){let e=new r.TextureLoader;e.setCrossOrigin(`anonymous`);let t=e=>(e.minFilter=r.NearestFilter,e.magFilter=r.NearestFilter,e.wrapS=r.RepeatWrapping,e.wrapT=r.RepeatWrapping,e.generateMipmaps=!1,e),{stbnScalarAtlas:n,stbnVec2Atlas:i}=Oc(),a=e.loadAsync(n).then(e=>{this.stbnScalarTexture=t(e),P.value=e,kc.debug(`STBN scalar atlas ${Y.px(e.image.width,e.image.height)}`)}),o=e.loadAsync(i).then(e=>{this.stbnVec2Texture=t(e),F.value=e,kc.debug(`STBN vec2 atlas ${Y.px(e.image.width,e.image.height)}`)});this.blueNoiseReady=Promise.allSettled([a,o]).then(e=>{for(let t of e)t.status===`rejected`&&kc.warn(`STBN atlas failed to load`,t.reason)})}setupEventListeners(){this.on(`pipeline:reset`,()=>{this.reset()}),this.on(`pipeline:resize`,e=>{e&&e.width&&e.height&&this.setSize(e.width,e.height)}),this.on(`pathtracer:setCompletionThreshold`,e=>{e&&e.threshold!==void 0&&(this.completionThreshold=e.threshold)})}async build(e){this.dispose(),this.scene=e,await this.sdfs.buildBVH(e),this.cameras=this.sdfs.cameras,this.updateSceneUniforms(),this.updateLights(),this._initCameraOptimizer(),this.setupMaterial()}updateSceneUniforms(){this.setTriangleData(this.sdfs.triangleData,this.sdfs.triangleCount),this.setBVHData(this.sdfs.bvhData),this.setInstanceTable(this.sdfs.instanceTable),this.materialData.setMaterialData(this.sdfs.materialData),this.materialData.loadTexturesFromSdfs(),this.sdfs.emissiveTriangleData?this.setEmissiveTriangleData(this.sdfs.emissiveTriangleData,this.sdfs.emissiveTriangleCount||0):this.emissiveTriangleCount.value=0,this.sdfs.lightBVHNodeData?this.setLightBVHData(this.sdfs.lightBVHNodeData,this.sdfs.lightBVHNodeCount||0):this.lightBVHNodeCount.value=0,this._meshRefs=this._collectMeshRefs(this.scene),this.setMeshVisibilityData(this._meshRefs),this.spheres=this.sdfs.spheres||[]}updateLights(){let e={uniforms:{directionalLights:{value:null},pointLights:{value:null},spotLights:{value:null},areaLights:{value:null}},defines:{}};if(this.lightSerializer.processSceneLights(this.scene,e),this.directionalLightsData=e.uniforms.directionalLights.value,this.pointLightsData=e.uniforms.pointLights.value,this.spotLightsData=e.uniforms.spotLights.value,this.areaLightsData=e.uniforms.areaLights.value,this.hasSun.value){let t=this.environment.envParams.skySunIntensity*950,n={intensity:t,color:{r:1,g:1,b:1},userData:{angle:this.sunAngularSize.value},updateMatrixWorld:()=>{},getWorldPosition:e=>{let t=this.sunDirection.value;return e.set(t.x,t.y,t.z).multiplyScalar(1e10)}};this.lightSerializer.addDirectionalLight(n),this.lightSerializer.preprocessLights(),this.lightSerializer.updateShaderUniforms(e),this.directionalLightsData=e.uniforms.directionalLights.value,kc.debug(`sun added as directional light · intensity ${t.toFixed(2)}`)}this._updateLightBufferNodes()}_updateLightBufferNodes(){this.directionalLightsData&&this.directionalLightsData.length>0?(this.directionalLightsBufferNode.array=Array.from(this.directionalLightsData),this.numDirectionalLights.value=Math.floor(this.directionalLightsData.length/12)):this.numDirectionalLights.value=0,this.areaLightsData&&this.areaLightsData.length>0?(this.areaLightsBufferNode.array=Array.from(this.areaLightsData),this.numAreaLights.value=Math.floor(this.areaLightsData.length/16)):this.numAreaLights.value=0,this.pointLightsData&&this.pointLightsData.length>0?(this.pointLightsBufferNode.array=Array.from(this.pointLightsData),this.numPointLights.value=Math.floor(this.pointLightsData.length/9)):this.numPointLights.value=0,this.spotLightsData&&this.spotLightsData.length>0?(this.spotLightsBufferNode.array=Array.from(this.spotLightsData),this.numSpotLights.value=Math.floor(this.spotLightsData.length/20)):this.numSpotLights.value=0}reset(){this.frameCount=0,this.frame.value=0,this.hasPreviousAccumulated.value=0,this.storageTextures.currentTarget=0,this.updateCompletionThreshold(),this.isComplete=!1,this.performanceMonitor?.reset(),this.lastInteractionModeState=!1,this._pinSeedToFrame&&(this._seedTick=0)}setSize(e,t){this.width=e,this.height=t,this.resolution.value.set(e,t),this.createStorageTextures(e,t)}setAccumulationEnabled(e){this.accumulationEnabled=e,this.enableAccumulation.value=+!!e}enterInteractionMode(){this.cameraOptimizer?.enterInteractionMode()}setInteractionModeEnabled(e){this.cameraOptimizer?.setInteractionModeEnabled(e)}get interactionMode(){return this.cameraOptimizer?.isInInteractionMode()??!1}get viewIsChanging(){return this.interactionMode||performance.now()-this._lastViewChangeAt<Ac}noteViewChanged(){this._lastViewChangeAt=performance.now()}setTriangleData(e,r){if(!e)return;let i=e.chunks&&e.chunks.length>1?e:null,a=i?null:e.chunks?e.chunks[0]:e,o=(i?i.recordCount*i.lanesPerRecord:a.length)/4,s=()=>i?y(o,4,Uint32Array):new t.StorageInstancedBufferAttribute(a,4);this.triangleStorageNode?(this.triangleStorageAttr=s(),this.triangleStorageNode.value=this.triangleStorageAttr,this.triangleStorageNode.bufferCount=o):(this.triangleStorageAttr=s(),this.triangleStorageNode=(0,n.storage)(this.triangleStorageAttr,`uvec4`,o).toReadOnly()),this._triangleRecords=i,i&&x(this.renderer,this.triangleStorageAttr,i.chunks),this.triangleCount=r,kc.debug(`${Y.n(this.triangleCount)} triangles (storage buffer)`)}setBVHData(e){if(!e)return;let r=e.chunks&&e.chunks.length>1?e:null,i=r?null:e.chunks?e.chunks[0]:e,a=(r?r.recordCount*r.lanesPerRecord:i.length)/4,o=()=>r?y(a,4,Float32Array):new t.StorageInstancedBufferAttribute(i,4);this.bvhStorageNode?(this.bvhStorageAttr=o(),this.bvhStorageNode.value=this.bvhStorageAttr,this.bvhStorageNode.bufferCount=a):(this.bvhStorageAttr=o(),this.bvhStorageNode=(0,n.storage)(this.bvhStorageAttr,`vec4`,a).toReadOnly()),this._bvhRecords=r,r&&x(this.renderer,this.bvhStorageAttr,r.chunks),this.bvhNodeCount=Math.floor(a/jc),kc.debug(`${Y.n(this.bvhNodeCount)} BVH nodes (storage buffer)`)}setInstanceTable(e){this._instanceTable=e}setMeshVisibilityData(e){!e||e.length===0||!this._instanceTable||(this._patchVisibilityFromMeshes(e),this._flushBVHEdits())}_patchVisibilityFromMeshes(e){let t=this._instanceTable,n=new Map;for(let r=0;r<t.count;r++){if(!t.isSet[r])continue;let i=t.sourceMesh[r],a=n.get(i);a===void 0&&n.set(i,a=this._isWorldVisible(e[i])),this._patchTLASLeafVisibility(r,a)}}updateMeshVisibility(e,t){this._patchTLASLeafVisibility(e,t)&&this._flushBVHEdits()}updateAllMeshVisibility(){!this._meshRefs||!this._instanceTable||(this._patchVisibilityFromMeshes(this._meshRefs),this._flushBVHEdits())}_patchTLASLeafVisibility(e,t){let n=this._instanceTable;if(!n||!n.isSet?.[e]||!this.bvhStorageAttr)return!1;let r=n.tlasLeafIndex[e];return r<0?!1:(n.visible[e]=+!!t,this._bvhRecords?this._bvhRecords.chunkFor(r)[this._bvhRecords.baseOf(r)+2]=+!!t:this.bvhStorageAttr.array[r*16+2]=+!!t,this._dirtyBVHLeaves??=new Set,this._dirtyBVHLeaves.add(r),!0)}_flushBVHEdits(){if(this.bvhStorageAttr){if(!this._bvhRecords){this.bvhStorageAttr.needsUpdate=!0,this._dirtyBVHLeaves?.clear();return}for(let e of this._dirtyBVHLeaves??[])S(this.renderer,this.bvhStorageAttr,this._bvhRecords,e*16,16);this._dirtyBVHLeaves?.clear()}}_collectMeshRefs(e){if(!e)return[];let t=[];return e.traverse(e=>{e.isMesh&&e.userData.meshIndex!==void 0&&(t[e.userData.meshIndex]=e)}),t}_isWorldVisible(e){for(;e;){if(!e.visible)return!1;e=e.parent}return!0}_updateStorageBuffer(e,t){e&&(e.array.set(t),e.needsUpdate=!0)}updateTriangleData(e){if(this._triangleRecords){x(this.renderer,this.triangleStorageAttr,this._triangleRecords.chunks);return}this._updateStorageBuffer(this.triangleStorageAttr,e?.chunks?e.chunks[0]:e)}updateBVHData(e){if(this._bvhRecords){x(this.renderer,this.bvhStorageAttr,this._bvhRecords.chunks);return}this._updateStorageBuffer(this.bvhStorageAttr,e?.chunks?e.chunks[0]:e)}updateBufferRanges(e,t){if(this.triangleStorageAttr&&e.length>0)if(this._triangleRecords)for(let t of e)S(this.renderer,this.triangleStorageAttr,this._triangleRecords,t.offset,t.count);else{this.triangleStorageAttr.clearUpdateRanges();for(let t of e)this.triangleStorageAttr.addUpdateRange(t.offset,t.count);this.triangleStorageAttr.version++}if(this.bvhStorageAttr&&t.length>0)if(this._bvhRecords)for(let e of t)S(this.renderer,this.bvhStorageAttr,this._bvhRecords,e.offset,e.count);else{this.bvhStorageAttr.clearUpdateRanges();for(let e of t)this.bvhStorageAttr.addUpdateRange(e.offset,e.count);this.bvhStorageAttr.version++}}createStorageTextures(e,t){this.storageTextures.writeColor?this.storageTextures.setSize(e,t):this.storageTextures.create(e,t),this.resolution.value.set(e,t)}setupMaterial(){if(this.cameraOptimizer||this._initCameraOptimizer(),!this.triangleStorageNode){kc.error(`triangle data required`);return}if(!this.bvhStorageNode){kc.error(`BVH data required`);return}if(this.isReady&&this.shaderBuilder.getSceneTextureNodes()){this.shaderBuilder.updateSceneTextures(this);return}this._ensureStorageTextures(),this.shaderBuilder.createSceneTextureNodes(this,this.storageTextures),this.isReady=!0}_ensureStorageTextures(){let e=this.renderer.domElement,t=Math.max(1,e.width||this.width),n=Math.max(1,e.height||this.height);this.storageTextures.ensureSize(t,n)&&this.resolution.value.set(t,n)}_handleResize(){let{width:e,height:t}=this.renderer.domElement;(e!==this.storageTextures.renderWidth||t!==this.storageTextures.renderHeight)&&(this.createStorageTextures(e,t),this.frameCount=0),this.resolution.value.set(e,t)}_matricesApproxEqual(e,t,n=1e-10){let r=e.elements,i=t.elements;for(let e=0;e<16;e++)if(Math.abs(r[e]-i[e])>n)return!1;return!0}_updateCameraUniforms(){return!this._matricesApproxEqual(this.lastCameraMatrix,this.camera.matrixWorld)||!this._matricesApproxEqual(this.lastProjectionMatrix,this.camera.projectionMatrixInverse)?(this.cameraWorldMatrix.value.copy(this.camera.matrixWorld),this.cameraViewMatrix.value.copy(this.camera.matrixWorldInverse),this.cameraProjectionMatrix.value.copy(this.camera.projectionMatrix),this.cameraProjectionMatrixInverse.value.copy(this.camera.projectionMatrixInverse),this.lastCameraMatrix.copy(this.camera.matrixWorld),this.lastProjectionMatrix.copy(this.camera.projectionMatrixInverse),!0):!1}_updateAccumulationUniforms(e,t){let n=this.cameraOptimizer?.isInInteractionMode()??!1;this.lastInteractionModeState=n,this.accumulationEnabled?n?(this.accumulationAlpha.value=1,this.hasPreviousAccumulated.value=0):(this.accumulationAlpha.value=Ae(e),this.hasPreviousAccumulated.value=+(e>0)):(this.accumulationAlpha.value=1,this.hasPreviousAccumulated.value=0)}_publishTexturesToContext(e,t){e.setTexture(`pathtracer:color`,t.color),e.setTexture(`pathtracer:normalDepth`,t.normalDepth),e.setTexture(`pathtracer:albedo`,t.albedo),e.setState(`pathtracer:samples`,this.frameCount),e.setState(`interactionMode`,this.cameraOptimizer?.isInInteractionMode()??!1),e.setState(`renderMode`,this.renderMode.value)}_emitStateEvents(){this.emit(`pathtracer:frameComplete`,{frame:this.frameCount,isComplete:this.isComplete}),this.cameraChanged&&=(this.emit(`camera:moved`),!1)}updateCompletionThreshold(){this.completionThreshold=ke(this.renderMode.value,this.maxSamples.value)}setRenderLimitMode(e){this.renderLimitMode=e,this.updateCompletionThreshold()}manageASVGFForRenderMode(e){e!==this.lastRenderMode&&(this.renderModeChangeTimeout&&clearTimeout(this.renderModeChangeTimeout),this.pendingRenderMode=e,this.renderModeChangeTimeout=setTimeout(()=>{this.pendingRenderMode!==null&&this.pendingRenderMode!==this.lastRenderMode&&(this.lastRenderMode=this.pendingRenderMode,this.emit(`asvgf:reset`),this.emit(`denoiser:reset`)),this.renderModeChangeTimeout=null,this.pendingRenderMode=null},this.renderModeChangeDelay))}setUniform(e,t){this.uniforms.set(e,t)}setBlueNoiseTexture(e){this.stbnScalarTexture=e,e&&(P.value=e)}_rebuildLightBuffer(){let e=this._lbvhDataCache,n=this._emissiveDataCache,r=this._bitTrailMapCache,i=e?e.length:0,a=n?n.length:0,o=r?Math.ceil(r.length/4)*4:0,s=Math.max(i+a+o,4);if(this.lightStorageAttr&&s<=this.lightStorageAttr.array.length){let t=this.lightStorageAttr.array;e&&t.set(e,0),n&&t.set(n,i),r&&t.set(r,i+a),this.lightStorageAttr.needsUpdate=!0}else{let o=new Float32Array(s);e&&o.set(e,0),n&&o.set(n,i),r&&o.set(r,i+a),this.lightStorageAttr=new t.StorageInstancedBufferAttribute(o,4),this.lightStorageNode.value=this.lightStorageAttr,this.lightStorageNode.bufferCount=o.length/4,this._lightBufferRealloc=!0}this.emissiveVec4Offset.value=(this.lightBVHNodeCount.value||0)*4,this.reverseMapVec4Offset.value=(i+a)/4}setEmissiveTriangleData(e,t,n=0,r=null){e&&(this._emissiveDataCache=e,r&&(this._bitTrailMapCache=r),this.emissiveTriangleCount.value=t,this.emissiveTotalPower.value=n,this._rebuildLightBuffer(),kc.debug(`${Y.n(t)} emissive triangles · totalPower ${n.toFixed(4)} (storage buffer)`))}setLightBVHData(e,t){e&&(this._lbvhDataCache=e,this.lightBVHNodeCount.value=t,this._rebuildLightBuffer(),kc.debug(`light BVH ${Y.n(t)} nodes`))}updateUniforms(e){let t=!1;for(let[n,r]of Object.entries(e))this[n]&&this[n].value!==void 0&&this[n].value!==r&&(this[n].value=r,t=!0);t&&this.reset()}async rebuildMaterials(e){if(!this.sdfs)throw Error(`Scene not built yet. Call build() first.`);try{kc.debug(`material rebuild started`),await this.sdfs.rebuildMaterials(e),this.updateSceneUniforms(),this.shaderBuilder.updateSceneTextures(this),this.updateLights(),this.reset(),kc.debug(`material rebuild complete`)}catch(e){kc.error(`material rebuild failed:`,e);try{kc.warn(`attempting recovery by resetting the path tracer`),this.reset()}catch(e){kc.error(`recovery failed:`,e)}throw e}}dispose(){this.renderModeChangeTimeout&&=(clearTimeout(this.renderModeChangeTimeout),null),this.cameraOptimizer?.dispose(),this.materialData?.dispose(),this.environment?.dispose(),this.shaderBuilder?.dispose(),this.uniforms?.dispose(),this.storageTextures?.dispose(),this.stbnScalarTexture?.dispose(),this.stbnVec2Texture?.dispose(),this.placeholderTexture?.dispose(),this.triangleStorageAttr=null,this._triangleRecords=null,this.triangleStorageNode=null,this.bvhStorageAttr=null,this._bvhRecords=null,this.bvhStorageNode=null,this.placeholderTexture=null,this.isReady=!1}},Nc=It(`gpu`),Pc={ORIGIN_META:0,DIR_FLAGS:1,THROUGHPUT_PDF:2,RADIANCE_ALPHA:3,MEDIUM_STACK:4,MEDIUM_SIGMA_A:5,SSS_SIGMA_S:6},Fc={DIST_TRI_BARY:0,NORMAL_MAT:1},Ic=0,Lc=(e,t)=>t===0?e:e.add(t*Ic);function Rc(e,t){t&&e?._attributes?.delete?.(t)}var zc=class{constructor(e=0,t=null){this.capacity=0,this._renderer=t,this._attrs={},this.rayBuffer=null,this.rngBuffer=null,this.hitBuffer=null,e>0&&this.allocate(e)}allocate(e){this.dispose(),this.capacity=e,Ic=e;let t=e*7,r=y(t,4);this._attrs.ray=r,this.rayBuffer={rw:(0,n.storage)(r,`vec4`),ro:(0,n.storage)(r,`vec4`).toReadOnly()};let i=y(e,1,Uint32Array);this._attrs.rng=i,this.rngBuffer={rw:(0,n.storage)(i,`uint`),ro:(0,n.storage)(i,`uint`).toReadOnly()};let a=e*2,o=y(a,4,Uint32Array);this._attrs.hit=o,this.hitBuffer={rw:(0,n.storage)(o,`uvec4`),ro:(0,n.storage)(o,`uvec4`).toReadOnly()},this.rayBytes=t*16+e*4,this.hitBytes=a*16,this.totalBytes=this.rayBytes+this.hitBytes,Nc.debug(`ray pool capacity ${Y.n(e)} · ${Y.mb(this.totalBytes)} (rays ${Y.mb(this.rayBytes)} · hits ${Y.mb(this.hitBytes)})`)}resize(e){return e<=this.capacity&&this.capacity>0?!1:(this.allocate(e),!0)}dispose(){Rc(this._renderer,this._attrs.ray),Rc(this._renderer,this._attrs.rng),Rc(this._renderer,this._attrs.hit),this._attrs={},this.rayBuffer=null,this.rngBuffer=null,this.hitBuffer=null,this.capacity=0}},Bc=(e,t)=>e.element(Lc(t,Pc.ORIGIN_META)).xyz,Vc=(e,t)=>e.element(Lc(t,Pc.DIR_FLAGS)).xyz,Hc=(e,t)=>(0,n.floatBitsToUint)(e.element(Lc(t,Pc.DIR_FLAGS)).w),Uc=(e,t)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).xyz,Wc=(e,t)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).w,Gc=(e,t)=>e.element(Lc(t,Pc.RADIANCE_ALPHA)),Kc=e=>(0,n.uint)(e).mul(1),qc=(e,t,r,i,a,o=null)=>{let s=Kc(t),c=o===null?(0,n.unpackUnorm2x16)(e.element(s).w).y:(0,n.float)(o);return e.element(s).assign((0,n.uvec4)((0,n.packSnorm2x16)((0,n.vec2)(r.x,r.y)),(0,n.packSnorm2x16)((0,n.vec2)(r.z,i)),(0,n.packUnorm2x16)((0,n.vec2)(a.x,a.y)),(0,n.packUnorm2x16)((0,n.vec2)(a.z,c))))},Jc=(e,t,r)=>{let i=Kc(t),a=e.element(i).toVar();return e.element(i).assign((0,n.uvec4)(a.x,a.y,a.z,(0,n.packUnorm2x16)((0,n.vec2)((0,n.unpackUnorm2x16)(a.w).x,r))))},Yc=(e,t)=>e.element(Kc(t)),Xc=e=>(0,n.unpackUnorm2x16)(e.w).y,Zc=e=>{let t=(0,n.unpackSnorm2x16)(e.x),r=(0,n.unpackSnorm2x16)(e.y);return(0,n.vec4)((0,n.vec3)(t.x,t.y,r.x).mul(.5).add(.5),r.y)},Qc=e=>(0,n.vec3)((0,n.unpackUnorm2x16)(e.z),(0,n.unpackUnorm2x16)(e.w).x),$c=e=>{let t=(0,n.clamp)((0,n.floor)((0,n.log2)((0,n.max)(e,1e-6))),-8,7),r=(0,n.clamp)((0,n.float)(e).mul((0,n.exp2)(t.negate())).sub(1).mul(64),0,63);return(0,n.select)((0,n.float)(e).lessThan(.004),(0,n.uint)(0),(0,n.uint)(t.add(8)).shiftLeft(6).bitOr((0,n.uint)(r)))},el=(e,t)=>{let r=(0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(22),i=(0,n.float)(r.shiftRight(6).bitAnd((0,n.uint)(15))).sub(8),a=(0,n.float)(r.bitAnd((0,n.uint)(63))).div(64).add(1);return(0,n.select)(r.equal((0,n.uint)(0)),(0,n.float)(0),a.mul((0,n.exp2)(i)))},tl=(e,t,r,i,a,o=(0,n.uint)(0),s=null)=>{let c=(0,n.uint)(i).bitAnd((0,n.uint)(255)).bitOr((0,n.uint)(a).bitAnd((0,n.uint)(255)).shiftLeft(8)).bitOr((0,n.uint)(o).bitAnd((0,n.uint)(63)).shiftLeft(16));return s!==null&&(c=c.bitOr($c(s).shiftLeft(22))),e.element(Lc(t,Pc.ORIGIN_META)).assign((0,n.vec4)(r,(0,n.uintBitsToFloat)(c)))},nl=(e,t,r,i)=>e.element(Lc(t,Pc.DIR_FLAGS)).assign((0,n.vec4)(r,(0,n.uintBitsToFloat)(i))),rl=(e,t,r,i)=>e.element(Lc(t,Pc.THROUGHPUT_PDF)).assign((0,n.vec4)(r,i)),il=(e,t,n)=>e.element(Lc(t,Pc.RADIANCE_ALPHA)).assign(n),al=(e,t)=>(0,n.uintBitsToFloat)(e.element(Lc(t,Fc.DIST_TRI_BARY)).x),ol=(e,t)=>e.element(Lc(t,Fc.DIST_TRI_BARY)).y,sl=(e,t)=>(0,n.uintBitsToFloat)(e.element(Lc(t,Fc.DIST_TRI_BARY)).zw),cl=(e,t)=>vr(e.element(Lc(t,Fc.NORMAL_MAT)).x),ll=(e,t)=>(0,n.uint)(e.element(Lc(t,Fc.NORMAL_MAT)).y),ul=(e,t)=>(0,n.int)(e.element(Lc(t,Fc.NORMAL_MAT)).z).sub((0,n.int)(1)),dl=(e,t,r,i,a,o,s,c,l)=>{e.element(Lc(t,Fc.DIST_TRI_BARY)).assign((0,n.uvec4)((0,n.floatBitsToUint)(r),i,(0,n.floatBitsToUint)(a),(0,n.floatBitsToUint)(o))),e.element(Lc(t,Fc.NORMAL_MAT)).assign((0,n.uvec4)(_r(s),c,l,(0,n.uint)(0)))},fl=(e,t)=>{let r=e.element(Lc(t,Pc.MEDIUM_STACK)),i=(0,n.floatBitsToUint)(r.x);return{stackDepth:i.bitAnd(255),transTraversals:i.shiftRight(8).bitAnd(255),wavelength:i.shiftRight(16).bitAnd(65535),ior1:r.y,ior2:r.z,ior3:r.w}},pl=(e,t,r,i,a,o,s,c=(0,n.uint)(0))=>e.element(Lc(t,Pc.MEDIUM_STACK)).assign((0,n.vec4)((0,n.uintBitsToFloat)(r.bitOr(i.shiftLeft(8)).bitOr(c.shiftLeft(16))),a,o,s)),ml=(e,t)=>e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).xyz,hl=(e,t,r)=>{let i=e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).w.toVar();e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).assign((0,n.vec4)(r,i))},gl=e=>{let t=(0,n.clamp)(e,(0,n.vec3)(0),(0,n.vec3)(1)).mul(1023).add(.5);return(0,n.uint)(t.x).bitOr((0,n.uint)(t.y).shiftLeft(10)).bitOr((0,n.uint)(t.z).shiftLeft(20))},_l=e=>(0,n.vec3)((0,n.float)(e.bitAnd((0,n.uint)(1023))),(0,n.float)(e.shiftRight(10).bitAnd((0,n.uint)(1023))),(0,n.float)(e.shiftRight(20).bitAnd((0,n.uint)(1023)))).div(1023),vl=(e,t)=>_l((0,n.floatBitsToUint)(e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).w)),yl=(e,t,r)=>{let i=e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).xyz.toVar();e.element(Lc(t,Pc.MEDIUM_SIGMA_A)).assign((0,n.vec4)(i,(0,n.uintBitsToFloat)(gl(r))))},bl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).bitAnd(255)),xl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(8).bitAnd(255)),Sl=(e,t)=>(0,n.int)((0,n.floatBitsToUint)(e.element(Lc(t,Pc.ORIGIN_META)).w).shiftRight(16).bitAnd((0,n.uint)(63))),Cl=(e,t)=>{let n=e.element(Lc(t,Pc.SSS_SIGMA_S));return{sigmaS:n.xyz,g:n.w}},wl=(e,t,r,i)=>e.element(Lc(t,Pc.SSS_SIGMA_S)).assign((0,n.vec4)(r,i)),Tl=It(`gpu`),$={ACTIVE_RAY_COUNT:0,ENTERING_COUNT:1,CONVERGED_COUNT:2,RESERVED_3:3,ACTIVE_PIXEL_COUNT:4,GEOMETRY_COUNT:5,CONVERGED_GEOMETRY_COUNT:6,ACTIVE_ENERGY:7,COUNT:8},El=65535,Dl={BOUNCE_MASK:255,ACTIVE:256,SPECULAR:512,INSIDE_MEDIUM:1024,RAY_TYPE_SHIFT:11,RAY_TYPE_MASK:63488,HAS_HIT_OPAQUE:65536,AUX_LOCKED:1<<17,REDIRECTED:1<<18},Ol=class{constructor(e=0,t=null){this._renderer=t,this.capacity=0,this.counters=null,this.activeIndices=null,this.activeIndicesRO=null,this.sortedIndices=null,this.sortedIndicesRO=null,this.sortGlobalHistogram=null,this.pingPong=0,e>0&&this.allocate(e)}allocate(e){this.dispose(),this.capacity=e,this._countersAttr=new t.StorageInstancedBufferAttribute(new Uint32Array($.COUNT),1),this.counters=(0,n.storage)(this._countersAttr,`uint`).toAtomic(),this.MAX_BOUNCE_SNAPSHOTS=32,this._bounceCountsAttr=new t.StorageInstancedBufferAttribute(new Uint32Array(2*this.MAX_BOUNCE_SNAPSHOTS),1),this.bounceCounts=(0,n.storage)(this._bounceCountsAttr,`uint`);let r=y(e,1,Uint32Array),i=y(e,1,Uint32Array);this._attrA=r,this._attrB=i,this.activeIndices={a:(0,n.storage)(r,`uint`),b:(0,n.storage)(i,`uint`)},this.activeIndicesRO={a:(0,n.storage)(r,`uint`).toReadOnly(),b:(0,n.storage)(i,`uint`).toReadOnly()};let a=y(e,1,Uint32Array);this._sortAttr=a,this.sortedIndices=(0,n.storage)(a,`uint`),this.sortedIndicesRO=(0,n.storage)(a,`uint`).toReadOnly(),this._sortGlobalHistAttr=new t.StorageInstancedBufferAttribute(new Uint32Array(256),1),this.sortGlobalHistogram=(0,n.storage)(this._sortGlobalHistAttr,`uint`).toAtomic(),this.pingPong=0,this.totalBytes=$.COUNT*4+e*4*3,Tl.debug(`queues capacity ${Y.n(e)} · ${Y.mb(this.totalBytes)}`)}resize(e){return e<=this.capacity&&this.capacity>0?!1:(this.allocate(e),!0)}getCounters(){return this.counters}getActiveReadRO(){return this.pingPong===0?this.activeIndicesRO.a:this.activeIndicesRO.b}getActiveRead(){return this.pingPong===0?this.activeIndices.a:this.activeIndices.b}getActiveWrite(){return this.pingPong===0?this.activeIndices.b:this.activeIndices.a}getSortedRW(){return this.sortedIndices}getSortedRO(){return this.sortedIndicesRO}getSortGlobalHistogram(){return this.sortGlobalHistogram}getCountersAttribute(){return this._countersAttr}getBounceCounts(){return this.bounceCounts}getBounceCountsAttribute(){return this._bounceCountsAttr}swap(){this.pingPong=1-this.pingPong}resetPingPong(){this.pingPong=0}dispose(){Rc(this._renderer,this._countersAttr),Rc(this._renderer,this._bounceCountsAttr),Rc(this._renderer,this._attrA),Rc(this._renderer,this._attrB),Rc(this._renderer,this._sortAttr),Rc(this._renderer,this._sortGlobalHistAttr),this._countersAttr=this._bounceCountsAttr=null,this._attrA=this._attrB=this._sortAttr=this._sortGlobalHistAttr=null,this.counters=null,this.activeIndices=null,this.activeIndicesRO=null,this.sortedIndices=null,this.sortedIndicesRO=null,this.sortGlobalHistogram=null,this.capacity=0}},kl={[r.RGBAFormat]:4,[r.RGBFormat]:3,[r.RGFormat]:2,[r.RedFormat]:1},Al={[r.FloatType]:4,[r.HalfFloatType]:2,[r.UnsignedByteType]:1,[r.ByteType]:1,[r.UnsignedShortType]:2,[r.ShortType]:2,[r.UnsignedIntType]:4,[r.IntType]:4};function jl(e){return(kl[e.format]??4)*(Al[e.type]??4)}function Ml(e){return e?.gpuByteLength??e?.array?.byteLength??0}function Nl(e){if(!e)return 0;if(e.isRenderTarget){let t=e.textures?.length?e.textures:[e.texture],n=e.width||0,r=e.height||0,i=e.depth||1,a=0;for(let e of t)e&&(a+=n*r*i*jl(e));return a}let t=e.image||{},n=t.width??e.width??0,r=t.height??e.height??0,i=t.depth??1;return n*r*i*jl(e)}var Pl=class{constructor(e=null){this._providers=[],this._renderer=e,this.current=0,this.peak=0,this.byCategory={}}setRenderer(e){this._renderer=e}register(e,t){this._providers.push({category:e,fn:t})}measure(){let e=new WeakSet,t={},n=0;for(let{category:r,fn:i}of this._providers){let a;try{a=i()}catch{a=null}if(!a)continue;let o=0;for(let t of Array.isArray(a)?a:[a])o+=this._resourceBytes(t,e);t[r]=(t[r]||0)+o,n+=o}return this.byCategory=t,this.current=n,n>this.peak&&(this.peak=n),{current:n,peak:this.peak,byCategory:t}}_resourceBytes(e,t){return e?typeof e.bytes==`number`&&!e.isTexture&&!e.isRenderTarget?e.bytes:e.gpuByteLength==null?e.array&&e.array.byteLength!=null?t.has(e.array)?0:(t.add(e.array),e.array.byteLength):e.isRenderTarget||e.isTexture?t.has(e)?0:(t.add(e),this._residentTextureBytes(e)):0:t.has(e)?0:(t.add(e),e.gpuByteLength):0}_isResident(e){let t=this._renderer?.backend;if(!t||typeof t.get!=`function`)return!0;if(typeof t.has==`function`&&!t.has(e))return!1;let n=t.get(e);return!!(n&&(n.texture||n.gpuTexture))}_residentTextureBytes(e){if(e.isRenderTarget){let t=e.textures?.length?e.textures:[e.texture],n=e.width||0,r=e.height||0,i=e.depth||1,a=0;for(let e of t)e&&this._isResident(e)&&(a+=n*r*i*jl(e));return a}return this._isResident(e)?Nl(e):0}resetPeak(){this.peak=this.current}getReport(){let e=e=>(e/1048576).toFixed(1),t=Object.entries(this.byCategory).map(([t,n])=>`${t}=${e(n)}`);return`VRAM current=${e(this.current)}MB peak=${e(this.peak)}MB [${t.join(` `)}]`}},Fl=It(`wavefront`),Il=class{constructor(e){this.renderer=e,this.kernels=new Map,this.timing=new Map,this.profiling=!1,this.profile=new Map,this._firstDispatches=[],this._firstDispatchFlush=null}_recordFirstDispatch(e,t){this._firstDispatches.push({name:e,ms:t}),clearTimeout(this._firstDispatchFlush),this._firstDispatchFlush=setTimeout(()=>this._flushFirstDispatches(),0)}_flushFirstDispatches(){let e=this._firstDispatches;if(this._firstDispatches=[],this._firstDispatchFlush=null,e.length===0)return;let t=e.reduce((e,t)=>e+t.ms,0),n=[...e].sort((e,t)=>t.ms-e.ms);Fl.info(Y.list([`${e.length} kernel${e.length===1?``:`s`} compiled in ${Y.ms(t)}`,`slowest ${n.slice(0,2).map(e=>`${e.name} ${Y.ms(e.ms)}`).join(`, `)}`])),e.forEach(e=>Fl.debug(`kernel '${e.name}' first dispatch (incl. compilation) ${Y.ms(e.ms)}`))}register(e,t){this.kernels.set(e,t),this.timing.set(e,{compiledOnce:!1,lastDispatchMs:0})}dispatch(e){let t=this.kernels.get(e);if(!t)throw Error(`KernelManager: Unknown kernel '${e}'`);let n=this.timing.get(e);if(n&&!n.compiledOnce){let r=performance.now();this.renderer.compute(t);let i=performance.now();n.compiledOnce=!0,n.lastDispatchMs=i-r,this._recordFirstDispatch(e,i-r)}else if(this.profiling){let n=performance.now();this.renderer.compute(t);let r=performance.now(),i=this.profile.get(e);i||(i={calls:0,totalMs:0},this.profile.set(e,i)),i.calls++,i.totalMs+=r-n}else this.renderer.compute(t)}setDispatchForCount(e,t){let n=this.kernels.get(e);n&&(n.dispatchSize=[Math.ceil(t/n.workgroupSize[0]),1,1])}setDispatchForGrid(e,t,n){let r=this.kernels.get(e);if(!r)return;let i=r.workgroupSize;r.dispatchSize=[Math.ceil(t/i[0]),Math.ceil(n/i[1]),1]}has(e){return this.kernels.has(e)}get(e){return this.kernels.get(e)}getTimingReport(){let e={};for(let[t,n]of this.timing)e[t]={...n};return e}enableProfiling(e){this.profiling=e,e&&this.profile.clear()}getProfileReport(){let e=[],t=0;for(let[n,{calls:r,totalMs:i}]of this.profile)t+=i,e.push({name:n,calls:r,totalMs:+i.toFixed(2),avgMs:+(i/r).toFixed(3)});return e.sort((e,t)=>t.totalMs-e.totalMs),e.push({name:`TOTAL`,calls:e.reduce((e,t)=>e+t.calls,0),totalMs:+t.toFixed(2),avgMs:null}),e}dispose(){clearTimeout(this._firstDispatchFlush),this._firstDispatchFlush=null,this._firstDispatches=[],this.kernels.clear(),this.timing.clear(),this.profile.clear()}},Ll=(0,n.Fn)(([e,t,r,i,a,o,s])=>{let c=(0,n.vec3)(0).toVar();return(0,n.If)(i.equal((0,n.int)(1)),()=>{let r=(0,n.mix)(a.x,a.y,e.x).toVar(),i=(0,n.mix)(o.y,o.x,e.y).toVar(),l=(0,n.cos)(i).toVar(),u=(0,n.vec3)(0).toVar(),d=(0,n.vec3)(0).toVar(),f=(0,n.vec3)(0).toVar();(0,n.If)(s.equal((0,n.int)(1)),()=>{let e=(0,n.vec3)(t[2].x,0,t[2].z).toVar();(0,n.If)((0,n.dot)(e,e).lessThan((0,n.float)(1e-8)),()=>{e.assign((0,n.vec3)(t[1].x,0,t[1].z))}),f.assign((0,n.normalize)(e)),d.assign((0,n.vec3)(0,1,0)),u.assign((0,n.cross)(d,f))}).Else(()=>{u.assign((0,n.normalize)((0,n.vec3)(t[0]))),d.assign((0,n.normalize)((0,n.vec3)(t[1]))),f.assign((0,n.normalize)((0,n.vec3)(t[2])))}),c.assign((0,n.normalize)(u.mul((0,n.sin)(r).mul(l)).add(d.mul((0,n.sin)(i))).sub(f.mul((0,n.cos)(r).mul(l)))))}).Else(()=>{let i=(0,n.vec3)(e.x.mul(2).sub(1),(0,n.float)(1).sub(e.y.mul(2)),1),a=r.mul((0,n.vec4)(i,1));c.assign((0,n.normalize)((0,n.mat3)(t[0].xyz,t[1].xyz,t[2].xyz).mul(a.xyz.div(a.w))))}),c}),Rl=(0,n.Fn)(([e,t,r,i,a,o,s,c,l,u,d,f,p,m,h])=>{let g=(0,n.vec3)(r[3]).toVar(),_=Ll(e,r,i,a,o,s,c).toVar(),v=g.toVar(),y=_.toVar();return(0,n.If)(l.and(u.greaterThan(0)).and(d.lessThan(64)).and(f.greaterThan(.001)),()=>{let e=u.div(d).mul(.001).mul(p).mul(m),i=ne(t),o=i.x.mul(h.max(.01)),s=i.y,c=(0,n.vec3)(0).toVar();(0,n.If)(a.equal((0,n.int)(1)),()=>{c.assign(ur({N:_}).mul((0,n.vec3)(o,s,0)))}).Else(()=>{let e=(0,n.normalize)((0,n.vec3)(r[0])),t=(0,n.normalize)((0,n.vec3)(r[1]));c.assign(e.mul(o).add(t.mul(s)))}),v.assign(g.add(c.mul(e))),y.assign((0,n.normalize)(g.add(_.mul(f)).sub(v)))}),Mn({origin:v,direction:y})});function zl(e){let{rayBufferRW:t,rngBufferRW:r,gBufferRW:i,resolution:a,frame:o,cameraWorldMatrix:s,cameraProjectionMatrixInverse:c,cameraProjection:l,panoLonRange:u,panoLatRange:d,panoLevelHorizon:f,enableDOF:p,focalLength:m,aperture:h,focusDistance:g,sceneScale:_,apertureScale:v,anamorphicRatio:y,renderWidth:b,chunkRowBase:x,chunkRows:S,transmissiveBounces:C,transparentBackground:w,auxGBufferEnabled:T,listDriven:E=!1,activeIndicesRO:D=null,counters:O=null}=e,k=T.greaterThan((0,n.uint)(0)),A=(e,b,x)=>{let S=(0,n.vec2)((0,n.float)(e).add(.5),(0,n.float)(b).add(.5)),w=R({state:he({pixelCoord:S,rayIndex:(0,n.int)(0),frame:o}).toVar()}).toVar(),T=me(S,(0,n.int)(1),(0,n.int)(1),w,a,o).toVar().sub(.5),E=(0,n.vec2)(S.x.add(T.x),S.y.sub(T.y)).div(a),D=Mn.wrap(Rl(E,w,s,c,l,u,d,f,p,m,h,g,_,v,y));tl(t,x,D.origin,(0,n.int)(0),(0,n.int)(0)),nl(t,x,D.direction,(0,n.uint)(Dl.ACTIVE)),rl(t,x,(0,n.vec4)(1,1,1,0).xyz,(0,n.float)(0)),il(t,x,(0,n.vec4)((0,n.vec3)(0),(0,n.float)(1))),(0,n.If)(k,()=>{qc(i,x,(0,n.vec3)(0,0,1),(0,n.float)(1),(0,n.vec3)(0),(0,n.float)(0)),yl(t,x,(0,n.vec3)(1))}),pl(t,x,(0,n.uint)(0),(0,n.uint)(C),(0,n.float)(1),(0,n.float)(1),(0,n.float)(1)),r.element(x).assign(w)};return(0,n.Fn)(()=>{if(E){let e=n.instanceIndex;(0,n.If)(e.lessThan((0,n.atomicLoad)(O.element((0,n.uint)($.ENTERING_COUNT)))),()=>{let t=(0,n.int)(D.element(e)),r=t.add(x.mul(b));A(r.mod(b),r.div(b),(0,n.uint)(t))})}else{let e=(0,n.int)(n.workgroupId.x).mul(16).add((0,n.int)(n.localId.x)),t=(0,n.int)(n.workgroupId.y).mul(16).add((0,n.int)(n.localId.y));(0,n.If)(e.lessThan(b).and(t.lessThan(S)),()=>{A(e,t.add(x),(0,n.uint)(t.mul(b).add(e)))})}})}var Bl=32,Vl=4096,Hl=4,Ul=1e8,Wl=()=>(0,n.array)(`int`,Bl).toVar(),Gl=e=>{let t=(0,n.mix)((0,n.vec3)(1),(0,n.sign)(e),(0,n.notEqual)(e,(0,n.vec3)(0)));return(0,n.mix)((0,n.vec3)(1).div(e),(0,n.vec3)(Ul).mul(t),(0,n.lessThan)((0,n.abs)(e),(0,n.vec3)(1e-8)))},Kl=(e,t)=>(0,n.vec3)(e[0].xyz.dot(t).add(e[0].w),e[1].xyz.dot(t).add(e[1].w),e[2].xyz.dot(t).add(e[2].w)),ql=(e,t)=>(0,n.vec3)(e[0].xyz.dot(t),e[1].xyz.dot(t),e[2].xyz.dot(t)),Jl=(0,n.wgslFn)(`
|
|
523
523
|
fn RayTriangleGeometry( rayOrigin: vec3f, rayDir: vec3f, pA: vec3f, pB: vec3f, pC: vec3f, closestHitDst: f32, woopParams: vec4f ) -> vec4f {
|
|
524
524
|
|
|
525
525
|
// Returns vec4(t, u, v, hit) where hit > 0.5 means intersection.
|