rayzee 7.21.0 → 7.22.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.es.js CHANGED
@@ -586,6 +586,10 @@ var J = {
586
586
  skyTurbidity: .8,
587
587
  skyMieAnisotropy: .76,
588
588
  skyPreset: "clearMorning",
589
+ cameraProjection: "perspective",
590
+ panoramaLonRange: [-180, 180],
591
+ panoramaLatRange: [-90, 90],
592
+ panoramaLevelHorizon: !0,
589
593
  enableDOF: !1,
590
594
  fov: 55,
591
595
  focusDistance: .8,
@@ -1247,7 +1251,9 @@ var di = class {
1247
1251
  area: Fe(new Float32Array(256), "float"),
1248
1252
  point: Fe(new Float32Array(144), "float"),
1249
1253
  spot: Fe(new Float32Array(320), "float")
1250
- }, n("cameraWorldMatrix", new Ct(), "mat4"), n("cameraProjectionMatrixInverse", new Ct(), "mat4"), n("cameraViewMatrix", new Ct(), "mat4"), n("cameraProjectionMatrix", new Ct(), "mat4"), r("enableDOF", J.enableDOF), n("focusDistance", J.focusDistance, "float"), n("focalLength", J.focalLength, "float"), n("aperture", J.aperture, "float"), n("apertureScale", 1, "float"), n("anamorphicRatio", J.anamorphicRatio ?? 1, "float"), n("sceneScale", 1, "float"), this._uniforms.set("samplingTechnique", Fn), Fn.value = J.samplingTechnique, n("fireflyThreshold", J.fireflyThreshold, "float"), r("enableEmissiveTriangleSampling", J.enableEmissiveTriangleSampling), n("emissiveBoost", J.emissiveBoost, "float"), n("emissiveTriangleCount", 0, "int"), n("emissiveTotalPower", 0, "float"), n("lightBVHNodeCount", 0, "int"), n("emissiveVec4Offset", 0, "int"), n("reverseMapVec4Offset", 0, "int"), n("renderMode", J.renderMode, "int"), r("enableAlphaShadows", J.enableAlphaShadows), n("resolution", new sn(e, t), "vec2");
1254
+ }, n("cameraWorldMatrix", new Ct(), "mat4"), n("cameraProjectionMatrixInverse", new Ct(), "mat4"), n("cameraViewMatrix", new Ct(), "mat4"), n("cameraProjectionMatrix", new Ct(), "mat4");
1255
+ let i = ([e, t]) => new sn(e, t).multiplyScalar(xt.DEG2RAD);
1256
+ n("cameraProjection", +(J.cameraProjection === "equirectangular"), "int"), n("panoLonRange", i(J.panoramaLonRange), "vec2"), n("panoLatRange", i(J.panoramaLatRange), "vec2"), r("panoLevelHorizon", J.panoramaLevelHorizon), r("enableDOF", J.enableDOF), n("focusDistance", J.focusDistance, "float"), n("focalLength", J.focalLength, "float"), n("aperture", J.aperture, "float"), n("apertureScale", 1, "float"), n("anamorphicRatio", J.anamorphicRatio ?? 1, "float"), n("sceneScale", 1, "float"), this._uniforms.set("samplingTechnique", Fn), Fn.value = J.samplingTechnique, n("fireflyThreshold", J.fireflyThreshold, "float"), r("enableEmissiveTriangleSampling", J.enableEmissiveTriangleSampling), n("emissiveBoost", J.emissiveBoost, "float"), n("emissiveTriangleCount", 0, "int"), n("emissiveTotalPower", 0, "float"), n("lightBVHNodeCount", 0, "int"), n("emissiveVec4Offset", 0, "int"), n("reverseMapVec4Offset", 0, "int"), n("renderMode", J.renderMode, "int"), r("enableAlphaShadows", J.enableAlphaShadows), n("resolution", new sn(e, t), "vec2");
1251
1257
  }
1252
1258
  _nameAll() {
1253
1259
  for (let [e, t] of this._uniforms) t.name = fi[e] || e;
@@ -1892,7 +1898,7 @@ var Xi = class {
1892
1898
  0,
1893
1899
  0,
1894
1900
  1
1895
- ]), 1, 1, Bt, ft), this._envPlaceholder.needsUpdate = !0, this.environmentTexture = this._envPlaceholder, this.envTexSize = new sn(), this.envCDFTexture = null, this._initCDFTexture(), this.environmentRotationMatrix = new Ct(), this.cdfBuildTime = 0, this.envParams = {
1901
+ ]), 1, 1, Bt, ft, void 0, void 0, void 0, K, K), this._envPlaceholder.needsUpdate = !0, this.environmentTexture = this._envPlaceholder, this.envTexSize = new sn(), this.envCDFTexture = null, this._initCDFTexture(), this.environmentRotationMatrix = new Ct(), this.cdfBuildTime = 0, this.envParams = {
1896
1902
  mode: "hdri",
1897
1903
  gradientZenithColor: new tt(J.gradientZenithColor),
1898
1904
  gradientHorizonColor: new tt(J.gradientHorizonColor),
@@ -4693,7 +4699,6 @@ var Ws = /* @__PURE__ */ f(([e, t]) => {
4693
4699
  setMinImprovement(e) {
4694
4700
  this.minImprovement = Math.max(.001, e);
4695
4701
  }
4696
- setMaxTreelets() {}
4697
4702
  getStatistics() {
4698
4703
  return { ...this.stats };
4699
4704
  }
@@ -4902,7 +4907,7 @@ var rc = {
4902
4907
  reinsertionOptimizationTime: 0,
4903
4908
  reinsertionsApplied: 0,
4904
4909
  reinsertionIterations: 0
4905
- }, this.enableTreeletOptimization = !0, this.treeletSize = 5, this.treeletOptimizationPasses = 1, this.treeletMinImprovement = .02, this.maxTreeletDepth = 3, this.maxTreeletsPerScene = 20, this.treeletComplexityThreshold = 5e4, this.enableReinsertionOptimization = !0, this.reinsertionBatchSizeRatio = .02, this.reinsertionMaxIterations = 2, this.initializeBinArrays(), this._partResult = {
4910
+ }, this.enableTreeletOptimization = !0, 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 = {
4906
4911
  mid: 0,
4907
4912
  lMinX: 0,
4908
4913
  lMinY: 0,
@@ -4935,7 +4940,7 @@ var rc = {
4935
4940
  e.objectMedian !== void 0 && (this.enableObjectMedianFallback = e.objectMedian), e.spatialMedian !== void 0 && (this.enableSpatialMedianFallback = e.spatialMedian);
4936
4941
  }
4937
4942
  setTreeletConfig(e) {
4938
- 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));
4943
+ 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);
4939
4944
  }
4940
4945
  disableTreeletOptimization() {
4941
4946
  this.enableTreeletOptimization = !1;
@@ -5082,26 +5087,26 @@ var rc = {
5082
5087
  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();
5083
5088
  let s = performance.now(), c = this.buildNodeRecursive(0, a, t, n);
5084
5089
  if (this.splitStats.sahBuildTime = performance.now() - s, this.enableTreeletOptimization && this.totalTriangles > 1e3) {
5085
- let e = this.totalTriangles > this.treeletComplexityThreshold, t = e ? 3 : this.treeletSize, r = e ? 10 : this.maxTreeletsPerScene, i = new Zs(this.traversalCost, this.intersectionCost);
5086
- i.setTreeletSize(t), i.setMinImprovement(this.treeletMinImprovement), i.setMaxTreelets(r);
5087
- let a = performance.now();
5090
+ let e = this.totalTriangles > this.treeletComplexityThreshold ? 3 : this.treeletSize, t = new Zs(this.traversalCost, this.intersectionCost);
5091
+ t.setTreeletSize(e), t.setMinImprovement(this.treeletMinImprovement);
5092
+ let r = performance.now();
5088
5093
  for (let e = 0; e < this.treeletOptimizationPasses; e++) {
5089
- let t = n ? (t) => {
5094
+ let i = n ? (t) => {
5090
5095
  n(`Treelet optimization pass ${e + 1}/${this.treeletOptimizationPasses}: ${t}`);
5091
5096
  } : null;
5092
5097
  try {
5093
- i.optimizeBVH(c, t);
5098
+ t.optimizeBVH(c, i);
5094
5099
  } catch (t) {
5095
5100
  ec.error(`treelet optimizer failed in pass ${e + 1}:`, t);
5096
5101
  break;
5097
5102
  }
5098
- let r = i.getStatistics(), o = performance.now() - a;
5099
- if (r.treeletsImproved === 0 && e > 0 || o > 15e3) break;
5103
+ let a = t.getStatistics(), o = performance.now() - r;
5104
+ if (a.treeletsImproved === 0 && e > 0 || o > 15e3) break;
5100
5105
  }
5101
- let o = performance.now() - a;
5102
- this.splitStats.treeletOptimizationTime = o;
5103
- let s = i.getStatistics();
5104
- this.splitStats.treeletsProcessed = s.treeletsProcessed, this.splitStats.treeletsImproved = s.treeletsImproved, this.splitStats.averageSAHImprovement = s.averageSAHImprovement;
5106
+ let i = performance.now() - r;
5107
+ this.splitStats.treeletOptimizationTime = i;
5108
+ let a = t.getStatistics();
5109
+ this.splitStats.treeletsProcessed = a.treeletsProcessed, this.splitStats.treeletsImproved = a.treeletsImproved, this.splitStats.averageSAHImprovement = a.averageSAHImprovement;
5105
5110
  }
5106
5111
  if (this.enableReinsertionOptimization && this.totalTriangles > 1e3) {
5107
5112
  let e = new $s(this.traversalCost, this.intersectionCost);
@@ -5537,7 +5542,7 @@ var rc = {
5537
5542
  }
5538
5543
  }
5539
5544
  }
5540
- }, pc = "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)}setMaxTreelets(){}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={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},C=S.FLOATS_PER_TRIANGLE;var w=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}},T=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=!0,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.maxTreeletDepth=3,this.maxTreeletsPerScene=20,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))}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=this.triangles,n=S.POSITION_A_OFFSET,r=S.POSITION_B_OFFSET,i=S.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*C,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/(C*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/(C*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,n=t?3:this.treeletSize,r=t?10:this.maxTreeletsPerScene,a=new e(this.traversalCost,this.intersectionCost);a.setTreeletSize(n),a.setMinImprovement(this.treeletMinImprovement),a.setMaxTreelets(r);let o=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{a.optimizeBVH(u,t)}catch(t){x.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let n=a.getStatistics(),r=performance.now()-o;if(n.treeletsImproved===0&&e>0||r>15e3)break}let s=performance.now()-o;this.splitStats.treeletOptimizationTime=s;let c=a.getStatistics();this.splitStats.treeletsProcessed=c.treeletsProcessed,this.splitStats.treeletsImproved=c.treeletsImproved,this.splitStats.averageSAHImprovement=c.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 Float32Array(s*C);for(let e=0;e<s;e++){let t=this.indices[e]*C,n=e*C;m.set(p.subarray(t,t+C),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 w;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,T=m.rMinZ,E=m.rMaxX,D=m.rMaxY,O=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,T,E,D,O),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new w;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,T=p.rMaxX,E=p.rMaxY,D=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,T,E,D),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)}let r=new Float32Array(t.length*16);for(let e=0;e<t.length;e++){let n=t[e],i=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[i]=e.minX,r[i+1]=e.minY,r[i+2]=e.minZ,r[i+3]=e._flatIndex,r[i+4]=e.maxX,r[i+5]=e.maxY,r[i+6]=e.maxZ,r[i+7]=t._flatIndex,r[i+8]=t.minX,r[i+9]=t.minY,r[i+10]=t.minZ,r[i+12]=t.maxX,r[i+13]=t.maxY,r[i+14]=t.maxZ}else r[i]=n.triangleOffset,r[i+1]=n.triangleCount,r[i+3]=-1}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)}let r=new Float32Array(t.length*16),i=[];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,r[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,r[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 if(n.isFrontier){let t=n.frontierTaskId;r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+2]=t,r[a+3]=-2,i.push({taskId:t,flatIndex:e})}else r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+3]=-1}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;let o=new Float32Array(a*16);o.set(e);let s=new Map;for(let e of n)s.set(e.taskId,e.flatIndex);let c=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=c*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;o[t+3]!==-1&&(o[t+3]+=c,o[t+7]+=c)}let l=s.get(t.taskId);if(l!==void 0){let e=l*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}c+=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 E=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?D(t):n===`assemble`?O(t):k(t)};function D(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 T;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Float32Array(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;E.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){E.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function O(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 T().assembleParallelBVH(t,n,r,i),u=new Uint32Array(o),d=new Float32Array(a),f=new Float32Array(s);for(let e=0;e<c;e++){let t=u[e]*32,n=e*32;f.set(d.subarray(t,t+32),n)}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[u[e]]=e;let m=performance.now()-e;E.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){E.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function k(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 T;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 Float32Array(t):new Float32Array(t,n,r/4),u=c?new Float32Array(c):null,d=p.buildSync(l,i,e,u),f=performance.now(),m=p.flattenBVH(d),h=performance.now()-f;E.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/32,treeletStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/128,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){E.error(`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" });
5545
+ }, pc = "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={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},C=S.FLOATS_PER_TRIANGLE;var w=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}},T=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=!0,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=this.triangles,n=S.POSITION_A_OFFSET,r=S.POSITION_B_OFFSET,i=S.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*C,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/(C*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/(C*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 Float32Array(s*C);for(let e=0;e<s;e++){let t=this.indices[e]*C,n=e*C;m.set(p.subarray(t,t+C),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 w;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,T=m.rMinZ,E=m.rMaxX,D=m.rMaxY,O=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,T,E,D,O),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new w;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,T=p.rMaxX,E=p.rMaxY,D=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,T,E,D),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)}let r=new Float32Array(t.length*16);for(let e=0;e<t.length;e++){let n=t[e],i=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[i]=e.minX,r[i+1]=e.minY,r[i+2]=e.minZ,r[i+3]=e._flatIndex,r[i+4]=e.maxX,r[i+5]=e.maxY,r[i+6]=e.maxZ,r[i+7]=t._flatIndex,r[i+8]=t.minX,r[i+9]=t.minY,r[i+10]=t.minZ,r[i+12]=t.maxX,r[i+13]=t.maxY,r[i+14]=t.maxZ}else r[i]=n.triangleOffset,r[i+1]=n.triangleCount,r[i+3]=-1}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)}let r=new Float32Array(t.length*16),i=[];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,r[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,r[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 if(n.isFrontier){let t=n.frontierTaskId;r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+2]=t,r[a+3]=-2,i.push({taskId:t,flatIndex:e})}else r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+3]=-1}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;let o=new Float32Array(a*16);o.set(e);let s=new Map;for(let e of n)s.set(e.taskId,e.flatIndex);let c=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=c*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;o[t+3]!==-1&&(o[t+3]+=c,o[t+7]+=c)}let l=s.get(t.taskId);if(l!==void 0){let e=l*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}c+=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 E=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?D(t):n===`assemble`?O(t):k(t)};function D(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 T;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Float32Array(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;E.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){E.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function O(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 T().assembleParallelBVH(t,n,r,i),u=new Uint32Array(o),d=new Float32Array(a),f=new Float32Array(s);for(let e=0;e<c;e++){let t=u[e]*32,n=e*32;f.set(d.subarray(t,t+32),n)}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[u[e]]=e;let m=performance.now()-e;E.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){E.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function k(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 T;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 Float32Array(t):new Float32Array(t,n,r/4),u=c?new Float32Array(c):null,d=p.buildSync(l,i,e,u),f=performance.now(),m=p.flattenBVH(d),h=performance.now()-f;E.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/32,treeletStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/128,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){E.error(`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" });
5541
5546
  function hc(e) {
5542
5547
  let t;
5543
5548
  try {
@@ -5558,7 +5563,7 @@ function hc(e) {
5558
5563
  }
5559
5564
  //#endregion
5560
5565
  //#region src/Processor/Workers/BVHSubtreeWorker.js?worker&inline
5561
- var gc = "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)}setMaxTreelets(){}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={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},S=x.FLOATS_PER_TRIANGLE;var C=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}},w=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=!0,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.maxTreeletDepth=3,this.maxTreeletsPerScene=20,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))}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=this.triangles,n=x.POSITION_A_OFFSET,r=x.POSITION_B_OFFSET,i=x.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*S,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/(S*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/(S*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,n=t?3:this.treeletSize,r=t?10:this.maxTreeletsPerScene,a=new e(this.traversalCost,this.intersectionCost);a.setTreeletSize(n),a.setMinImprovement(this.treeletMinImprovement),a.setMaxTreelets(r);let o=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{a.optimizeBVH(u,t)}catch(t){b.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let n=a.getStatistics(),r=performance.now()-o;if(n.treeletsImproved===0&&e>0||r>15e3)break}let s=performance.now()-o;this.splitStats.treeletOptimizationTime=s;let c=a.getStatistics();this.splitStats.treeletsProcessed=c.treeletsProcessed,this.splitStats.treeletsImproved=c.treeletsImproved,this.splitStats.averageSAHImprovement=c.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 Float32Array(s*S);for(let e=0;e<s;e++){let t=this.indices[e]*S,n=e*S;m.set(p.subarray(t,t+S),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 C;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,w=m.rMinY,T=m.rMinZ,E=m.rMaxX,D=m.rMaxY,O=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,w,T,E,D,O),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new C;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,w=p.rMinZ,T=p.rMaxX,E=p.rMaxY,D=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,w,T,E,D),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)}let r=new Float32Array(t.length*16);for(let e=0;e<t.length;e++){let n=t[e],i=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[i]=e.minX,r[i+1]=e.minY,r[i+2]=e.minZ,r[i+3]=e._flatIndex,r[i+4]=e.maxX,r[i+5]=e.maxY,r[i+6]=e.maxZ,r[i+7]=t._flatIndex,r[i+8]=t.minX,r[i+9]=t.minY,r[i+10]=t.minZ,r[i+12]=t.maxX,r[i+13]=t.maxY,r[i+14]=t.maxZ}else r[i]=n.triangleOffset,r[i+1]=n.triangleCount,r[i+3]=-1}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)}let r=new Float32Array(t.length*16),i=[];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,r[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,r[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 if(n.isFrontier){let t=n.frontierTaskId;r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+2]=t,r[a+3]=-2,i.push({taskId:t,flatIndex:e})}else r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+3]=-1}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;let o=new Float32Array(a*16);o.set(e);let s=new Map;for(let e of n)s.set(e.taskId,e.flatIndex);let c=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=c*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;o[t+3]!==-1&&(o[t+3]+=c,o[t+7]+=c)}let l=s.get(t.taskId);if(l!==void 0){let e=l*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}c+=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 w;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})}}};", _c = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", gc], { type: "text/javascript;charset=utf-8" });
5566
+ var gc = "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={FLOATS_PER_TRIANGLE:32,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_OFFSET:12,NORMAL_B_OFFSET:16,NORMAL_C_OFFSET:20,UV_AB_OFFSET:24,UV_C_MAT_OFFSET:28},S=x.FLOATS_PER_TRIANGLE;var C=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}},w=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=!0,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=this.triangles,n=x.POSITION_A_OFFSET,r=x.POSITION_B_OFFSET,i=x.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*S,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/(S*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/(S*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 Float32Array(s*S);for(let e=0;e<s;e++){let t=this.indices[e]*S,n=e*S;m.set(p.subarray(t,t+S),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 C;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,w=m.rMinY,T=m.rMinZ,E=m.rMaxX,D=m.rMaxY,O=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,w,T,E,D,O),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new C;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,w=p.rMinZ,T=p.rMaxX,E=p.rMaxY,D=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,w,T,E,D),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)}let r=new Float32Array(t.length*16);for(let e=0;e<t.length;e++){let n=t[e],i=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[i]=e.minX,r[i+1]=e.minY,r[i+2]=e.minZ,r[i+3]=e._flatIndex,r[i+4]=e.maxX,r[i+5]=e.maxY,r[i+6]=e.maxZ,r[i+7]=t._flatIndex,r[i+8]=t.minX,r[i+9]=t.minY,r[i+10]=t.minZ,r[i+12]=t.maxX,r[i+13]=t.maxY,r[i+14]=t.maxZ}else r[i]=n.triangleOffset,r[i+1]=n.triangleCount,r[i+3]=-1}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)}let r=new Float32Array(t.length*16),i=[];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,r[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,r[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 if(n.isFrontier){let t=n.frontierTaskId;r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+2]=t,r[a+3]=-2,i.push({taskId:t,flatIndex:e})}else r[a]=n.triangleOffset,r[a+1]=n.triangleCount,r[a+3]=-1}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;let o=new Float32Array(a*16);o.set(e);let s=new Map;for(let e of n)s.set(e.taskId,e.flatIndex);let c=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=c*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;o[t+3]!==-1&&(o[t+3]+=c,o[t+7]+=c)}let l=s.get(t.taskId);if(l!==void 0){let e=l*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}c+=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 w;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})}}};", _c = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", gc], { type: "text/javascript;charset=utf-8" });
5562
5567
  function vc(e) {
5563
5568
  let t;
5564
5569
  try {
@@ -7385,6 +7390,7 @@ var Zc = ai("scene"), Qc = class {
7385
7390
  treeletSize: 7,
7386
7391
  treeletOptimizationPasses: 1,
7387
7392
  treeletMinImprovement: .01,
7393
+ treeletComplexityThreshold: 5e4,
7388
7394
  ...e
7389
7395
  }, this.triangleData = 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.bvhData = null, this.materialData = null, this.instanceTable = null, this.originalToBvhMap = null, this._refitWorker = null, this._refitSharedBuffers = null, this._rebuildGeneration = 0, this._pendingRebuilds = /* @__PURE__ */ 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.performanceMetrics = {
7390
7396
  textureCreationTime: 0,
@@ -7401,7 +7407,8 @@ var Zc = ai("scene"), Qc = class {
7401
7407
  enabled: this.config.enableTreeletOptimization,
7402
7408
  size: this.config.treeletSize,
7403
7409
  passes: this.config.treeletOptimizationPasses,
7404
- minImprovement: this.config.treeletMinImprovement
7410
+ minImprovement: this.config.treeletMinImprovement,
7411
+ complexityThreshold: this.config.treeletComplexityThreshold
7405
7412
  }), this.textureCreator = new Lc({ maxTextureSize: this.config.maxTextureSize }), this.emissiveTriangleBuilder = new Kc(), this.tlasBuilder = new kc();
7406
7413
  }
7407
7414
  _log(e, t) {
@@ -7489,7 +7496,8 @@ var Zc = ai("scene"), Qc = class {
7489
7496
  enabled: i !== !1,
7490
7497
  size: this.config.treeletSize,
7491
7498
  passes: this.config.treeletOptimizationPasses,
7492
- minImprovement: this.config.treeletMinImprovement
7499
+ minImprovement: this.config.treeletMinImprovement,
7500
+ complexityThreshold: this.config.treeletComplexityThreshold
7493
7501
  },
7494
7502
  reinsertionOptimization: {
7495
7503
  enabled: this.bvhBuilder.enableReinsertionOptimization,
@@ -7795,7 +7803,8 @@ var Zc = ai("scene"), Qc = class {
7795
7803
  enabled: this.config.enableTreeletOptimization,
7796
7804
  size: this.config.treeletSize,
7797
7805
  passes: this.config.treeletOptimizationPasses,
7798
- minImprovement: this.config.treeletMinImprovement
7806
+ minImprovement: this.config.treeletMinImprovement,
7807
+ complexityThreshold: this.config.treeletComplexityThreshold
7799
7808
  })), this._log("Configuration updated", this.config);
7800
7809
  }
7801
7810
  async refitBVH(e, t) {
@@ -7956,7 +7965,8 @@ var Zc = ai("scene"), Qc = class {
7956
7965
  enabled: s,
7957
7966
  size: this.config.treeletSize,
7958
7967
  passes: this.config.treeletOptimizationPasses,
7959
- minImprovement: this.config.treeletMinImprovement
7968
+ minImprovement: this.config.treeletMinImprovement,
7969
+ complexityThreshold: this.config.treeletComplexityThreshold
7960
7970
  },
7961
7971
  reinsertionOptimization: {
7962
7972
  enabled: this.bvhBuilder.enableReinsertionOptimization,
@@ -8745,7 +8755,7 @@ var vl = class {
8745
8755
  ACTIVE_RAY_COUNT: 0,
8746
8756
  ENTERING_COUNT: 1,
8747
8757
  CONVERGED_COUNT: 2,
8748
- FROZEN_COUNT: 3,
8758
+ RESERVED_3: 3,
8749
8759
  ACTIVE_PIXEL_COUNT: 4,
8750
8760
  COUNT: 5
8751
8761
  }, ru = {
@@ -8906,46 +8916,9 @@ var uu = class {
8906
8916
  let e = (e) => (e / 1048576).toFixed(1), t = Object.entries(this.byCategory).map(([t, n]) => `${t}=${e(n)}`);
8907
8917
  return `VRAM current=${e(this.current)}MB peak=${e(this.peak)}MB [${t.join(" ")}]`;
8908
8918
  }
8909
- }, du = ai("wavefront"), fu = {
8910
- generate: [
8911
- 16,
8912
- 16,
8913
- 1
8914
- ],
8915
- extend: [
8916
- 256,
8917
- 1,
8918
- 1
8919
- ],
8920
- shade: [
8921
- 256,
8922
- 1,
8923
- 1
8924
- ],
8925
- connect: [
8926
- 256,
8927
- 1,
8928
- 1
8929
- ],
8930
- accumulate: [
8931
- 256,
8932
- 1,
8933
- 1
8934
- ],
8935
- compact: [
8936
- 256,
8937
- 1,
8938
- 1
8939
- ],
8940
- finalWrite: [
8941
- 16,
8942
- 16,
8943
- 1
8944
- ]
8945
- }, pu = class {
8919
+ }, du = ai("wavefront"), fu = class {
8946
8920
  constructor(e) {
8947
- this.renderer = e, this.kernels = /* @__PURE__ */ new Map(), this.workgroupSizes = /* @__PURE__ */ new Map(), this.timing = /* @__PURE__ */ new Map(), this.profiling = !1, this.profile = /* @__PURE__ */ new Map(), this._firstDispatches = [], this._firstDispatchFlush = null;
8948
- for (let [e, t] of Object.entries(fu)) this.workgroupSizes.set(e, t);
8921
+ this.renderer = e, this.kernels = /* @__PURE__ */ new Map(), this.timing = /* @__PURE__ */ new Map(), this.profiling = !1, this.profile = /* @__PURE__ */ new Map(), this._firstDispatches = [], this._firstDispatchFlush = null;
8949
8922
  }
8950
8923
  _recordFirstDispatch(e, t) {
8951
8924
  this._firstDispatches.push({
@@ -8984,38 +8957,21 @@ var uu = class {
8984
8957
  }, this.profile.set(e, i)), i.calls++, i.totalMs += r - n;
8985
8958
  } else this.renderer.compute(t);
8986
8959
  }
8987
- setDispatchCount(e, t) {
8960
+ setDispatchForCount(e, t) {
8988
8961
  let n = this.kernels.get(e);
8989
- n && (n.dispatchSize = t);
8990
- }
8991
- calcScreenDispatch(e, t, n) {
8992
- let r = this.workgroupSizes.get(n) || [
8993
- 16,
8994
- 16,
8995
- 1
8996
- ];
8997
- return [
8998
- Math.ceil(e / r[0]),
8999
- Math.ceil(t / r[1]),
9000
- 1
9001
- ];
9002
- }
9003
- calcRayDispatch(e, t) {
9004
- let n = this.workgroupSizes.get(t) || [
9005
- 256,
9006
- 1,
9007
- 1
9008
- ];
9009
- return [
9010
- Math.ceil(e / n[0]),
8962
+ n && (n.dispatchSize = [
8963
+ Math.ceil(t / n.workgroupSize[0]),
9011
8964
  1,
9012
8965
  1
9013
- ];
8966
+ ]);
9014
8967
  }
9015
- getWorkgroupSize(e) {
9016
- return this.workgroupSizes.get(e) || [
9017
- 256,
9018
- 1,
8968
+ setDispatchForGrid(e, t, n) {
8969
+ let r = this.kernels.get(e);
8970
+ if (!r) return;
8971
+ let i = r.workgroupSize;
8972
+ r.dispatchSize = [
8973
+ Math.ceil(t / i[0]),
8974
+ Math.ceil(n / i[1]),
9019
8975
  1
9020
8976
  ];
9021
8977
  }
@@ -9051,7 +9007,66 @@ var uu = class {
9051
9007
  dispose() {
9052
9008
  clearTimeout(this._firstDispatchFlush), this._firstDispatchFlush = null, this._firstDispatches = [], this.kernels.clear(), this.timing.clear(), this.profile.clear();
9053
9009
  }
9054
- }, mu = 32, hu = 512, gu = 4, _u = 8, vu = 1e8, yu = () => y("int", mu).toVar(), bu = G("\n fn RayTriangleGeometry( rayOrigin: vec3f, rayDir: vec3f, pA: vec3f, pB: vec3f, pC: vec3f, closestHitDst: f32, woopParams: vec4f ) -> vec4f {\n\n // Returns vec4(t, u, v, hit) where hit > 0.5 means intersection.\n // woopParams: (Sx, Sy, Sz, bitcast<f32>(packed kx|ky<<2|kz<<4))\n var result = vec4f( 1e20f, 0.0f, 0.0f, 0.0f );\n\n let Sx = woopParams.x;\n let Sy = woopParams.y;\n let Sz = woopParams.z;\n // Packed as regular f32 (values 0–42), not bitcast — avoids subnormal FTZ on Apple GPUs.\n let packed = i32( woopParams.w );\n let kx = packed & 3;\n let ky = ( packed >> 2 ) & 3;\n let kz = ( packed >> 4 ) & 3;\n\n let A = pA - rayOrigin;\n let B = pB - rayOrigin;\n let C = pC - rayOrigin;\n\n let Akz = A[ kz ];\n let Bkz = B[ kz ];\n let Ckz = C[ kz ];\n\n let Ax = A[ kx ] - Sx * Akz;\n let Ay = A[ ky ] - Sy * Akz;\n let Bx = B[ kx ] - Sx * Bkz;\n let By = B[ ky ] - Sy * Bkz;\n let Cx = C[ kx ] - Sx * Ckz;\n let Cy = C[ ky ] - Sy * Ckz;\n\n // Edge function tests — all three must share sign (or be exactly zero) for hit.\n let U = Cx * By - Cy * Bx;\n let V = Ax * Cy - Ay * Cx;\n let W = Bx * Ay - By * Ax;\n\n let neg = U < 0.0f || V < 0.0f || W < 0.0f;\n let pos = U > 0.0f || V > 0.0f || W > 0.0f;\n if ( !( neg && pos ) ) {\n\n let det = U + V + W;\n if ( det != 0.0f ) {\n\n let T = U * ( Sz * Akz ) + V * ( Sz * Bkz ) + W * ( Sz * Ckz );\n\n // Sign-aware bounds check on t (multiply both sides by sign(det) once).\n let detSign = select( -1.0f, 1.0f, det > 0.0f );\n let tSigned = T * detSign;\n let detAbs = abs( det );\n\n if ( tSigned > 0.0f && tSigned < closestHitDst * detAbs ) {\n\n // Match Möller-Trumbore convention: u = weight of B, v = weight of C.\n // In Woop's edge functions, U → weight of A, V → weight of B, W → weight of C.\n let invDet = 1.0f / det;\n result = vec4f( T * invDet, V * invDet, W * invDet, 1.0f );\n\n }\n\n }\n\n }\n\n return result;\n\n }\n"), xu = G("\n fn computeWoopRayParams( rayDir: vec3f ) -> vec4f {\n\n let absDir = abs( rayDir );\n\n // kz = argmax(|dir|)\n var kz: i32 = 0;\n if ( absDir.y >= absDir.x ) { kz = 1; }\n if ( absDir.z >= absDir[ u32( kz ) ] ) { kz = 2; }\n\n var kx: i32 = ( kz + 1 ) % 3;\n var ky: i32 = ( kx + 1 ) % 3;\n\n // Preserve triangle winding when the dominant axis component is negative.\n if ( rayDir[ u32( kz ) ] < 0.0f ) {\n let tmp = kx;\n kx = ky;\n ky = tmp;\n }\n\n let dz = rayDir[ u32( kz ) ];\n let Sx = rayDir[ u32( kx ) ] / dz;\n let Sy = rayDir[ u32( ky ) ] / dz;\n let Sz = 1.0f / dz;\n\n let packed = kx | ( ky << 2 ) | ( kz << 4 );\n return vec4f( Sx, Sy, Sz, f32( packed ) );\n\n }\n"), Su = G("\n fn fastRayAABBDst( rayOrigin: vec3f, invDir: vec3f, boxMin: vec3f, boxMax: vec3f ) -> f32 {\n\n let t1 = ( boxMin - rayOrigin ) * invDir;\n let t2 = ( boxMax - rayOrigin ) * invDir;\n\n let tmin = min( t1, t2 );\n let tmax = max( t1, t2 );\n\n let tNear = max( max( tmin.x, tmin.y ), tmin.z );\n let tFar = min( min( tmax.x, tmax.y ), tmax.z ) * 1.00000024f; // Robust traversal: 2 ULP padding (Ize 2013)\n\n let isHit = tNear <= tFar && tFar > 0.0f;\n return select( 1e20f, max( tNear, 0.0f ), isHit );\n\n }\n"), Cu = (e) => f(([t, n, r, i]) => {
9010
+ }, pu = f(([e, t, n, r, i, a, o]) => {
9011
+ let s = U(0).toVar();
9012
+ return p(r.equal(N(1)), () => {
9013
+ let n = fe(i.x, i.y, e.x).toVar(), r = fe(a.y, a.x, e.y).toVar(), c = D(r).toVar(), l = U(0).toVar(), u = U(0).toVar(), d = U(0).toVar();
9014
+ p(o.equal(N(1)), () => {
9015
+ let e = U(t[2].x, 0, t[2].z).toVar();
9016
+ p(A(e, e).lessThan(j(1e-8)), () => {
9017
+ e.assign(U(t[1].x, 0, t[1].z));
9018
+ }), d.assign(I(e)), u.assign(U(0, 1, 0)), l.assign(O(u, d));
9019
+ }).Else(() => {
9020
+ l.assign(I(U(t[0]))), u.assign(I(U(t[1]))), d.assign(I(U(t[2])));
9021
+ }), s.assign(I(l.mul(Se(n).mul(c)).add(u.mul(Se(r))).sub(d.mul(D(n).mul(c)))));
9022
+ }).Else(() => {
9023
+ let r = U(e.x.mul(2).sub(1), j(1).sub(e.y.mul(2)), 1), i = n.mul(W(r, 1));
9024
+ s.assign(I(ue(t[0].xyz, t[1].xyz, t[2].xyz).mul(i.xyz.div(i.w))));
9025
+ }), s;
9026
+ }), mu = f(([e, t, n, r, i, a, o, s, c, l, u, d, f, m, h]) => {
9027
+ let g = U(n[3]).toVar(), _ = pu(e, n, r, i, a, o, s).toVar(), v = g.toVar(), y = _.toVar();
9028
+ return p(c.and(l.greaterThan(0)).and(u.lessThan(64)).and(d.greaterThan(.001)), () => {
9029
+ let e = l.div(u).mul(.001).mul(f).mul(m), r = qn(t), a = r.x.mul(h.max(.01)), o = r.y, s = U(0).toVar();
9030
+ p(i.equal(N(1)), () => {
9031
+ s.assign(ja({ N: _ }).mul(U(a, o, 0)));
9032
+ }).Else(() => {
9033
+ let e = I(U(n[0])), t = I(U(n[1]));
9034
+ s.assign(e.mul(a).add(t.mul(o)));
9035
+ }), v.assign(g.add(s.mul(e))), y.assign(I(g.add(_.mul(d)).sub(v)));
9036
+ }), ea({
9037
+ origin: v,
9038
+ direction: y
9039
+ });
9040
+ });
9041
+ function hu(e) {
9042
+ let { rayBufferRW: t, rngBufferRW: n, gBufferRW: r, resolution: i, frame: a, cameraWorldMatrix: o, cameraProjectionMatrixInverse: s, cameraProjection: c, panoLonRange: l, panoLatRange: u, panoLevelHorizon: d, enableDOF: m, focalLength: h, aperture: g, focusDistance: _, sceneScale: v, apertureScale: y, anamorphicRatio: b, renderWidth: x, chunkRowBase: C, chunkRows: w, transmissiveBounces: T, transparentBackground: E, auxGBufferEnabled: D, listDriven: O = !1, activeIndicesRO: k = null, counters: A = null } = e, ee = D.greaterThan(z(0)), te = (e, f, x) => {
9043
+ let S = H(j(e).add(.5), j(f).add(.5)), C = Un({ state: sr({
9044
+ pixelCoord: S,
9045
+ rayIndex: N(0),
9046
+ frame: a
9047
+ }).toVar() }).toVar(), w = or(S, N(1), N(1), C, i, a).toVar().sub(.5), D = H(S.x.add(w.x), S.y.sub(w.y)).div(i), O = ea.wrap(mu(D, C, o, s, c, l, u, d, m, h, g, _, v, y, b));
9048
+ Ml(t, x, O.origin, N(0), N(0)), Nl(t, x, O.direction, z(ru.ACTIVE)), Pl(t, x, W(1, 1, 1, 0).xyz, j(0)), Fl(t, x, W(U(0), L(E, j(1), j(0)))), p(ee, () => {
9049
+ El(r, x, U(0, 0, 1), j(1), U(0)), Yl(t, x, U(1));
9050
+ }), Ul(t, x, z(0), z(T), j(1), j(1), j(1)), n.element(x).assign(C);
9051
+ };
9052
+ return f(() => {
9053
+ if (O) {
9054
+ let e = M;
9055
+ p(e.lessThan(S(A.element(z(nu.ENTERING_COUNT)))), () => {
9056
+ let t = N(k.element(e)), n = t.add(C.mul(x));
9057
+ te(n.mod(x), n.div(x), z(t));
9058
+ });
9059
+ } else {
9060
+ let e = N(He.x).mul(16).add(N(se.x)), t = N(He.y).mul(16).add(N(se.y));
9061
+ p(e.lessThan(x).and(t.lessThan(w)), () => {
9062
+ te(e, t.add(C), z(t.mul(x).add(e)));
9063
+ });
9064
+ }
9065
+ });
9066
+ }
9067
+ //#endregion
9068
+ //#region src/TSL/BVHTraversal.js
9069
+ var gu = 32, _u = 512, vu = 4, yu = 8, bu = 1e8, xu = () => y("int", gu).toVar(), Su = G("\n fn RayTriangleGeometry( rayOrigin: vec3f, rayDir: vec3f, pA: vec3f, pB: vec3f, pC: vec3f, closestHitDst: f32, woopParams: vec4f ) -> vec4f {\n\n // Returns vec4(t, u, v, hit) where hit > 0.5 means intersection.\n // woopParams: (Sx, Sy, Sz, bitcast<f32>(packed kx|ky<<2|kz<<4))\n var result = vec4f( 1e20f, 0.0f, 0.0f, 0.0f );\n\n let Sx = woopParams.x;\n let Sy = woopParams.y;\n let Sz = woopParams.z;\n // Packed as regular f32 (values 0–42), not bitcast — avoids subnormal FTZ on Apple GPUs.\n let packed = i32( woopParams.w );\n let kx = packed & 3;\n let ky = ( packed >> 2 ) & 3;\n let kz = ( packed >> 4 ) & 3;\n\n let A = pA - rayOrigin;\n let B = pB - rayOrigin;\n let C = pC - rayOrigin;\n\n let Akz = A[ kz ];\n let Bkz = B[ kz ];\n let Ckz = C[ kz ];\n\n let Ax = A[ kx ] - Sx * Akz;\n let Ay = A[ ky ] - Sy * Akz;\n let Bx = B[ kx ] - Sx * Bkz;\n let By = B[ ky ] - Sy * Bkz;\n let Cx = C[ kx ] - Sx * Ckz;\n let Cy = C[ ky ] - Sy * Ckz;\n\n // Edge function tests — all three must share sign (or be exactly zero) for hit.\n let U = Cx * By - Cy * Bx;\n let V = Ax * Cy - Ay * Cx;\n let W = Bx * Ay - By * Ax;\n\n let neg = U < 0.0f || V < 0.0f || W < 0.0f;\n let pos = U > 0.0f || V > 0.0f || W > 0.0f;\n if ( !( neg && pos ) ) {\n\n let det = U + V + W;\n if ( det != 0.0f ) {\n\n let T = U * ( Sz * Akz ) + V * ( Sz * Bkz ) + W * ( Sz * Ckz );\n\n // Sign-aware bounds check on t (multiply both sides by sign(det) once).\n let detSign = select( -1.0f, 1.0f, det > 0.0f );\n let tSigned = T * detSign;\n let detAbs = abs( det );\n\n if ( tSigned > 0.0f && tSigned < closestHitDst * detAbs ) {\n\n // Match Möller-Trumbore convention: u = weight of B, v = weight of C.\n // In Woop's edge functions, U → weight of A, V → weight of B, W → weight of C.\n let invDet = 1.0f / det;\n result = vec4f( T * invDet, V * invDet, W * invDet, 1.0f );\n\n }\n\n }\n\n }\n\n return result;\n\n }\n"), Cu = G("\n fn computeWoopRayParams( rayDir: vec3f ) -> vec4f {\n\n let absDir = abs( rayDir );\n\n // kz = argmax(|dir|)\n var kz: i32 = 0;\n if ( absDir.y >= absDir.x ) { kz = 1; }\n if ( absDir.z >= absDir[ u32( kz ) ] ) { kz = 2; }\n\n var kx: i32 = ( kz + 1 ) % 3;\n var ky: i32 = ( kx + 1 ) % 3;\n\n // Preserve triangle winding when the dominant axis component is negative.\n if ( rayDir[ u32( kz ) ] < 0.0f ) {\n let tmp = kx;\n kx = ky;\n ky = tmp;\n }\n\n let dz = rayDir[ u32( kz ) ];\n let Sx = rayDir[ u32( kx ) ] / dz;\n let Sy = rayDir[ u32( ky ) ] / dz;\n let Sz = 1.0f / dz;\n\n let packed = kx | ( ky << 2 ) | ( kz << 4 );\n return vec4f( Sx, Sy, Sz, f32( packed ) );\n\n }\n"), wu = G("\n fn fastRayAABBDst( rayOrigin: vec3f, invDir: vec3f, boxMin: vec3f, boxMax: vec3f ) -> f32 {\n\n let t1 = ( boxMin - rayOrigin ) * invDir;\n let t2 = ( boxMax - rayOrigin ) * invDir;\n\n let tmin = min( t1, t2 );\n let tmax = max( t1, t2 );\n\n let tNear = max( max( tmin.x, tmin.y ), tmin.z );\n let tFar = min( min( tmax.x, tmax.y ), tmax.z ) * 1.00000024f; // Robust traversal: 2 ULP padding (Ize 2013)\n\n let isHit = tNear <= tFar && tFar > 0.0f;\n return select( 1e20f, max( tNear, 0.0f ), isHit );\n\n }\n"), Tu = (e) => f(([t, n, r, i]) => {
9055
9070
  let a = i ?? T(!1), o = aa({
9056
9071
  didHit: !1,
9057
9072
  dst: j(0x56bc75e2d63100000),
@@ -9062,12 +9077,12 @@ var uu = class {
9062
9077
  meshIndex: N(-1),
9063
9078
  boxTests: N(0),
9064
9079
  triTests: N(0)
9065
- }).toVar(), s = N(-1).toVar(), c = j(0).toVar(), l = j(0).toVar(), u = yu(), f = N(1).toVar();
9080
+ }).toVar(), s = N(-1).toVar(), c = j(0).toVar(), l = j(0).toVar(), u = xu(), f = N(1).toVar();
9066
9081
  u.element(N(0)).assign(N(0));
9067
- let h = fe(U(1), xe(t.direction), me(t.direction, U(0))), g = fe(U(1).div(t.direction), U(vu).mul(h), oe(_(t.direction), U(1e-8))).toVar(), v = t.origin, y = t.direction, b = xu({ rayDir: y }).toVar(), x = N(0).toVar();
9068
- return m(f.greaterThan(N(0)).and(x.lessThan(N(hu))), () => {
9082
+ let h = fe(U(1), xe(t.direction), me(t.direction, U(0))), g = fe(U(1).div(t.direction), U(bu).mul(h), oe(_(t.direction), U(1e-8))).toVar(), v = t.origin, y = t.direction, b = Cu({ rayDir: y }).toVar(), x = N(0).toVar();
9083
+ return m(f.greaterThan(N(0)).and(x.lessThan(N(_u))), () => {
9069
9084
  x.addAssign(1), f.subAssign(1);
9070
- let t = u.element(f).toVar(), i = $(n, t, N(0), N(gu));
9085
+ let t = u.element(f).toVar(), i = $(n, t, N(0), N(vu));
9071
9086
  e && o.boxTests.addAssign(1), p(i.w.lessThan(0), () => {
9072
9087
  p(i.w.greaterThan(j(-1.5)), () => {
9073
9088
  let t = N(i.x).toVar(), n = N(i.y).toVar();
@@ -9076,7 +9091,7 @@ var uu = class {
9076
9091
  end: n
9077
9092
  }, ({ i: n }) => {
9078
9093
  e && o.triTests.addAssign(1);
9079
- let i = t.add(n).toVar(), u = $(r, i, N(0), N(_u)).xyz, d = $(r, i, N(1), N(_u)).xyz, f = $(r, i, N(2), N(_u)).xyz, m = bu({
9094
+ let i = t.add(n).toVar(), u = $(r, i, N(0), N(yu)).xyz, d = $(r, i, N(1), N(yu)).xyz, f = $(r, i, N(2), N(yu)).xyz, m = Su({
9080
9095
  rayOrigin: v,
9081
9096
  rayDir: y,
9082
9097
  pA: u,
@@ -9086,7 +9101,7 @@ var uu = class {
9086
9101
  woopParams: b
9087
9102
  });
9088
9103
  p(m.w.greaterThan(.5), () => {
9089
- let e = m.x, t = m.y, n = m.z, u = $(r, i, N(3), N(_u)).xyz, d = $(r, i, N(4), N(_u)).xyz, f = $(r, i, N(5), N(_u)), h = f.xyz, g = N(f.w).toVar(), _ = j(1).sub(t).sub(n), v = y.dot(I(u.mul(_).add(d.mul(t)).add(h.mul(n))));
9104
+ let e = m.x, t = m.y, n = m.z, u = $(r, i, N(3), N(yu)).xyz, d = $(r, i, N(4), N(yu)).xyz, f = $(r, i, N(5), N(yu)), h = f.xyz, g = N(f.w).toVar(), _ = j(1).sub(t).sub(n), v = y.dot(I(u.mul(_).add(d.mul(t)).add(h.mul(n))));
9090
9105
  p(a.or(g.equal(N(2))).or(g.equal(N(0)).and(v.lessThan(-1e-4))).or(g.equal(N(1)).and(v.greaterThan(1e-4))), () => {
9091
9106
  o.didHit.assign(!0), o.dst.assign(e), s.assign(i), c.assign(t), l.assign(n);
9092
9107
  });
@@ -9095,17 +9110,17 @@ var uu = class {
9095
9110
  d();
9096
9111
  });
9097
9112
  }).Else(() => {
9098
- p(i.z.greaterThan(.5).and(f.lessThan(N(mu))), () => {
9113
+ p(i.z.greaterThan(.5).and(f.lessThan(N(gu))), () => {
9099
9114
  u.element(f).assign(N(i.x)), f.addAssign(1);
9100
9115
  });
9101
9116
  });
9102
9117
  }).Else(() => {
9103
- let e = $(n, t, N(1), N(gu)), r = $(n, t, N(2), N(gu)), a = $(n, t, N(3), N(gu)), s = N(i.w).toVar(), c = N(e.w).toVar(), l = Su({
9118
+ let e = $(n, t, N(1), N(vu)), r = $(n, t, N(2), N(vu)), a = $(n, t, N(3), N(vu)), s = N(i.w).toVar(), c = N(e.w).toVar(), l = wu({
9104
9119
  rayOrigin: v,
9105
9120
  invDir: g,
9106
9121
  boxMin: i.xyz,
9107
9122
  boxMax: e.xyz
9108
- }).toVar(), d = Su({
9123
+ }).toVar(), d = wu({
9109
9124
  rayOrigin: v,
9110
9125
  invDir: g,
9111
9126
  boxMin: r.xyz,
@@ -9113,21 +9128,21 @@ var uu = class {
9113
9128
  }).toVar();
9114
9129
  p(de(l, d).lessThan(o.dst), () => {
9115
9130
  let e = l.lessThan(d);
9116
- p(L(e, d, l).lessThan(o.dst).and(f.lessThan(N(mu))), () => {
9131
+ p(L(e, d, l).lessThan(o.dst).and(f.lessThan(N(gu))), () => {
9117
9132
  u.element(f).assign(L(e, c, s)), f.addAssign(1);
9118
- }), p(f.lessThan(N(mu)), () => {
9133
+ }), p(f.lessThan(N(gu)), () => {
9119
9134
  u.element(f).assign(L(e, s, c)), f.addAssign(1);
9120
9135
  });
9121
9136
  });
9122
9137
  });
9123
9138
  }), p(o.didHit, () => {
9124
9139
  o.hitPoint.assign(t.origin.add(t.direction.mul(o.dst)));
9125
- let e = j(1).sub(c).sub(l), n = $(r, s, N(3), N(_u)).xyz, i = $(r, s, N(4), N(_u)).xyz, a = $(r, s, N(5), N(_u)).xyz;
9140
+ let e = j(1).sub(c).sub(l), n = $(r, s, N(3), N(yu)).xyz, i = $(r, s, N(4), N(yu)).xyz, a = $(r, s, N(5), N(yu)).xyz;
9126
9141
  o.normal.assign(I(n.mul(e).add(i.mul(c)).add(a.mul(l))));
9127
- let u = $(r, s, N(6), N(_u)), d = $(r, s, N(7), N(_u));
9142
+ let u = $(r, s, N(6), N(yu)), d = $(r, s, N(7), N(yu));
9128
9143
  o.uv.assign(u.xy.mul(e).add(u.zw.mul(c)).add(d.xy.mul(l))), o.materialIndex.assign(N(d.z)), o.meshIndex.assign(N(d.w)), o.triangleIndex.assign(s);
9129
9144
  }), o;
9130
- }), wu = /* @__PURE__ */ Cu(!1), Tu = /* @__PURE__ */ Cu(!0), Eu = f(([e, t, n, r]) => {
9145
+ }), Eu = /* @__PURE__ */ Tu(!1), Du = /* @__PURE__ */ Tu(!0), Ou = f(([e, t, n, r]) => {
9131
9146
  let i = aa({
9132
9147
  didHit: !1,
9133
9148
  dst: r,
@@ -9138,12 +9153,12 @@ var uu = class {
9138
9153
  meshIndex: N(-1),
9139
9154
  boxTests: N(0),
9140
9155
  triTests: N(0)
9141
- }).toVar(), a = yu(), o = N(1).toVar();
9156
+ }).toVar(), a = xu(), o = N(1).toVar();
9142
9157
  a.element(N(0)).assign(N(0));
9143
- let s = fe(U(1), xe(e.direction), me(e.direction, U(0))), c = fe(U(1).div(e.direction), U(vu).mul(s), oe(_(e.direction), U(1e-8))).toVar(), l = xu({ rayDir: e.direction }).toVar(), u = N(0).toVar();
9144
- return m(o.greaterThan(N(0)).and(i.didHit.not()).and(u.lessThan(N(hu))), () => {
9158
+ let s = fe(U(1), xe(e.direction), me(e.direction, U(0))), c = fe(U(1).div(e.direction), U(bu).mul(s), oe(_(e.direction), U(1e-8))).toVar(), l = Cu({ rayDir: e.direction }).toVar(), u = N(0).toVar();
9159
+ return m(o.greaterThan(N(0)).and(i.didHit.not()).and(u.lessThan(N(_u))), () => {
9145
9160
  u.addAssign(1), o.subAssign(1);
9146
- let r = a.element(o).toVar(), s = $(t, r, N(0), N(gu));
9161
+ let r = a.element(o).toVar(), s = $(t, r, N(0), N(vu));
9147
9162
  p(s.w.lessThan(0), () => {
9148
9163
  p(s.w.greaterThan(j(-1.5)), () => {
9149
9164
  let t = N(s.x).toVar(), r = N(s.y).toVar();
@@ -9151,7 +9166,7 @@ var uu = class {
9151
9166
  start: N(0),
9152
9167
  end: r
9153
9168
  }, ({ i: r }) => {
9154
- let a = t.add(r).toVar(), o = $(n, a, N(0), N(_u)).xyz, s = $(n, a, N(1), N(_u)).xyz, c = $(n, a, N(2), N(_u)).xyz, u = bu({
9169
+ let a = t.add(r).toVar(), o = $(n, a, N(0), N(yu)).xyz, s = $(n, a, N(1), N(yu)).xyz, c = $(n, a, N(2), N(yu)).xyz, u = Su({
9155
9170
  rayOrigin: e.origin,
9156
9171
  rayDir: e.direction,
9157
9172
  pA: o,
@@ -9161,22 +9176,22 @@ var uu = class {
9161
9176
  woopParams: l
9162
9177
  });
9163
9178
  p(u.w.greaterThan(.5), () => {
9164
- let t = $(n, a, N(7), N(_u));
9179
+ let t = $(n, a, N(7), N(yu));
9165
9180
  i.didHit.assign(!0), i.dst.assign(u.x), i.materialIndex.assign(N(t.z)), i.meshIndex.assign(N(t.w)), i.hitPoint.assign(e.origin.add(e.direction.mul(u.x))), i.uv.assign(H(u.y, u.z)), i.triangleIndex.assign(a), d();
9166
9181
  });
9167
9182
  });
9168
9183
  }).Else(() => {
9169
- p(s.z.greaterThan(.5).and(o.lessThan(N(mu))), () => {
9184
+ p(s.z.greaterThan(.5).and(o.lessThan(N(gu))), () => {
9170
9185
  a.element(o).assign(N(s.x)), o.addAssign(1);
9171
9186
  });
9172
9187
  });
9173
9188
  }).Else(() => {
9174
- let n = $(t, r, N(1), N(gu)), l = $(t, r, N(2), N(gu)), u = $(t, r, N(3), N(gu)), d = N(s.w).toVar(), f = N(n.w).toVar(), m = Su({
9189
+ let n = $(t, r, N(1), N(vu)), l = $(t, r, N(2), N(vu)), u = $(t, r, N(3), N(vu)), d = N(s.w).toVar(), f = N(n.w).toVar(), m = wu({
9175
9190
  rayOrigin: e.origin,
9176
9191
  invDir: c,
9177
9192
  boxMin: s.xyz,
9178
9193
  boxMax: n.xyz
9179
- }).toVar(), h = Su({
9194
+ }).toVar(), h = wu({
9180
9195
  rayOrigin: e.origin,
9181
9196
  invDir: c,
9182
9197
  boxMin: l.xyz,
@@ -9184,66 +9199,33 @@ var uu = class {
9184
9199
  }).toVar();
9185
9200
  p(de(m, h).lessThan(i.dst), () => {
9186
9201
  let e = m.lessThan(h);
9187
- p(L(e, h, m).lessThan(i.dst).and(o.lessThan(N(mu))), () => {
9202
+ p(L(e, h, m).lessThan(i.dst).and(o.lessThan(N(gu))), () => {
9188
9203
  a.element(o).assign(L(e, f, d)), o.addAssign(1);
9189
- }), p(o.lessThan(N(mu)), () => {
9204
+ }), p(o.lessThan(N(gu)), () => {
9190
9205
  a.element(o).assign(L(e, d, f)), o.addAssign(1);
9191
9206
  });
9192
9207
  });
9193
9208
  });
9194
9209
  }), i;
9195
- }), Du = f(([e, t, n, r, i, a, o, s, c, l, u]) => {
9196
- let d = U(e.xy, 1), f = r.mul(W(d, 1)), m = I(ue(n[0].xyz, n[1].xyz, n[2].xyz).mul(f.xyz.div(f.w))).toVar(), h = U(n[3]).toVar(), g = h.toVar(), _ = m.toVar();
9197
- return p(i.and(a.greaterThan(0)).and(o.lessThan(64)).and(s.greaterThan(.001)), () => {
9198
- let e = a.div(o).mul(.001).mul(c).mul(l), r = qn(t), i = r.x.mul(u.max(.01)), d = r.y, f = I(U(n[0])), p = I(U(n[1])), v = f.mul(i).add(p.mul(d)).mul(e);
9199
- g.assign(h.add(v)), _.assign(I(h.add(m.mul(s)).sub(g)));
9200
- }), ea({
9201
- origin: g,
9202
- direction: _
9203
- });
9204
9210
  });
9205
- function Ou(e) {
9206
- let { rayBufferRW: t, rngBufferRW: n, gBufferRW: r, resolution: i, frame: a, cameraWorldMatrix: o, cameraProjectionMatrixInverse: s, enableDOF: c, focalLength: l, aperture: u, focusDistance: d, sceneScale: m, apertureScale: h, anamorphicRatio: g, renderWidth: _, chunkRowBase: v, chunkRows: y, transmissiveBounces: b, transparentBackground: x, auxGBufferEnabled: C, listDriven: w = !1, activeIndicesRO: T = null, counters: E = null } = e, D = C.greaterThan(z(0)), O = (e, f, _) => {
9207
- let v = H(j(e).add(.5), j(f).add(.5)), y = v.div(i).mul(2).sub(1).toVar();
9208
- y.y.assign(y.y.negate());
9209
- let S = Un({ state: sr({
9210
- pixelCoord: v,
9211
- rayIndex: N(0),
9212
- frame: a
9213
- }).toVar() }).toVar(), C = or(v, N(1), N(1), S, i, a).toVar(), w = H(2).div(i), T = C.sub(.5).mul(w), E = y.add(T), O = ea.wrap(Du(E, S, o, s, c, l, u, d, m, h, g));
9214
- Ml(t, _, O.origin, N(0), N(0)), Nl(t, _, O.direction, z(ru.ACTIVE)), Pl(t, _, W(1, 1, 1, 0).xyz, j(0)), Fl(t, _, W(U(0), L(x, j(1), j(0)))), p(D, () => {
9215
- El(r, _, U(0, 0, 1), j(1), U(0)), Yl(t, _, U(1));
9216
- }), Ul(t, _, z(0), z(b), j(1), j(1), j(1)), n.element(_).assign(S);
9217
- };
9218
- return f(() => {
9219
- if (w) {
9220
- let e = M;
9221
- p(e.lessThan(S(E.element(z(nu.ENTERING_COUNT)))), () => {
9222
- let t = N(T.element(e)), n = t.add(v.mul(_));
9223
- O(n.mod(_), n.div(_), z(t));
9224
- });
9225
- } else {
9226
- let e = N(He.x).mul(16).add(N(se.x)), t = N(He.y).mul(16).add(N(se.y));
9227
- p(e.lessThan(_).and(t.lessThan(y)), () => {
9228
- O(e, t.add(v), z(t.mul(_).add(e)));
9229
- });
9230
- }
9231
- });
9232
- }
9233
9211
  //#endregion
9234
9212
  //#region src/TSL/ExtendKernel.js
9235
9213
  function ku(e) {
9236
- let { bvhBuffer: t, triangleBuffer: n, materialBuffer: r, rayBufferRO: i, hitBufferRW: a, activeIndicesRO: o, counters: s, maxRayCount: c } = e;
9214
+ let { bvhBuffer: t, triangleBuffer: n, rayBufferRO: r, hitBufferRW: i, activeIndicesRO: a, counters: o, maxRayCount: s } = e;
9237
9215
  return f(() => {
9238
- let e = M, r = s ? S(s.element(z(nu.ENTERING_COUNT))) : c;
9239
- p(e.greaterThanEqual(r), () => {
9216
+ let e = M, c = o ? S(o.element(z(nu.ENTERING_COUNT))) : s;
9217
+ p(e.greaterThanEqual(c), () => {
9240
9218
  h();
9241
9219
  });
9242
- let l = o.element(e), u = ea({
9243
- origin: yl(i, l).toVar(),
9244
- direction: bl(i, l).toVar()
9245
- }), d = Hl(i, l).stackDepth.greaterThan(z(0)), f = aa.wrap(wu(u, t, n, d)).toVar();
9246
- Vl(a, l, f.dst, z(f.triangleIndex), f.uv.x, f.uv.y, f.normal, z(f.materialIndex), z(f.meshIndex));
9220
+ let l = a.element(e);
9221
+ p(xl(r, l).bitAnd(z(ru.ACTIVE)).equal(z(0)), () => {
9222
+ h();
9223
+ });
9224
+ let u = ea({
9225
+ origin: yl(r, l).toVar(),
9226
+ direction: bl(r, l).toVar()
9227
+ }), d = Hl(r, l).stackDepth.greaterThan(z(0)), f = aa.wrap(Eu(u, t, n, d)).toVar();
9228
+ Vl(i, l, f.dst, z(f.triangleIndex), f.uv.x, f.uv.y, f.normal, z(f.materialIndex), z(f.meshIndex));
9247
9229
  });
9248
9230
  }
9249
9231
  //#endregion
@@ -9528,7 +9510,7 @@ var Au = /* @__PURE__ */ G("\n fn equirectDirectionToUv( direction: vec3f, envir
9528
9510
  selectionTotalWeight: A
9529
9511
  });
9530
9512
  }), Ku = f(([e, t]) => F(bo(e, t), 1e-8)), qu = f(([e, t, n, r]) => Ku(r, la.wrap(Na(n, e, t, r)))), Ju = f(([e, t, n, r, i, a, o, s, c, l, u, d, h, g, _, v, y, b, x, S, C, w, T, E, D, O, k, ee, te, ne, re, ie, M]) => {
9531
- let P = U(0).toVar(), ae = U(0).toVar(), oe = e.add(t.mul(.001)).toVar(), se = f(([e, t, n]) => ys(e, t, n, Eu, w, T, E));
9513
+ let P = U(0).toVar(), ae = U(0).toVar(), oe = e.add(t.mul(.001)).toVar(), se = f(([e, t, n]) => ys(e, t, n, Ou, w, T, E));
9532
9514
  return p(n.emissiveIntensity.lessThanEqual(10), () => {
9533
9515
  let e = _.add(y).add(x).add(C).toVar(), f = e.greaterThan(N(0)).toVar(), w = j(0).toVar();
9534
9516
  p(f, () => {
@@ -10417,7 +10399,7 @@ function Bd(e) {
10417
10399
  });
10418
10400
  let Jt = ia.wrap(Ju(ut, dt, q, Lt, Ut, Gt, Wt, st, Ye, Qe, je, Ae, $e, ie, P, oe, se, le, ue, de, pe, t, n, r, g, _, v, i, te, ne, re, y, T(!1))).shadowed.toVar(), Yt = L(st.greaterThan(0), Ee, j(1));
10419
10401
  qe.assign(W(qe.xyz.add(Zu(Ke.mul(Jt).mul(Yt), j(st), ke, N(R))), qe.w)), Ve && p(Ie.equal(N(1)).and(Ne.greaterThan(N(0))), () => {
10420
- let e = f(([e, i, a]) => ys(e, i, a, Eu, t, n, r));
10402
+ let e = f(([e, i, a]) => ys(e, i, a, Ou, t, n, r));
10421
10403
  p(Le.greaterThan(N(0)), () => {
10422
10404
  let t = cd.wrap(Pd(ut, dt, Ye, Qe, je, Ae, $e, a, a, Pe, n));
10423
10405
  p(t.valid.and(t.pdf.greaterThan(0)), () => {
@@ -10485,50 +10467,46 @@ function Hd(e) {
10485
10467
  }
10486
10468
  var Ud = /* @__PURE__ */ G("\n fn nanInfToRed( c: vec3f ) -> vec3f {\n let isNan = c.x != c.x || c.y != c.y || c.z != c.z;\n let isInf = abs( c.x ) > 1e30f || abs( c.y ) > 1e30f || abs( c.z ) > 1e30f;\n if ( isNan || isInf ) { return vec3f( 1.0f, 0.0f, 0.0f ); }\n return vec3f( 0.0f );\n }\n");
10487
10469
  function Wd(e) {
10488
- let { rayBufferRO: t, gBufferRO: n, writeColorTex: r, writeNDTex: i, writeAlbedoTex: a, resolution: o, frame: s, enableAccumulation: c, hasPreviousAccumulated: l, accumulationAlpha: u, cameraIsMoving: d, transparentBackground: m, prevAccumTexture: h, prevAlbedoTexture: g, prevNormalDepthTexture: _, renderWidth: v, chunkRowBase: y, chunkRows: b, visMode: S, auxGBufferEnabled: C, cleanAuxNormalEnabled: w, counters: T, m2BufferRW: E, useAdaptiveSampling: D, noiseThreshold: O, adaptiveMinSamples: k, usePixelFreeze: A, pixelFreezeThreshold: ee, pixelFreezeStability: te, streakBufferRW: ne, frozenMaskRO: re } = e, ie = C.greaterThan(z(0)), M = w.greaterThan(z(0)), P = D.greaterThan(N(0)), oe = A.greaterThan(N(0));
10470
+ let { rayBufferRO: t, gBufferRO: n, writeColorTex: r, writeNDTex: i, writeAlbedoTex: a, resolution: o, frame: s, enableAccumulation: c, hasPreviousAccumulated: l, accumulationAlpha: u, cameraIsMoving: d, transparentBackground: m, prevAccumTexture: h, prevAlbedoTexture: g, prevNormalDepthTexture: _, renderWidth: v, chunkRowBase: y, chunkRows: b, visMode: S, auxGBufferEnabled: C, cleanAuxNormalEnabled: w, counters: T, m2BufferRW: E, useAdaptiveSampling: D, noiseThreshold: O, adaptiveMinSamples: k, usePixelFreeze: A, pixelFreezeThreshold: ee, streakBufferRW: te, frozenMaskRO: ne } = e, re = C.greaterThan(z(0)), ie = w.greaterThan(z(0)), M = D.greaterThan(N(0)), P = A.greaterThan(N(0));
10489
10471
  return f(() => {
10490
10472
  let e = N(He.x).mul(16).add(N(se.x)), f = N(He.y).mul(16).add(N(se.y));
10491
10473
  p(e.lessThan(v).and(f.lessThan(b)), () => {
10492
- let b = f.add(y), C = z(f.mul(v).add(e)), w = z(b.mul(v).add(e)), D = wl(t, C), A = D.xyz.toVar(), se = L(m, D.w, j(1)).toVar(), ce = oe.and(s.greaterThan(z(0))).and(re.element(w).equal(z(1))).toVar(), le = W(0).toVar(), ue = W(0).xyz.toVar();
10493
- p(ie, () => {
10474
+ let b = f.add(y), C = z(f.mul(v).add(e)), w = z(b.mul(v).add(e)), D = wl(t, C), A = D.xyz.toVar(), oe = L(m, D.w, j(1)).toVar(), se = P.and(s.greaterThan(z(0))).and(ne.element(w).equal(z(1))).toVar(), ce = W(0).toVar(), le = W(0).xyz.toVar();
10475
+ p(re, () => {
10494
10476
  let e = Dl(n, C);
10495
- le.assign(Ol(e)), ue.assign(W(kl(e), 0).xyz);
10477
+ ce.assign(Ol(e)), le.assign(W(kl(e), 0).xyz);
10496
10478
  });
10497
- let F = H(j(e).add(.5), j(b).add(.5)).div(o);
10479
+ let ue = H(j(e).add(.5), j(b).add(.5)).div(o);
10498
10480
  p(c.and(d.not()).and(s.greaterThan(z(0))).and(l).and(S.notEqual(N(11))), () => {
10499
- let e = je(h, F, 0).toVar();
10500
- A.assign(L(ce, e.xyz, fe(e.xyz, D.xyz, u))), p(ie, () => {
10501
- ue.assign(fe(je(g, F, 0).xyz, ue, u)), p(M, () => {
10502
- let e = je(_, F, 0).xyz.mul(2).sub(1), t = le.xyz.mul(2).sub(1).toVar(), n = fe(e, t, u).toVar(), r = ae(n), i = L(r.greaterThan(1e-4), n.div(r), t);
10503
- le.assign(W(i.mul(.5).add(.5), le.w));
10481
+ let e = je(h, ue, 0).toVar();
10482
+ A.assign(L(se, e.xyz, fe(e.xyz, D.xyz, u))), p(re, () => {
10483
+ le.assign(fe(je(g, ue, 0).xyz, le, u)), p(ie, () => {
10484
+ let e = je(_, ue, 0).xyz.mul(2).sub(1), t = ce.xyz.mul(2).sub(1).toVar(), n = fe(e, t, u).toVar(), r = ae(n), i = L(r.greaterThan(1e-4), n.div(r), t);
10485
+ ce.assign(W(i.mul(.5).add(.5), ce.w));
10504
10486
  });
10505
10487
  }), p(m, () => {
10506
- se.assign(L(ce, e.w, fe(e.w, D.w, u)));
10488
+ oe.assign(L(se, e.w, fe(e.w, D.w, u)));
10507
10489
  });
10508
- }), p(P, () => {
10490
+ }), p(M, () => {
10509
10491
  let e = Oa(D.xyz), t = fe(E.element(w).toVar(), e.mul(e), u).toVar();
10510
10492
  E.element(w).assign(t);
10511
10493
  let n = Oa(A).toVar(), r = t.sub(n.mul(n)).max(j(0)).div(j(s).add(1)).sqrt().toVar(), i = r.div(n.add(j(1e-4))), a = L(n.lessThan(j(1)), n.sqrt(), n), o = r.div(a.add(j(1e-4))).lessThan(O);
10512
10494
  p(s.greaterThanEqual(z(k)).and(o), () => {
10513
10495
  x(T.element(z(nu.CONVERGED_COUNT)), z(1));
10514
- }), p(oe, () => {
10496
+ }), p(P, () => {
10515
10497
  p(s.equal(z(0)), () => {
10516
- ne.element(w).assign(z(0));
10517
- }), p(ce, () => {
10518
- x(T.element(z(nu.FROZEN_COUNT)), z(1));
10519
- }), p(ce.not().and(s.greaterThan(z(0))), () => {
10520
- let e = L(s.greaterThanEqual(z(k)).and(i.lessThan(ee)), ne.element(w).add(z(1)), z(0)).toVar();
10521
- ne.element(w).assign(e), p(e.greaterThanEqual(z(te)), () => {
10522
- x(T.element(z(nu.FROZEN_COUNT)), z(1));
10523
- });
10498
+ te.element(w).assign(z(0));
10499
+ }), p(se.not().and(s.greaterThan(z(0))), () => {
10500
+ let e = L(s.greaterThanEqual(z(k)).and(i.lessThan(ee)), te.element(w).add(z(1)), z(0)).toVar();
10501
+ te.element(w).assign(e);
10524
10502
  });
10525
10503
  });
10526
10504
  }), p(S.equal(N(11)), () => {
10527
10505
  A.assign(Ud(A));
10528
10506
  });
10529
- let de = Re(z(e), z(b));
10530
- Ne(r, de, W(A, se)).toWriteOnly(), p(ie, () => {
10531
- Ne(i, de, le).toWriteOnly(), Ne(a, de, W(ue, 1)).toWriteOnly();
10507
+ let F = Re(z(e), z(b));
10508
+ Ne(r, F, W(A, oe)).toWriteOnly(), p(re, () => {
10509
+ Ne(i, F, ce).toWriteOnly(), Ne(a, F, W(le, 1)).toWriteOnly();
10532
10510
  });
10533
10511
  });
10534
10512
  });
@@ -10539,7 +10517,7 @@ var Gd = /* @__PURE__ */ G("\n fn visualizeDepth( depth: f32 ) -> vec3f {\n ret
10539
10517
  let _ = W(1, 0, 1, 1).toVar(), v = ea({
10540
10518
  origin: e,
10541
10519
  direction: t
10542
- }), y = aa.wrap(Tu(v, n, r).toVar());
10520
+ }), y = aa.wrap(Du(v, n, r).toVar());
10543
10521
  return p(l.equal(N(7)), () => {
10544
10522
  let e = j(y.triTests).div(u);
10545
10523
  _.assign(L(e.lessThan(1), W(U(e), 1), W(1, 0, 0, 1)));
@@ -10626,7 +10604,7 @@ var Gd = /* @__PURE__ */ G("\n fn visualizeDepth( depth: f32 ) -> vec3f {\n ret
10626
10604
  }).toVar(), h = ea({
10627
10605
  origin: y.hitPoint.add(u.mul(.001)),
10628
10606
  direction: m
10629
- }), v = aa.wrap(Tu(h, n, r).toVar()), b = U(0).toVar();
10607
+ }), v = aa.wrap(Du(h, n, r).toVar()), b = U(0).toVar();
10630
10608
  p(v.didHit.not(), () => {
10631
10609
  p(c, () => {
10632
10610
  b.assign(Pu({
@@ -10680,21 +10658,19 @@ var Gd = /* @__PURE__ */ G("\n fn visualizeDepth( depth: f32 ) -> vec3f {\n ret
10680
10658
  }), _;
10681
10659
  });
10682
10660
  function Yd(e) {
10683
- let { writeColorTex: t, writeNDTex: n, writeAlbedoTex: r, resolution: i, renderWidth: a, renderHeight: o, cameraWorldMatrix: s, cameraProjectionMatrixInverse: c, cameraProjectionMatrix: l, cameraViewMatrix: u, enableDOF: d, focalLength: m, aperture: h, focusDistance: g, sceneScale: _, apertureScale: v, anamorphicRatio: y, bvhBuffer: b, triangleBuffer: x, materialBuffer: S, envTexture: C, environmentMatrix: w, environmentIntensity: T, enableEnvironmentLight: E, visMode: D, debugVisScale: O, frame: k } = e;
10661
+ let { writeColorTex: t, writeNDTex: n, writeAlbedoTex: r, resolution: i, renderWidth: a, renderHeight: o, cameraWorldMatrix: s, cameraProjectionMatrixInverse: c, cameraProjectionMatrix: l, cameraViewMatrix: u, cameraProjection: d, panoLonRange: m, panoLatRange: h, panoLevelHorizon: g, enableDOF: _, focalLength: v, aperture: y, focusDistance: b, sceneScale: x, apertureScale: S, anamorphicRatio: C, bvhBuffer: w, triangleBuffer: T, materialBuffer: E, envTexture: D, environmentMatrix: O, environmentIntensity: k, enableEnvironmentLight: A, visMode: ee, debugVisScale: te, frame: ne } = e;
10684
10662
  return f(() => {
10685
10663
  let e = N(He.x).mul(16).add(N(se.x)), f = N(He.y).mul(16).add(N(se.y));
10686
10664
  p(e.lessThan(a).and(f.lessThan(o)), () => {
10687
- let a = H(j(e).add(.5), j(f).add(.5)), o = Un({ state: z(f.mul(N(i.x)).add(e)).add(z(1)) }).toVar(), A = a.div(i).mul(2).sub(1).toVar();
10688
- A.y.assign(A.y.negate());
10689
- let ee = ea.wrap(Du(A, o, s, c, d, m, h, g, _, v, y)), te = W(1, 0, 1, 1).toVar();
10690
- p(D.equal(N(9)), () => {
10691
- let e = or(a, N(0), N(1), o, i, k);
10692
- te.assign(W(e, 1, 1));
10665
+ let a = H(j(e).add(.5), j(f).add(.5)), o = Un({ state: z(f.mul(N(i.x)).add(e)).add(z(1)) }).toVar(), re = ea.wrap(mu(a.div(i), o, s, c, d, m, h, g, _, v, y, b, x, S, C)), ie = W(1, 0, 1, 1).toVar();
10666
+ p(ee.equal(N(9)), () => {
10667
+ let e = or(a, N(0), N(1), o, i, ne);
10668
+ ie.assign(W(e, 1, 1));
10693
10669
  }).Else(() => {
10694
- te.assign(Jd(ee.origin, ee.direction, b, x, S, C, w, T, E, D, O, a, i, l, u, k));
10670
+ ie.assign(Jd(re.origin, re.direction, w, T, E, D, O, k, A, ee, te, a, i, l, u, ne));
10695
10671
  });
10696
- let ne = Re(z(e), z(f));
10697
- Ne(t, ne, te).toWriteOnly(), Ne(n, ne, W(.5, .5, 1, 1)).toWriteOnly(), Ne(r, ne, W(te.xyz, 1)).toWriteOnly();
10672
+ let M = Re(z(e), z(f));
10673
+ Ne(t, M, ie).toWriteOnly(), Ne(n, M, W(.5, .5, 1, 1)).toWriteOnly(), Ne(r, M, W(ie.xyz, 1)).toWriteOnly();
10698
10674
  });
10699
10675
  });
10700
10676
  }
@@ -10740,16 +10716,33 @@ function Qd({ sortGlobalHistogram: e, bins: t = 256 }) {
10740
10716
  }
10741
10717
  function $d({ hitBufferRO: e, activeIndicesReadRO: t, sortedIndicesRW: n, sortGlobalHistogram: r, counters: i, bins: a = 256 }) {
10742
10718
  return f(() => {
10743
- let o = M, s = S(i.element(z(nu.ENTERING_COUNT)));
10744
- p(o.lessThan(s), () => {
10745
- let i = t.element(o), s = z(Bl(e, i)).clamp(z(0), z(a - 1)), c = x(r.element(s), z(1));
10746
- n.element(c).assign(i);
10719
+ let o = M, s = se.x, c = jn("uint", a);
10720
+ p(s.lessThan(z(a)), () => {
10721
+ C(c.element(s), z(0));
10722
+ }), Ve();
10723
+ let l = S(i.element(z(nu.ENTERING_COUNT))), u = o.lessThan(l), d = z(0).toVar(), f = z(0).toVar();
10724
+ p(u, () => {
10725
+ d.assign(t.element(o)), f.assign(z(Bl(e, d)).clamp(z(0), z(a - 1))), x(c.element(f), z(1));
10726
+ }), Ve(), p(s.lessThan(z(a)), () => {
10727
+ let e = c.element(s), t = S(e);
10728
+ p(t.greaterThan(z(0)), () => {
10729
+ C(e, x(r.element(s), t));
10730
+ });
10731
+ }), Ve(), p(u, () => {
10732
+ n.element(x(c.element(f), z(1))).assign(d);
10747
10733
  });
10748
10734
  });
10749
10735
  }
10750
10736
  //#endregion
10751
10737
  //#region src/Stages/PathTracer.js
10752
- var ef = ai("wavefront"), tf = class extends dl {
10738
+ var ef = ai("wavefront"), tf = 256, nf = [
10739
+ "extend",
10740
+ "shade",
10741
+ "globalHist",
10742
+ "globalScatter",
10743
+ "compact",
10744
+ "compactCopyback"
10745
+ ], rf = class extends dl {
10753
10746
  constructor(e, t, n, r = {}) {
10754
10747
  super(e, t, n, r), this.name = "PathTracer", this._packedBuffers = null, this._queueManager = null, this._kernelManager = null, this._gBufferAttr = null, this._m2Attr = null, this._streakAttr = null, this._frozenMaskAttr = null, this._dilateFrozenUniform = B(1, "int"), this._wavefrontReady = !1, this._auxGBufferEnabled = !1, this._auxGBufferUniform = B(0, "uint"), this._cleanAuxNormalEnabled = !1, this._cleanAuxNormalUniform = B(0, "uint"), this._useDynamicDispatch = !0, this._sortMaterials = !1, this._useSubgroupCompact = !1, this._lastBounceCounts = null, this._lastBounceCountsBudget = -1, this._readbackPending = !1, this._readbackEveryNFrames = 4, this._readbackFrameCounter = 0, this._readbackGeneration = 0, this._curveSizingValid = !1, this._bounceEarlyExitThreshold = 100, this._convergedFraction = 0, this._convergedReadbackPending = !1, this._lastActivePixelCount = 0, this._wfRenderWidth = B(1920, "int"), this._wfRenderHeight = B(1080, "int"), this._wfMaxRayCount = B(0, "uint"), this._wfCurrentBounce = B(0, "int"), this._wfChunkRowBase = B(0, "int"), this._wfChunkRows = B(0, "int"), this._wfIsFirstChunk = B(1, "uint"), this._pathBudget = 0, this._pathBudgetOverride = 0, this._chunkRows = 0, this._numChunks = 1, this.vramTracker = new uu(this.renderer), this._registerVRAMProviders(), ef.debug("initialized (wavefront)");
10755
10748
  }
@@ -10824,11 +10817,7 @@ var ef = ai("wavefront"), tf = class extends dl {
10824
10817
  let n = Math.min(l, c - t), r = this._setChunk(t, n, e), i = this.usePixelFreeze.value > 0, o = u && i && this._curveSizingValid && this._lastActivePixelCount > 0 ? this._lastActivePixelCount : r;
10825
10818
  if (i) {
10826
10819
  let e = Math.min(r, Math.ceil(o * 1.5) + 1024);
10827
- a.setDispatchCount("generateList", [
10828
- Math.ceil(e / 256),
10829
- 1,
10830
- 1
10831
- ]), a.dispatch("resetFrameCounters"), a.dispatch("buildActivePixels"), a.dispatch("seedEnter"), a.dispatch("generateList");
10820
+ a.setDispatchForCount("generateList", e), a.dispatch("resetFrameCounters"), a.dispatch("buildActivePixels"), a.dispatch("seedEnter"), a.dispatch("generateList");
10832
10821
  } else a.dispatch("generate"), a.dispatch("initActiveIndices");
10833
10822
  for (let e = 0; e <= s; e++) {
10834
10823
  this._wfCurrentBounce.value = e;
@@ -10839,20 +10828,11 @@ var ef = ai("wavefront"), tf = class extends dl {
10839
10828
  let n = e - 1, i;
10840
10829
  n < f && d[n] !== void 0 ? i = d[n] : f > 0 && (i = d[f - 1]), t = i > 0 ? i : r;
10841
10830
  } else e === 0 && i && (t = o);
10842
- let n = Math.min(r, Math.ceil(t * 1.5) + 1024), s = [
10843
- Math.ceil(n / 256),
10844
- 1,
10845
- 1
10846
- ];
10847
- a.setDispatchCount("extend", s), a.setDispatchCount("shade", s), a.setDispatchCount("globalHist", s), a.setDispatchCount("globalScatter", s), a.setDispatchCount("compact", s), a.setDispatchCount("compactCopyback", s);
10831
+ let n = Math.min(r, Math.ceil(t * 1.5) + 1024);
10832
+ for (let e of nf) a.setDispatchForCount(e, n);
10848
10833
  } else {
10849
10834
  a.dispatch("enterFull");
10850
- let e = [
10851
- Math.ceil(r / 256),
10852
- 1,
10853
- 1
10854
- ];
10855
- a.setDispatchCount("extend", e), a.setDispatchCount("shade", e), a.setDispatchCount("compact", e), a.setDispatchCount("globalHist", e), a.setDispatchCount("globalScatter", e);
10835
+ for (let e of nf) a.setDispatchForCount(e, r);
10856
10836
  }
10857
10837
  if (a.dispatch("extend"), this._sortMaterials && (a.dispatch("resetGlobalHist"), a.dispatch("globalHist"), a.dispatch("globalPrefix"), a.dispatch("globalScatter")), a.dispatch("shade"), a.dispatch("compact"), t ? a.dispatch("compactCopyback") : a.dispatch("snapshotBounceCount"), e < f && e < s && d[e] !== void 0 && d[e] <= this._bounceEarlyExitThreshold) break;
10858
10838
  }
@@ -10962,7 +10942,7 @@ var ef = ai("wavefront"), tf = class extends dl {
10962
10942
  let d = Te(this._streakAttr, "uint"), m = Te(this._streakAttr, "uint").toReadOnly();
10963
10943
  _l(this.renderer, this._frozenMaskAttr), this._frozenMaskAttr = new o(new Uint32Array(l), 1);
10964
10944
  let g = Te(this._frozenMaskAttr, "uint"), _ = Te(this._frozenMaskAttr, "uint").toReadOnly();
10965
- this._queueManager ? this._queueManager.resize(this._packedBuffers.capacity) : this._queueManager = new iu(this._packedBuffers.capacity, this.renderer), this._kernelManager ||= new pu(this.renderer);
10945
+ this._queueManager ? this._queueManager.resize(this._packedBuffers.capacity) : this._queueManager = new iu(this._packedBuffers.capacity, this.renderer), this._kernelManager ||= new fu(this.renderer);
10966
10946
  let v = this._packedBuffers, y = this._queueManager;
10967
10947
  this._wfRenderWidth.value = t, this._wfRenderHeight.value = n, this._wfMaxRayCount.value = Math.min(r, this._chunkRows * t);
10968
10948
  let b = this.shaderBuilder.prevColorTexNode, w = this.shaderBuilder.prevAlbedoTexNode, T = this.shaderBuilder.prevNormalDepthTexNode, E = this.storageTextures.getWriteTextures(), D = y.getCounters(), O = y.getBounceCounts(), k = this._wfCurrentBounce, A = f(() => {
@@ -10989,11 +10969,11 @@ var ef = ai("wavefront"), tf = class extends dl {
10989
10969
  });
10990
10970
  });
10991
10971
  this._kernelManager.register("initActiveIndices", te().compute([
10992
- Math.ceil(this._chunkRows * t / 256),
10972
+ Math.ceil(this._chunkRows * t / tf),
10993
10973
  1,
10994
10974
  1
10995
10975
  ], [
10996
- 256,
10976
+ tf,
10997
10977
  1,
10998
10978
  1
10999
10979
  ]));
@@ -11005,6 +10985,10 @@ var ef = ai("wavefront"), tf = class extends dl {
11005
10985
  frame: this.seedFrame,
11006
10986
  cameraWorldMatrix: this.cameraWorldMatrix,
11007
10987
  cameraProjectionMatrixInverse: this.cameraProjectionMatrixInverse,
10988
+ cameraProjection: this.cameraProjection,
10989
+ panoLonRange: this.panoLonRange,
10990
+ panoLatRange: this.panoLatRange,
10991
+ panoLevelHorizon: this.panoLevelHorizon,
11008
10992
  enableDOF: this.enableDOF,
11009
10993
  focalLength: this.focalLength,
11010
10994
  aperture: this.aperture,
@@ -11019,7 +11003,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11019
11003
  transmissiveBounces: this.transmissiveBounces,
11020
11004
  transparentBackground: this.transparentBackground,
11021
11005
  auxGBufferEnabled: this._auxGBufferUniform
11022
- }, ne = Ou(j);
11006
+ }, ne = hu(j);
11023
11007
  this._kernelManager.register("generate", ne().compute([
11024
11008
  Math.ceil(t / 16),
11025
11009
  Math.ceil(this._chunkRows / 16),
@@ -11031,7 +11015,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11031
11015
  ]));
11032
11016
  let re = this.pixelFreezeStability, ie = f(() => {
11033
11017
  C(D.element(z(nu.ACTIVE_RAY_COUNT)), z(0)), p(this._wfIsFirstChunk.greaterThan(z(0)), () => {
11034
- C(D.element(z(nu.CONVERGED_COUNT)), z(0)), C(D.element(z(nu.FROZEN_COUNT)), z(0));
11018
+ C(D.element(z(nu.CONVERGED_COUNT)), z(0));
11035
11019
  });
11036
11020
  });
11037
11021
  this._kernelManager.register("resetFrameCounters", ie().compute([
@@ -11075,11 +11059,11 @@ var ef = ai("wavefront"), tf = class extends dl {
11075
11059
  });
11076
11060
  });
11077
11061
  this._kernelManager.register("buildActivePixels", P().compute([
11078
- Math.ceil(this._chunkRows * t / 256),
11062
+ Math.ceil(this._chunkRows * t / tf),
11079
11063
  1,
11080
11064
  1
11081
11065
  ], [
11082
- 256,
11066
+ tf,
11083
11067
  1,
11084
11068
  1
11085
11069
  ]));
@@ -11096,18 +11080,18 @@ var ef = ai("wavefront"), tf = class extends dl {
11096
11080
  1,
11097
11081
  1
11098
11082
  ]));
11099
- let oe = Ou({
11083
+ let oe = hu({
11100
11084
  ...j,
11101
11085
  listDriven: !0,
11102
11086
  activeIndicesRO: y.activeIndicesRO.a,
11103
11087
  counters: D
11104
11088
  });
11105
11089
  this._kernelManager.register("generateList", oe().compute([
11106
- Math.ceil(i / 256),
11090
+ Math.ceil(i / tf),
11107
11091
  1,
11108
11092
  1
11109
11093
  ], [
11110
- 256,
11094
+ tf,
11111
11095
  1,
11112
11096
  1
11113
11097
  ]));
@@ -11123,7 +11107,6 @@ var ef = ai("wavefront"), tf = class extends dl {
11123
11107
  let he = ku({
11124
11108
  bvhBuffer: se,
11125
11109
  triangleBuffer: ce,
11126
- materialBuffer: le,
11127
11110
  rayBufferRO: v.rayBuffer.ro,
11128
11111
  hitBufferRW: v.hitBuffer.rw,
11129
11112
  activeIndicesRO: y.getActiveReadRO(),
@@ -11304,11 +11287,11 @@ var ef = ai("wavefront"), tf = class extends dl {
11304
11287
  }), L.element(e).assign(be.element(e));
11305
11288
  });
11306
11289
  this._kernelManager.register("compactCopyback", xe().compute([
11307
- Math.ceil(i / 256),
11290
+ Math.ceil(i / tf),
11308
11291
  1,
11309
11292
  1
11310
11293
  ], [
11311
- 256,
11294
+ tf,
11312
11295
  1,
11313
11296
  1
11314
11297
  ]));
@@ -11340,7 +11323,6 @@ var ef = ai("wavefront"), tf = class extends dl {
11340
11323
  adaptiveMinSamples: this.adaptiveMinSamples,
11341
11324
  usePixelFreeze: this.usePixelFreeze,
11342
11325
  pixelFreezeThreshold: this.pixelFreezeThreshold,
11343
- pixelFreezeStability: this.pixelFreezeStability,
11344
11326
  streakBufferRW: d,
11345
11327
  frozenMaskRO: _,
11346
11328
  chunkRowBase: this._wfChunkRowBase,
@@ -11366,6 +11348,10 @@ var ef = ai("wavefront"), tf = class extends dl {
11366
11348
  cameraProjectionMatrixInverse: this.cameraProjectionMatrixInverse,
11367
11349
  cameraProjectionMatrix: this.cameraProjectionMatrix,
11368
11350
  cameraViewMatrix: this.cameraViewMatrix,
11351
+ cameraProjection: this.cameraProjection,
11352
+ panoLonRange: this.panoLonRange,
11353
+ panoLatRange: this.panoLatRange,
11354
+ panoLevelHorizon: this.panoLevelHorizon,
11369
11355
  enableDOF: this.enableDOF,
11370
11356
  focalLength: this.focalLength,
11371
11357
  aperture: this.aperture,
@@ -11403,43 +11389,23 @@ var ef = ai("wavefront"), tf = class extends dl {
11403
11389
  }
11404
11390
  _setWfDispatch() {
11405
11391
  let e = this._wfRenderWidth.value, t = this._wfRenderHeight.value;
11406
- this._kernelManager.setDispatchCount("debug", [
11407
- Math.ceil(e / 16),
11408
- Math.ceil(t / 16),
11409
- 1
11410
- ]);
11392
+ this._kernelManager.setDispatchForGrid("debug", e, t);
11411
11393
  }
11412
11394
  _setChunk(e, t, n) {
11413
11395
  let r = this._wfRenderWidth.value, i = t * r;
11414
11396
  this._wfChunkRowBase.value = e, this._wfChunkRows.value = t, this._wfIsFirstChunk.value = +(n === 0), this._wfMaxRayCount.value = i;
11415
11397
  let a = this._kernelManager;
11416
- return a.setDispatchCount("generate", [
11417
- Math.ceil(r / 16),
11418
- Math.ceil(t / 16),
11419
- 1
11420
- ]), a.setDispatchCount("finalWrite", [
11421
- Math.ceil(r / 16),
11422
- Math.ceil(t / 16),
11423
- 1
11424
- ]), a.setDispatchCount("initActiveIndices", [
11425
- Math.ceil(i / 256),
11426
- 1,
11427
- 1
11428
- ]), a.setDispatchCount("buildActivePixels", [
11429
- Math.ceil(i / 256),
11430
- 1,
11431
- 1
11432
- ]), i;
11398
+ return a.setDispatchForGrid("generate", r, t), a.setDispatchForGrid("finalWrite", r, t), a.setDispatchForCount("initActiveIndices", i), a.setDispatchForCount("buildActivePixels", i), i;
11433
11399
  }
11434
11400
  dispose() {
11435
11401
  super.dispose(), this._packedBuffers?.dispose(), this._queueManager?.dispose(), this._kernelManager?.dispose(), this._gBufferAttr?.dispose?.(), this._m2Attr?.dispose?.(), this._streakAttr?.dispose?.(), this._frozenMaskAttr?.dispose?.(), this._packedBuffers = null, this._queueManager = null, this._kernelManager = null, this._gBufferAttr = null, this._m2Attr = null, this._streakAttr = null, this._frozenMaskAttr = null, this._wavefrontReady = !1;
11436
11402
  }
11437
- }, nf = class extends lr {
11403
+ }, af = class extends lr {
11438
11404
  constructor(e, t = {}) {
11439
11405
  super("NormalDepth", {
11440
11406
  ...t,
11441
11407
  executionMode: cr.ALWAYS
11442
- }), this.renderer = e, this.pathTracer = t.pathTracer, this._dirty = !0, this.cameraWorldMatrix = B(new Ct(), "mat4"), this.cameraProjectionMatrixInverse = B(new Ct(), "mat4"), this.resolutionWidth = B(t.width || 1), this.resolutionHeight = B(t.height || 1);
11408
+ }), this.renderer = e, this.pathTracer = t.pathTracer, this._dirty = !0, this.cameraWorldMatrix = B(new Ct(), "mat4"), this.cameraProjectionMatrixInverse = B(new Ct(), "mat4"), this.cameraProjection = B(0, "int"), this.panoLonRange = B(new sn(), "vec2"), this.panoLatRange = B(new sn(), "vec2"), this.panoLevelHorizon = B(1, "int"), this.resolutionWidth = B(t.width || 1), this.resolutionHeight = B(t.height || 1);
11443
11409
  let n = t.width || 1, r = t.height || 1;
11444
11410
  this._outputStorageTex = new s(Y, Y), this._outputStorageTex.type = ht, this._outputStorageTex.format = Bt, this._outputStorageTex.minFilter = Ot, this._outputStorageTex.magFilter = Ot, this._shadingStorageTex = new s(Y, Y), this._shadingStorageTex.type = ht, this._shadingStorageTex.format = Bt, this._shadingStorageTex.minFilter = Ot, this._shadingStorageTex.magFilter = Ot, this._shadingRT = new i(n, r, {
11445
11411
  type: ht,
@@ -11479,18 +11445,18 @@ var ef = ai("wavefront"), tf = class extends dl {
11479
11445
  this._computeNode = f(([r, i]) => {
11480
11446
  let l = N(He.x).mul(8).add(N(se.x)), u = N(He.y).mul(8).add(N(se.y));
11481
11447
  p(l.lessThan(N(a)).and(u.lessThan(N(o))), () => {
11482
- let d = U(j(l).add(.5).div(a).mul(2).sub(1), j(u).add(.5).div(o).mul(2).sub(1).negate(), 1), f = i.mul(W(d, 1)), m = I(ue(r[0].xyz, r[1].xyz, r[2].xyz).mul(f.xyz.div(f.w))), h = ea({
11448
+ let d = pu(H(j(l).add(.5).div(a), j(u).add(.5).div(o)), r, i, this.cameraProjection, this.panoLonRange, this.panoLatRange, this.panoLevelHorizon), f = ea({
11483
11449
  origin: U(r[3]),
11484
- direction: m
11485
- }), g = aa.wrap(wu(h, t, e)), _ = g.normal.mul(.5).add(.5), v = de(g.dst, j(65504)), y = g.didHit.select(W(_, v), W(0, 0, 0, j(65504)));
11486
- Ne(s, Re(z(l), z(u)), y).toWriteOnly();
11487
- let b = g.normal.toVar();
11488
- p(g.didHit, () => {
11489
- let e = ta.wrap(za(g.materialIndex, n)).toVar(), t = pa.wrap(as(g.uv, e)).toVar(), r = cs(g.normal, e, t).toVar();
11490
- b.assign(ls(r, e, t));
11450
+ direction: d
11451
+ }), m = aa.wrap(Eu(f, t, e)), h = m.normal.mul(.5).add(.5), g = de(m.dst, j(65504)), _ = m.didHit.select(W(h, g), W(0, 0, 0, j(65504)));
11452
+ Ne(s, Re(z(l), z(u)), _).toWriteOnly();
11453
+ let v = m.normal.toVar();
11454
+ p(m.didHit, () => {
11455
+ let e = ta.wrap(za(m.materialIndex, n)).toVar(), t = pa.wrap(as(m.uv, e)).toVar(), r = cs(m.normal, e, t).toVar();
11456
+ v.assign(ls(r, e, t));
11491
11457
  });
11492
- let x = g.didHit.select(W(b.mul(.5).add(.5), v), W(0, 0, 0, j(65504)));
11493
- Ne(c, Re(z(l), z(u)), x).toWriteOnly();
11458
+ let y = m.didHit.select(W(v.mul(.5).add(.5), g), W(0, 0, 0, j(65504)));
11459
+ Ne(c, Re(z(l), z(u)), y).toWriteOnly();
11494
11460
  });
11495
11461
  })(r, i).compute([
11496
11462
  this._dispatchX,
@@ -11506,7 +11472,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11506
11472
  if (!this.enabled || !this._syncStorageBuffers()) return;
11507
11473
  this._computeBuilt || this._buildCompute();
11508
11474
  let t = this.pathTracer;
11509
- if (t && (this.cameraWorldMatrix.value.copy(t.uniforms.get("cameraWorldMatrix").value), this.cameraProjectionMatrixInverse.value.copy(t.uniforms.get("cameraProjectionMatrixInverse").value)), !this._dirty && this._hasHistory) {
11475
+ if (t && (this.cameraWorldMatrix.value.copy(t.uniforms.get("cameraWorldMatrix").value), this.cameraProjectionMatrixInverse.value.copy(t.uniforms.get("cameraProjectionMatrixInverse").value), this.cameraProjection.value = t.uniforms.get("cameraProjection").value, this.panoLonRange.value.copy(t.uniforms.get("panoLonRange").value), this.panoLatRange.value.copy(t.uniforms.get("panoLatRange").value), this.panoLevelHorizon.value = t.uniforms.get("panoLevelHorizon").value), !this._dirty && this._hasHistory) {
11510
11476
  let t = this._currentIdx === 0 ? this._rtA : this._rtB;
11511
11477
  e.setTexture("pathtracer:normalDepth", t.texture), e.setTexture("pathtracer:prevNormalDepth", t.texture), e.setTexture("pathtracer:shadingNormal", this._shadingRT.texture);
11512
11478
  return;
@@ -11544,7 +11510,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11544
11510
  dispose() {
11545
11511
  this._computeNode?.dispose(), this._outputStorageTex?.dispose(), this._shadingStorageTex?.dispose(), this._shadingRT?.dispose(), this._rtA?.dispose(), this._rtB?.dispose();
11546
11512
  }
11547
- }, rf = class extends lr {
11513
+ }, of = class extends lr {
11548
11514
  constructor(e, t, n = {}) {
11549
11515
  super("MotionVector", {
11550
11516
  ...n,
@@ -11664,7 +11630,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11664
11630
  dispose() {
11665
11631
  this._screenSpaceComputeNode?.dispose(), this._worldSpaceComputeNode?.dispose(), this._screenSpaceStorageTex?.dispose(), this._worldSpaceStorageTex?.dispose(), this.screenSpaceTarget?.dispose(), this.worldSpaceTarget?.dispose(), this._normalDepthTexNode?.dispose();
11666
11632
  }
11667
- }, af = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), of = (e) => U(af(e.x), af(e.y), af(e.z)), sf = class extends lr {
11633
+ }, sf = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), cf = (e) => U(sf(e.x), sf(e.y), sf(e.z)), lf = class extends lr {
11668
11634
  constructor(e, t = {}) {
11669
11635
  super("ASVGF", {
11670
11636
  ...t,
@@ -11705,7 +11671,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11705
11671
  let e = this._colorTexNode, t = this._albedoTexNode, n = this._motionTexNode, r = this._readTemporalTexNode, i = this.gradientNoiseFloor, a = this.gradientSigmaScale, o = this._gradientStorageTex, s = this.resW, c = this.resH, l = Be("float", 144), u = Be("float", 144);
11706
11672
  this._gradientNode = f(() => {
11707
11673
  let d = se.x, f = se.y, m = f.mul(8).add(d), h = N(He.x).mul(8).sub(2).toVar(), g = N(He.y).mul(8).sub(2).toVar(), v = (i) => {
11708
- let a = i.mod(z(12)), o = i.div(z(12)), d = h.add(N(a)).clamp(N(0), N(s).sub(1)), f = g.add(N(o)).clamp(N(0), N(c).sub(1)), p = R(e, P(d, f)).xyz, m = R(t, P(d, f)).xyz, _ = Oa(of(p.div(F(m, U(Er))))).toVar();
11674
+ let a = i.mod(z(12)), o = i.div(z(12)), d = h.add(N(a)).clamp(N(0), N(s).sub(1)), f = g.add(N(o)).clamp(N(0), N(c).sub(1)), p = R(e, P(d, f)).xyz, m = R(t, P(d, f)).xyz, _ = Oa(cf(p.div(F(m, U(Er))))).toVar();
11709
11675
  l.element(i).assign(_);
11710
11676
  let v = R(n, P(d, f)), y = j(d).sub(v.x.mul(s)), b = j(f).sub(v.y.mul(c)), x = N(y.add(.5)).clamp(N(0), N(s).sub(1)), S = N(b.add(.5)).clamp(N(0), N(c).sub(1)), C = v.w.greaterThan(.5), w = R(r, P(x, S)).xyz, T = C.select(Oa(w), _);
11711
11677
  u.element(i).assign(T);
@@ -11752,7 +11718,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11752
11718
  return f(() => {
11753
11719
  let f = N(He.x).mul(8).add(N(se.x)), y = N(He.y).mul(8).add(N(se.y));
11754
11720
  p(f.lessThan(N(g)).and(y.lessThan(N(v))), () => {
11755
- let b = P(f, y), x = R(t, b), S = x.xyz, C = x.w, w = R(n, b).xyz, T = F(w, U(Er)), E = of(S.div(T)), D = W(E, 1).toVar(), O = W(S, C).toVar();
11721
+ let b = P(f, y), x = R(t, b), S = x.xyz, C = x.w, w = R(n, b).xyz, T = F(w, U(Er)), E = cf(S.div(T)), D = W(E, 1).toVar(), O = W(S, C).toVar();
11756
11722
  p(m.greaterThan(.5).and(h.lessThan(.5)), () => {
11757
11723
  let e = R(r, b), t = e.w.greaterThan(.5), n = j(f).sub(e.x.mul(g)), c = j(y).sub(e.y.mul(v)), m = n.greaterThanEqual(0).and(n.lessThan(j(g))).and(c.greaterThanEqual(0)).and(c.lessThan(j(v)));
11758
11724
  p(t.and(m), () => {
@@ -11761,7 +11727,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11761
11727
  return i.mul(l).mul(u);
11762
11728
  }, se = oe(w, te, re), ce = oe(k, te, ie), le = oe(w, ne, M), ue = oe(k, ne, ae), pe = se.add(ce).add(le).add(ue);
11763
11729
  p(pe.greaterThan(j(.01)), () => {
11764
- let e = R(o, P(w, te)), t = R(o, P(k, te)), n = R(o, P(w, ne)), r = R(o, P(k, ne)), i = j(1).div(pe), a = e.xyz.mul(se).add(t.xyz.mul(ce)).add(n.xyz.mul(le)).add(r.xyz.mul(ue)).mul(i), c = e.w.mul(se).add(t.w.mul(ce)).add(n.w.mul(le)).add(r.w.mul(ue)).mul(i), f = R(s, b).x.mul(d).clamp(0, 1), p = of(fe(a, E, fe(F(j(1).div(c.add(1)), u), j(1), f))), m = de(c.add(1), l);
11730
+ let e = R(o, P(w, te)), t = R(o, P(k, te)), n = R(o, P(w, ne)), r = R(o, P(k, ne)), i = j(1).div(pe), a = e.xyz.mul(se).add(t.xyz.mul(ce)).add(n.xyz.mul(le)).add(r.xyz.mul(ue)).mul(i), c = e.w.mul(se).add(t.w.mul(ce)).add(n.w.mul(le)).add(r.w.mul(ue)).mul(i), f = R(s, b).x.mul(d).clamp(0, 1), p = cf(fe(a, E, fe(F(j(1).div(c.add(1)), u), j(1), f))), m = de(c.add(1), l);
11765
11731
  D.assign(W(p, m)), O.assign(W(p.mul(T), C));
11766
11732
  });
11767
11733
  });
@@ -11879,7 +11845,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11879
11845
  dispose() {
11880
11846
  this._gradientNode?.dispose(), this._temporalNodeA?.dispose(), this._temporalNodeB?.dispose(), this._temporalTexA?.dispose(), this._temporalTexB?.dispose(), this._outputModulatedTex?.dispose(), this._gradientStorageTex?.dispose(), this._demodulatedRT?.dispose(), this._outputRT?.dispose(), this._gradientRT?.dispose(), this._heatmapComputeNode?.dispose(), this._heatmapStorageTex?.dispose(), this.heatmapTarget?.dispose(), this._colorTexNode?.dispose(), this._albedoTexNode?.dispose(), this._motionTexNode?.dispose(), this._normalDepthTexNode?.dispose(), this._prevNormalDepthTexNode?.dispose(), this._readTemporalTexNode?.dispose(), this._gradientReadTexNode?.dispose(), this._heatmapRawColorTexNode?.dispose(), this._heatmapColorTexNode?.dispose(), this._heatmapTemporalTexNode?.dispose(), this._heatmapNDTexNode?.dispose(), this._heatmapMotionTexNode?.dispose(), this._heatmapGradientTexNode?.dispose();
11881
11847
  }
11882
- }, cf = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), lf = /* @__PURE__ */ G("\n fn temporalAccumulate(\n lum: f32,\n prevMean: f32,\n prevMeanSq: f32,\n alpha: f32,\n spatialVariance: f32,\n varianceBoost: f32\n ) -> vec4f {\n\n let newMean = prevMean + ( lum - prevMean ) * alpha;\n let newMeanSq = prevMeanSq + ( lum * lum - prevMeanSq ) * alpha;\n let temporalVariance = max( newMeanSq - newMean * newMean, 0.0 );\n\n return vec4f(\n newMean,\n newMeanSq,\n temporalVariance * varianceBoost,\n spatialVariance * varianceBoost\n );\n\n }\n"), uf = class extends lr {
11848
+ }, uf = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), df = /* @__PURE__ */ G("\n fn temporalAccumulate(\n lum: f32,\n prevMean: f32,\n prevMeanSq: f32,\n alpha: f32,\n spatialVariance: f32,\n varianceBoost: f32\n ) -> vec4f {\n\n let newMean = prevMean + ( lum - prevMean ) * alpha;\n let newMeanSq = prevMeanSq + ( lum * lum - prevMeanSq ) * alpha;\n let temporalVariance = max( newMeanSq - newMean * newMean, 0.0 );\n\n return vec4f(\n newMean,\n newMeanSq,\n temporalVariance * varianceBoost,\n spatialVariance * varianceBoost\n );\n\n }\n"), ff = class extends lr {
11883
11849
  constructor(e, t = {}) {
11884
11850
  super("VarianceEstimation", {
11885
11851
  ...t,
@@ -11905,9 +11871,9 @@ var ef = ai("wavefront"), tf = class extends dl {
11905
11871
  let n = this._colorTexNode, r = this.temporalAlpha, i = this.varianceBoost, a = this.resW, o = this.resH, s = Be("float", 100);
11906
11872
  return f(() => {
11907
11873
  let c = se.x, l = se.y, u = l.mul(8).add(c), d = N(He.x).mul(8).sub(1), f = N(He.y).mul(8).sub(1), m = u.mod(10), h = u.div(10), g = R(n, P(d.add(N(m)).clamp(N(0), N(a).sub(1)), f.add(N(h)).clamp(N(0), N(o).sub(1)))).xyz;
11908
- s.element(u).assign(cf(Oa(g))), p(u.lessThan(z(36)), () => {
11874
+ s.element(u).assign(uf(Oa(g))), p(u.lessThan(z(36)), () => {
11909
11875
  let e = u.add(z(64)), t = e.mod(10), r = e.div(10), i = R(n, P(d.add(N(t)).clamp(N(0), N(a).sub(1)), f.add(N(r)).clamp(N(0), N(o).sub(1)))).xyz;
11910
- s.element(e).assign(cf(Oa(i)));
11876
+ s.element(e).assign(uf(Oa(i)));
11911
11877
  }), Ve();
11912
11878
  let _ = N(He.x).mul(8).add(N(c)), v = N(He.y).mul(8).add(N(l));
11913
11879
  p(_.lessThan(N(a)).and(v.lessThan(N(o))), () => {
@@ -11918,7 +11884,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11918
11884
  }
11919
11885
  n.divAssign(9), a.divAssign(9);
11920
11886
  let o = F(a.sub(n.mul(n)), j(0)), u = s.element(l.add(1).mul(10).add(c.add(1))), d = R(t, P(_, v));
11921
- Ne(e, Re(z(_), z(v)), lf(u, d.x, d.y, r, o, i)).toWriteOnly();
11887
+ Ne(e, Re(z(_), z(v)), df(u, d.x, d.y, r, o, i)).toWriteOnly();
11922
11888
  });
11923
11889
  })().compute([
11924
11890
  this._dispatchX,
@@ -11972,7 +11938,7 @@ var ef = ai("wavefront"), tf = class extends dl {
11972
11938
  dispose() {
11973
11939
  this._computeNodeA?.dispose(), this._computeNodeB?.dispose(), this._storageTexA?.dispose(), this._storageTexB?.dispose(), this._outputTarget?.dispose(), this._colorTexNode?.dispose(), this._readTexNodeA?.dispose(), this._readTexNodeB?.dispose();
11974
11940
  }
11975
- }, df = /* @__PURE__ */ G("\n fn bilateralWeight(\n centerLum: f32, sLum: f32,\n centerNormal: vec3f, sNormal: vec3f,\n centerDepth: f32, sDepth: f32,\n centerColor: vec3f, sColor: vec3f,\n kernelW: f32,\n sigmaL: f32, phiNorm: f32, phiDep: f32, phiCol: f32\n ) -> f32 {\n\n let lumW = exp( -abs( centerLum - sLum ) / sigmaL );\n // clamp dot to [0,1]: miss-ray normals decode to (-1,-1,-1) with\n // dot=3 → pow saturates to +inf → inf*0 = NaN. See project_tsl_pitfalls.\n // max(phiNorm, 1e-6): pow(0.0, 0.0) is undefined in WGSL and returned NaN on ~12%\n // of pixels when phiNormal was set to 0.\n let normW = pow( clamp( dot( centerNormal, sNormal ), 0.0, 1.0 ), max( phiNorm, 1e-6 ) );\n let depW = exp( -abs( centerDepth - sDepth ) / max( centerDepth * phiDep, 0.001 ) );\n let maxDiff = max( max( abs( centerColor.x - sColor.x ),\n abs( centerColor.y - sColor.y ) ),\n abs( centerColor.z - sColor.z ) );\n let avgLum = max( ( centerLum + sLum ) * 0.5, 0.0001 );\n let colW = exp( -( maxDiff / avgLum ) / max( phiCol, 0.0001 ) );\n return kernelW * lumW * normW * depW * colW;\n\n }\n"), ff = class extends lr {
11941
+ }, pf = /* @__PURE__ */ G("\n fn bilateralWeight(\n centerLum: f32, sLum: f32,\n centerNormal: vec3f, sNormal: vec3f,\n centerDepth: f32, sDepth: f32,\n centerColor: vec3f, sColor: vec3f,\n kernelW: f32,\n sigmaL: f32, phiNorm: f32, phiDep: f32, phiCol: f32\n ) -> f32 {\n\n let lumW = exp( -abs( centerLum - sLum ) / sigmaL );\n // clamp dot to [0,1]: miss-ray normals decode to (-1,-1,-1) with\n // dot=3 → pow saturates to +inf → inf*0 = NaN. See project_tsl_pitfalls.\n // max(phiNorm, 1e-6): pow(0.0, 0.0) is undefined in WGSL and returned NaN on ~12%\n // of pixels when phiNormal was set to 0.\n let normW = pow( clamp( dot( centerNormal, sNormal ), 0.0, 1.0 ), max( phiNorm, 1e-6 ) );\n let depW = exp( -abs( centerDepth - sDepth ) / max( centerDepth * phiDep, 0.001 ) );\n let maxDiff = max( max( abs( centerColor.x - sColor.x ),\n abs( centerColor.y - sColor.y ) ),\n abs( centerColor.z - sColor.z ) );\n let avgLum = max( ( centerLum + sLum ) * 0.5, 0.0001 );\n let colW = exp( -( maxDiff / avgLum ) / max( phiCol, 0.0001 ) );\n return kernelW * lumW * normW * depW * colW;\n\n }\n"), mf = class extends lr {
11976
11942
  constructor(e, t = {}) {
11977
11943
  super("BilateralFiltering", {
11978
11944
  ...t,
@@ -12027,7 +11993,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12027
11993
  return fe(t.z, F(t.z, t.w), d);
12028
11994
  }, ee = k.select(A(p), x.w.mul(x.w)).toVar(), te = u.mul(we(F(ee, j(0)))).div(O).add(j(1e-4)), ne = U(0).toVar(), re = j(0).toVar(), ie = j(0).toVar();
12029
11995
  for (let e = 0; e < 5; e++) for (let i = 0; i < 5; i++) {
12030
- let a = i - 2, o = e - 2, u = y[e * 5 + i], d = f.add(m.mul(a)).clamp(N(0), N(_).sub(1)), p = b.add(m.mul(o)).clamp(N(0), N(v).sub(1)), h = R(t, P(d, p)), g = h.xyz, x = R(n, P(d, p)), C = R(r, P(d, p)).xyz.mul(2).sub(1), D = x.w, O = df(E, Oa(g), w, C, T, D, S, g, j(u), te, c, l, s), ee = k.select(A(P(d, p)), h.w.mul(h.w));
11996
+ let a = i - 2, o = e - 2, u = y[e * 5 + i], d = f.add(m.mul(a)).clamp(N(0), N(_).sub(1)), p = b.add(m.mul(o)).clamp(N(0), N(v).sub(1)), h = R(t, P(d, p)), g = h.xyz, x = R(n, P(d, p)), C = R(r, P(d, p)).xyz.mul(2).sub(1), D = x.w, O = pf(E, Oa(g), w, C, T, D, S, g, j(u), te, c, l, s), ee = k.select(A(P(d, p)), h.w.mul(h.w));
12031
11997
  ne.addAssign(g.mul(O)), re.addAssign(O), ie.addAssign(O.mul(O).mul(F(ee, j(0))));
12032
11998
  }
12033
11999
  let M = ne.div(F(re, j(1e-4))), ae = ie.div(F(re.mul(re), j(1e-8))), oe = h.equal(N(1)), se = oe.select(M.mul(D), M), ce = oe.select(R(o, p).w, we(F(ae, j(0))));
@@ -12086,7 +12052,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12086
12052
  dispose() {
12087
12053
  this._computeNodeA?.dispose(), this._computeNodeB?.dispose(), this._storageTexA?.dispose(), this._storageTexB?.dispose(), this._outputTarget?.dispose(), this._readTexNode?.dispose(), this._normalDepthTexNode?.dispose(), this._shadingNormalTexNode?.dispose(), this._albedoTexNode?.dispose(), this._varianceTexNode?.dispose(), this._srcAlphaTexNode?.dispose();
12088
12054
  }
12089
- }, pf = 6e4, mf = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), hf = (e) => U(mf(e.x), mf(e.y), mf(e.z)), gf = [
12055
+ }, hf = 6e4, gf = (e) => L(e.equal(e), e, j(0)).clamp(0, 1e7), _f = (e) => U(gf(e.x), gf(e.y), gf(e.z)), vf = [
12090
12056
  1 / 256,
12091
12057
  4 / 256,
12092
12058
  6 / 256,
@@ -12112,7 +12078,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12112
12078
  6 / 256,
12113
12079
  4 / 256,
12114
12080
  1 / 256
12115
- ], _f = class extends lr {
12081
+ ], yf = class extends lr {
12116
12082
  constructor(e, t = {}) {
12117
12083
  super("EdgeAwareFiltering", {
12118
12084
  ...t,
@@ -12140,7 +12106,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12140
12106
  return f(() => {
12141
12107
  let o = N(He.x).mul(16).add(N(se.x)), s = N(He.y).mul(16).add(N(se.y));
12142
12108
  p(o.lessThan(N(i)).and(s.lessThan(N(a))), () => {
12143
- let i = P(o, s), a = R(e, i).xyz, c = R(t, i).w.lessThan(j(pf)), l = R(n, i).xyz, u = L(c, F(l, U(Er)), U(1)), d = hf(a.div(u));
12109
+ let i = P(o, s), a = R(e, i).xyz, c = R(t, i).w.lessThan(j(hf)), l = R(n, i).xyz, u = L(c, F(l, U(Er)), U(1)), d = _f(a.div(u));
12144
12110
  Ne(r, Re(z(o), z(s)), W(d, 1)).toWriteOnly();
12145
12111
  });
12146
12112
  })().compute([
@@ -12158,12 +12124,12 @@ var ef = ai("wavefront"), tf = class extends dl {
12158
12124
  return f(() => {
12159
12125
  let f = N(He.x).mul(16).add(N(se.x)), v = N(He.y).mul(16).add(N(se.y));
12160
12126
  p(f.lessThan(N(g)).and(v.lessThan(N(_))), () => {
12161
- let p = P(f, v), y = R(t, p), b = y.xyz, x = Oa(b), S = R(r, p).w, C = R(i, p).xyz.mul(2).sub(1), w = S.lessThan(j(pf)), T = L(w, j(1), j(0)), E = R(a, p).xyz, D = L(w, F(E, U(Er)), U(1)), O = F(Oa(D), j(Er)), k = h.equal(N(1)), ee = (e) => {
12127
+ let p = P(f, v), y = R(t, p), b = y.xyz, x = Oa(b), S = R(r, p).w, C = R(i, p).xyz.mul(2).sub(1), w = S.lessThan(j(hf)), T = L(w, j(1), j(0)), E = R(a, p).xyz, D = L(w, F(E, U(Er)), U(1)), O = F(Oa(D), j(Er)), k = h.equal(N(1)), ee = (e) => {
12162
12128
  let t = R(o, e);
12163
12129
  return F(t.z, t.w);
12164
12130
  }, te = k.select(ee(p), y.w.mul(y.w)).toVar(), ne = c.mul(we(F(te, j(0)))).div(O).add(j(1e-4)), re = U(0).toVar(), ie = j(0).toVar(), M = j(0).toVar();
12165
12131
  for (let e = 0; e < 5; e++) for (let n = 0; n < 5; n++) {
12166
- let a = n - 2, o = e - 2, s = gf[e * 5 + n], c = P(f.add(d.mul(a)).clamp(N(0), N(g).sub(1)), v.add(d.mul(o)).clamp(N(0), N(_).sub(1))), p = R(t, c), m = p.xyz, h = Oa(m), y = R(r, c).w, b = R(i, c).xyz.mul(2).sub(1), w = L(y.lessThan(j(pf)), j(1), j(0)), E = x.sub(h).abs().div(ne).negate().exp(), D = _e(A(C, b).clamp(0, 1), l), O = S.sub(y).abs().div(F(S.mul(u), j(.001))).negate().exp(), te = T.mul(w), ae = T.oneMinus().mul(w.oneMinus()), oe = te.add(ae), se = fe(j(1), D.mul(O), te), ce = j(s).mul(E).mul(se).mul(oe), le = k.select(ee(c), p.w.mul(p.w));
12132
+ let a = n - 2, o = e - 2, s = vf[e * 5 + n], c = P(f.add(d.mul(a)).clamp(N(0), N(g).sub(1)), v.add(d.mul(o)).clamp(N(0), N(_).sub(1))), p = R(t, c), m = p.xyz, h = Oa(m), y = R(r, c).w, b = R(i, c).xyz.mul(2).sub(1), w = L(y.lessThan(j(hf)), j(1), j(0)), E = x.sub(h).abs().div(ne).negate().exp(), D = _e(A(C, b).clamp(0, 1), l), O = S.sub(y).abs().div(F(S.mul(u), j(.001))).negate().exp(), te = T.mul(w), ae = T.oneMinus().mul(w.oneMinus()), oe = te.add(ae), se = fe(j(1), D.mul(O), te), ce = j(s).mul(E).mul(se).mul(oe), le = k.select(ee(c), p.w.mul(p.w));
12167
12133
  re.addAssign(m.mul(ce)), ie.addAssign(ce), M.addAssign(ce.mul(ce).mul(F(le, j(0))));
12168
12134
  }
12169
12135
  let ae = re.div(F(ie, j(1e-4))), oe = M.div(F(ie.mul(ie), j(1e-8))), se = m.equal(N(1)), ce = R(n, p).xyz, le = fe(ce, ae.mul(D), s), ue = se.select(le, ae), de = se.select(R(n, p).w, we(F(oe, j(0))));
@@ -12225,7 +12191,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12225
12191
  dispose() {
12226
12192
  this._computeDemod?.dispose(), this._computeAtrousA?.dispose(), this._computeAtrousB?.dispose(), this._demodTex?.dispose(), this._storageTexA?.dispose(), this._storageTexB?.dispose(), this.outputTarget?.dispose(), this._colorTexNode?.dispose(), this._ndTexNode?.dispose(), this._snTexNode?.dispose(), this._albedoTexNode?.dispose(), this._varTexNode?.dispose(), this._readTexNode?.dispose();
12227
12193
  }
12228
- }, vf = 256, yf = -8, bf = 6 - yf, xf = bf / vf, Sf = 1e4, Cf = /* @__PURE__ */ G("\n fn adaptExposure(\n geoMean: f32,\n prevExposure: f32,\n keyValue: f32,\n minExp: f32,\n maxExp: f32,\n speedBright: f32,\n speedDark: f32,\n dt: f32,\n isFirstFrame: f32\n ) -> vec4f {\n\n let targetExp = clamp( keyValue / max( geoMean, 0.001 ), minExp, maxExp );\n var newExposure = targetExp;\n\n // Temporal smoothing (skip on first frame)\n if ( isFirstFrame < 0.5 ) {\n\n // Asymmetric speed: brighter scenes adapt faster\n let speed = select( speedDark, speedBright, targetExp < prevExposure );\n let alpha = 1.0 - exp( -dt * speed );\n newExposure = mix( prevExposure, targetExp, alpha );\n\n }\n\n return vec4f( newExposure, geoMean, targetExp, 1.0 );\n\n }\n"), wf = class extends lr {
12194
+ }, bf = 256, xf = -8, Sf = 6 - xf, Cf = Sf / bf, wf = 1e4, Tf = /* @__PURE__ */ G("\n fn adaptExposure(\n geoMean: f32,\n prevExposure: f32,\n keyValue: f32,\n minExp: f32,\n maxExp: f32,\n speedBright: f32,\n speedDark: f32,\n dt: f32,\n isFirstFrame: f32\n ) -> vec4f {\n\n let targetExp = clamp( keyValue / max( geoMean, 0.001 ), minExp, maxExp );\n var newExposure = targetExp;\n\n // Temporal smoothing (skip on first frame)\n if ( isFirstFrame < 0.5 ) {\n\n // Asymmetric speed: brighter scenes adapt faster\n let speed = select( speedDark, speedBright, targetExp < prevExposure );\n let alpha = 1.0 - exp( -dt * speed );\n newExposure = mix( prevExposure, targetExp, alpha );\n\n }\n\n return vec4f( newExposure, geoMean, targetExp, 1.0 );\n\n }\n"), Ef = class extends lr {
12229
12195
  constructor(e, t = {}) {
12230
12196
  super("AutoExposure", {
12231
12197
  ...t,
@@ -12241,7 +12207,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12241
12207
  depthBuffer: !1,
12242
12208
  stencilBuffer: !1
12243
12209
  };
12244
- this._downsampleTarget = new i(this.REDUCTION_SIZE, this.REDUCTION_SIZE, e), this._downsampleStorageTex = new s(this.REDUCTION_SIZE, this.REDUCTION_SIZE), this._downsampleStorageTex.type = ft, this._downsampleStorageTex.format = Bt, this._downsampleStorageTex.minFilter = Ot, this._downsampleStorageTex.magFilter = Ot, this._reductionStorageTex = new s(1, 1), this._reductionStorageTex.type = ft, this._reductionStorageTex.format = Bt, this._reductionStorageTex.minFilter = Ot, this._reductionStorageTex.magFilter = Ot, this._reductionReadTarget = new i(1, 1, e), this._adaptationResult = w(1, "vec4"), this._readbackBuffer = new n(16), this._readbackBuffer.name = "AutoExposureAdaptation", this._histogramBuffer = w(vf, "uint").toAtomic();
12210
+ this._downsampleTarget = new i(this.REDUCTION_SIZE, this.REDUCTION_SIZE, e), this._downsampleStorageTex = new s(this.REDUCTION_SIZE, this.REDUCTION_SIZE), this._downsampleStorageTex.type = ft, this._downsampleStorageTex.format = Bt, this._downsampleStorageTex.minFilter = Ot, this._downsampleStorageTex.magFilter = Ot, this._reductionStorageTex = new s(1, 1), this._reductionStorageTex.type = ft, this._reductionStorageTex.format = Bt, this._reductionStorageTex.minFilter = Ot, this._reductionStorageTex.magFilter = Ot, this._reductionReadTarget = new i(1, 1, e), this._adaptationResult = w(1, "vec4"), this._readbackBuffer = new n(16), this._readbackBuffer.name = "AutoExposureAdaptation", this._histogramBuffer = w(bf, "uint").toAtomic();
12245
12211
  }
12246
12212
  _buildCompute() {
12247
12213
  this._buildDownsampleCompute(), this._buildHistogramCompute(), this._buildHistogramAnalyzeCompute(), this._buildAdaptationCompute();
@@ -12275,7 +12241,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12275
12241
  for (let i = 0; i < 16; i++) {
12276
12242
  let a = r.mul(16).add(i), o = a.mod(64), s = a.div(64), c = R(e, P(N(o), N(s))), l = c.x, u = c.y;
12277
12243
  p(u.greaterThan(0), () => {
12278
- let e = z(l.div(u).sub(j(yf)).div(j(bf)).mul(j(vf)).floor().clamp(0, j(vf - 1))), r = j(o).add(.5).div(j(64)), i = j(s).add(.5).div(j(64)), a = r.sub(.5), c = i.sub(.5), d = z(a.mul(a).add(c.mul(c)).mul(n).negate().exp().mul(j(Sf)));
12244
+ let e = z(l.div(u).sub(j(xf)).div(j(Sf)).mul(j(bf)).floor().clamp(0, j(bf - 1))), r = j(o).add(.5).div(j(64)), i = j(s).add(.5).div(j(64)), a = r.sub(.5), c = i.sub(.5), d = z(a.mul(a).add(c.mul(c)).mul(n).negate().exp().mul(j(wf)));
12279
12245
  x(t.element(e), d);
12280
12246
  });
12281
12247
  }
@@ -12293,14 +12259,14 @@ var ef = ai("wavefront"), tf = class extends dl {
12293
12259
  let e = this._histogramBuffer, t = this._reductionStorageTex, n = this.lowPercentileU, r = this.highPercentileU;
12294
12260
  this._histogramAnalyzeNode = f(() => {
12295
12261
  let i = j(0).toVar();
12296
- m(vf, ({ i: t }) => {
12262
+ m(bf, ({ i: t }) => {
12297
12263
  i.addAssign(j(S(e.element(t))));
12298
12264
  });
12299
12265
  let a = i.mul(n), o = i.mul(r), s = j(0).toVar(), c = j(0).toVar(), l = j(0).toVar(), u = j(0).toVar();
12300
- m(vf, ({ i: t }) => {
12266
+ m(bf, ({ i: t }) => {
12301
12267
  let n = j(S(e.element(t)));
12302
12268
  u.assign(s), s.addAssign(n), p(u.lessThan(o).and(s.greaterThan(a)), () => {
12303
- let e = j(yf).add(j(t).add(.5).mul(j(xf)));
12269
+ let e = j(xf).add(j(t).add(.5).mul(j(Cf)));
12304
12270
  c.addAssign(e.mul(n)), l.addAssign(n);
12305
12271
  });
12306
12272
  });
@@ -12315,7 +12281,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12315
12281
  _buildAdaptationCompute() {
12316
12282
  let e = this._reductionReadTexNode, t = this._adaptationResult, n = this.keyValueU, r = this.minExposureU, i = this.maxExposureU, a = this.adaptSpeedBrightU, o = this.adaptSpeedDarkU, s = this.deltaTimeU, c = this.isFirstFrameU, l = this.previousExposureU;
12317
12283
  this._adaptationComputeNode = f(() => {
12318
- let u = R(e, P(N(0), N(0))).x, d = Cf(u, l, n, r, i, a, o, s, c);
12284
+ let u = R(e, P(N(0), N(0))).x, d = Tf(u, l, n, r, i, a, o, s, c);
12319
12285
  t.element(z(0)).assign(d);
12320
12286
  })().compute(1, [
12321
12287
  1,
@@ -12379,7 +12345,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12379
12345
  dispose() {
12380
12346
  this._downsampleComputeNode?.dispose(), this._histogramComputeNode?.dispose(), this._histogramAnalyzeNode?.dispose(), this._adaptationComputeNode?.dispose(), this._downsampleTarget?.dispose(), this._downsampleStorageTex?.dispose(), this._reductionStorageTex?.dispose(), this._reductionReadTarget?.dispose(), this._readbackBuffer?.dispose(), this._inputTexNode?.dispose(), this._reductionReadTexNode?.dispose();
12381
12347
  }
12382
- }, Tf = class extends lr {
12348
+ }, Df = class extends lr {
12383
12349
  constructor(n, r = {}) {
12384
12350
  super("Compositor", {
12385
12351
  ...r,
@@ -12405,7 +12371,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12405
12371
  dispose() {
12406
12372
  this._sourceTexNode?.dispose(), this.compositorMaterial?.dispose(), this.compositorQuad = null;
12407
12373
  }
12408
- }, Ef = class {
12374
+ }, Of = class {
12409
12375
  constructor() {
12410
12376
  this.textures = /* @__PURE__ */ new Map(), this.renderTargets = /* @__PURE__ */ new Map(), this.uniforms = /* @__PURE__ */ new Map(), this.state = {
12411
12377
  frame: 0,
@@ -12527,7 +12493,7 @@ var ef = ai("wavefront"), tf = class extends dl {
12527
12493
  dispose() {
12528
12494
  this.textures.clear(), this.renderTargets.clear(), this.uniforms.clear(), this._stateChangeCallbacks.clear(), this.state = {};
12529
12495
  }
12530
- }, Df = class extends ut {
12496
+ }, kf = class extends ut {
12531
12497
  constructor() {
12532
12498
  super(), this._onceCallbacks = /* @__PURE__ */ new Map();
12533
12499
  }
@@ -12565,38 +12531,38 @@ var ef = ai("wavefront"), tf = class extends dl {
12565
12531
  eventNames() {
12566
12532
  return this._listeners ? Object.keys(this._listeners) : [];
12567
12533
  }
12568
- }, Of = !1, kf = [], Af = /* @__PURE__ */ new WeakMap();
12569
- function jf(e) {
12570
- Of = !!e;
12534
+ }, Af = !1, jf = [], Mf = /* @__PURE__ */ new WeakMap();
12535
+ function Nf(e) {
12536
+ Af = !!e;
12571
12537
  }
12572
- function Mf() {
12573
- return kf.slice();
12538
+ function Pf() {
12539
+ return jf.slice();
12574
12540
  }
12575
- function Nf() {
12576
- kf.length = 0;
12541
+ function Ff() {
12542
+ jf.length = 0;
12577
12543
  }
12578
- function Pf(e) {
12544
+ function If(e) {
12579
12545
  let t = [];
12580
12546
  for (let n of Object.keys(e)) e[n]?.isTextureNode === !0 && t.push(n);
12581
12547
  return t;
12582
12548
  }
12583
- var Ff = (e) => !e || !e.image || !(e.image.width > 0);
12584
- function If(e, t, n) {
12585
- if (!Of) {
12549
+ var Lf = (e) => !e || !e.image || !(e.image.width > 0);
12550
+ function Rf(e, t, n) {
12551
+ if (!Af) {
12586
12552
  n();
12587
12553
  return;
12588
12554
  }
12589
- let r = Af.get(e);
12555
+ let r = Mf.get(e);
12590
12556
  if (r || (r = {
12591
12557
  phase: "pending",
12592
12558
  unboundAtCompile: []
12593
- }, Af.set(e, r)), r.phase !== "pending") {
12594
- n(), r.phase === "watch" && Lf(e, r);
12559
+ }, Mf.set(e, r)), r.phase !== "pending") {
12560
+ n(), r.phase === "watch" && zf(e, r);
12595
12561
  return;
12596
12562
  }
12597
12563
  let i = Object.prototype.hasOwnProperty.call(t, "compute"), a = t.compute;
12598
12564
  t.compute = function(...t) {
12599
- return r.phase === "pending" && (r.unboundAtCompile = Pf(e).filter((t) => Ff(e[t].value)), r.phase = r.unboundAtCompile.length < 2 ? "done" : "watch"), a.apply(this, t);
12565
+ return r.phase === "pending" && (r.unboundAtCompile = If(e).filter((t) => Lf(e[t].value)), r.phase = r.unboundAtCompile.length < 2 ? "done" : "watch"), a.apply(this, t);
12600
12566
  };
12601
12567
  try {
12602
12568
  n();
@@ -12604,14 +12570,14 @@ function If(e, t, n) {
12604
12570
  i ? t.compute = a : delete t.compute;
12605
12571
  }
12606
12572
  }
12607
- function Lf(e, t) {
12573
+ function zf(e, t) {
12608
12574
  let n = [];
12609
12575
  for (let r of t.unboundAtCompile) {
12610
12576
  let t = e[r]?.value;
12611
- if (Ff(t)) return;
12577
+ if (Lf(t)) return;
12612
12578
  t.isStorageTexture !== !0 && n.push(r);
12613
12579
  }
12614
- t.phase = "done", n.length !== 0 && kf.push({
12580
+ t.phase = "done", n.length !== 0 && jf.push({
12615
12581
  stage: e.name,
12616
12582
  nodes: n,
12617
12583
  unboundAtCompile: t.unboundAtCompile.slice(),
@@ -12620,9 +12586,9 @@ function Lf(e, t) {
12620
12586
  }
12621
12587
  //#endregion
12622
12588
  //#region src/Pipeline/RenderPipeline.js
12623
- var Rf = class {
12589
+ var Bf = class {
12624
12590
  constructor(e, t, n) {
12625
- this.renderer = e, this.width = t, this.height = n, this.stages = [], this.context = new Ef(), this.eventBus = new Df(), this.context.setState("width", t), this.context.setState("height", n), this.stats = {
12591
+ this.renderer = e, this.width = t, this.height = n, this.stages = [], this.context = new Of(), this.eventBus = new kf(), this.context.setState("width", t), this.context.setState("height", n), this.stats = {
12626
12592
  enabled: !1,
12627
12593
  logSkipped: !1,
12628
12594
  timings: /* @__PURE__ */ new Map(),
@@ -12656,7 +12622,7 @@ var Rf = class {
12656
12622
  }
12657
12623
  try {
12658
12624
  let n = this.stats.enabled ? performance.now() : 0;
12659
- if (If(t, this.renderer, () => t.render(this.context, e)), this.stats.enabled) {
12625
+ if (Rf(t, this.renderer, () => t.render(this.context, e)), this.stats.enabled) {
12660
12626
  let e = performance.now() - n;
12661
12627
  this.stats.timings.has(t.name) || this.stats.timings.set(t.name, []);
12662
12628
  let r = this.stats.timings.get(t.name);
@@ -12754,7 +12720,7 @@ var Rf = class {
12754
12720
  let e = this.getInfo();
12755
12721
  console.group("[Pipeline] Info"), console.log("Stages:", e.stages), console.log("Context Textures:", e.textures), console.log("Context Render Targets:", e.renderTargets), console.log("Context Uniforms:", e.uniforms), console.log("Event Types:", e.events), console.log("State:", e.contextState), console.groupEnd();
12756
12722
  }
12757
- }, zf = class {
12723
+ }, Vf = class {
12758
12724
  constructor() {
12759
12725
  this.timeElapsed = 0, this.lastResetTime = performance.now(), this.renderCompleteDispatched = !1;
12760
12726
  }
@@ -12776,7 +12742,7 @@ var Rf = class {
12776
12742
  resumeFromPause() {
12777
12743
  this.renderCompleteDispatched = !1, this.lastResetTime = performance.now() - this.timeElapsed * 1e3;
12778
12744
  }
12779
- }, Bf = class extends ut {
12745
+ }, Hf = class extends ut {
12780
12746
  constructor({ scene: e, camera: t, canvas: n, assetLoader: r, pathTracer: i, floorPlane: a }) {
12781
12747
  super(), this.scene = e, this.camera = t, this.canvas = n, this.assetLoader = r, this.pathTracer = i, this.floorPlane = a, this.raycaster = new Ut(), this.focusMode = !1, this.focusPointIndicator = null, this.afPointPlacementMode = !1, this.handleAFPointClick = this.handleAFPointClick.bind(this), this.selectedObject = null, this.selectMode = !1, this.clickTimeout = null, this.mouseDownPosition = null, this.dragThreshold = 5, this.handleFocusClick = this.handleFocusClick.bind(this), this.handleSelectClick = this.handleSelectClick.bind(this), this.handleSelectDoubleClick = this.handleSelectDoubleClick.bind(this), this.handleMouseDown = this.handleMouseDown.bind(this), this.handleMouseUp = this.handleMouseUp.bind(this), this.handleContextMenu = this.handleContextMenu.bind(this), this.handleContextPointerDown = this.handleContextPointerDown.bind(this), this.handleContextPointerUp = this.handleContextPointerUp.bind(this), this.contextPointerDownPosition = null, this.canvas.addEventListener("pointerdown", this.handleContextPointerDown), this.canvas.addEventListener("pointerup", this.handleContextPointerUp), this.canvas.addEventListener("contextmenu", this.handleContextMenu), this._overlayManager = null, this._transformManager = null, this._appDispatch = null, this._orbitControls = null, this._helperScene = null;
12782
12748
  }
@@ -13012,18 +12978,18 @@ var Rf = class {
13012
12978
  dispose() {
13013
12979
  this.canvas.removeEventListener("click", this.handleAFPointClick), this.canvas.removeEventListener("click", this.handleFocusClick), this.canvas.removeEventListener("mousedown", this.handleMouseDown), this.canvas.removeEventListener("mouseup", this.handleMouseUp), this.canvas.removeEventListener("click", this.handleSelectClick), this.canvas.removeEventListener("dblclick", this.handleSelectDoubleClick), this.canvas.removeEventListener("contextmenu", this.handleContextMenu), this.canvas.removeEventListener("pointerdown", this.handleContextPointerDown), this.canvas.removeEventListener("pointerup", this.handleContextPointerUp), this.clickTimeout &&= (clearTimeout(this.clickTimeout), null), this.mouseDownPosition = null, this.contextPointerDownPosition = null, this.focusPointIndicator &&= (this.scene.remove(this.focusPointIndicator), null), this.canvas.style.cursor = "auto", this.scene = null, this.camera = null, this.canvas = null, this.assetLoader = null, this.pathTracer = null, this.floorPlane = null, this.raycaster = null;
13014
12980
  }
13015
- }, Vf = {
12981
+ }, Uf = {
13016
12982
  STRING: "string",
13017
12983
  NUMBER: "number",
13018
12984
  WORD: "word",
13019
12985
  LBRACKET: "[",
13020
12986
  RBRACKET: "]"
13021
- }, Hf = (e) => e === " " || e === " " || e === "\n" || e === "\r" || e === "\f", Uf = (e) => e >= "0" && e <= "9", Wf = (e, t, n) => !!(Uf(e) || e === "." && Uf(t) || (e === "-" || e === "+") && (Uf(t) || t === "." && Uf(n)));
13022
- function Gf(e) {
12987
+ }, Wf = (e) => e === " " || e === " " || e === "\n" || e === "\r" || e === "\f", Gf = (e) => e >= "0" && e <= "9", Kf = (e, t, n) => !!(Gf(e) || e === "." && Gf(t) || (e === "-" || e === "+") && (Gf(t) || t === "." && Gf(n)));
12988
+ function qf(e) {
13023
12989
  let t = [], n = e.length, r = 0;
13024
12990
  for (; r < n;) {
13025
12991
  let i = e[r];
13026
- if (Hf(i)) {
12992
+ if (Wf(i)) {
13027
12993
  r++;
13028
12994
  continue;
13029
12995
  }
@@ -13032,11 +12998,11 @@ function Gf(e) {
13032
12998
  continue;
13033
12999
  }
13034
13000
  if (i === "[") {
13035
- t.push({ type: Vf.LBRACKET }), r++;
13001
+ t.push({ type: Uf.LBRACKET }), r++;
13036
13002
  continue;
13037
13003
  }
13038
13004
  if (i === "]") {
13039
- t.push({ type: Vf.RBRACKET }), r++;
13005
+ t.push({ type: Uf.RBRACKET }), r++;
13040
13006
  continue;
13041
13007
  }
13042
13008
  if (i === "\"") {
@@ -13045,12 +13011,12 @@ function Gf(e) {
13045
13011
  for (; r < n && e[r] !== "\"";) r++;
13046
13012
  if (r >= n) throw Error("PBRT tokenizer: unterminated string literal");
13047
13013
  t.push({
13048
- type: Vf.STRING,
13014
+ type: Uf.STRING,
13049
13015
  value: e.slice(i, r)
13050
13016
  }), r++;
13051
13017
  continue;
13052
13018
  }
13053
- if (Wf(i, e[r + 1], e[r + 2])) {
13019
+ if (Kf(i, e[r + 1], e[r + 2])) {
13054
13020
  let i = r;
13055
13021
  for (r++; r < n;) {
13056
13022
  let t = e[r];
@@ -13060,16 +13026,16 @@ function Gf(e) {
13060
13026
  let a = e.slice(i, r), o = Number(a);
13061
13027
  if (Number.isNaN(o)) throw Error(`PBRT tokenizer: invalid number "${a}"`);
13062
13028
  t.push({
13063
- type: Vf.NUMBER,
13029
+ type: Uf.NUMBER,
13064
13030
  value: o
13065
13031
  });
13066
13032
  continue;
13067
13033
  }
13068
13034
  {
13069
13035
  let i = r;
13070
- for (; r < n && !Hf(e[r]) && e[r] !== "\"" && e[r] !== "[" && e[r] !== "]" && e[r] !== "#";) r++;
13036
+ for (; r < n && !Wf(e[r]) && e[r] !== "\"" && e[r] !== "[" && e[r] !== "]" && e[r] !== "#";) r++;
13071
13037
  t.push({
13072
- type: Vf.WORD,
13038
+ type: Uf.WORD,
13073
13039
  value: e.slice(i, r)
13074
13040
  });
13075
13041
  }
@@ -13078,7 +13044,7 @@ function Gf(e) {
13078
13044
  }
13079
13045
  //#endregion
13080
13046
  //#region src/Processor/PBRT/PBRTMath.js
13081
- function Kf() {
13047
+ function Jf() {
13082
13048
  return [
13083
13049
  1,
13084
13050
  0,
@@ -13098,7 +13064,7 @@ function Kf() {
13098
13064
  1
13099
13065
  ];
13100
13066
  }
13101
- function qf(e, t) {
13067
+ function Yf(e, t) {
13102
13068
  let n = e[0], r = e[1], i = e[2], a = e[3], o = e[4], s = e[5], c = e[6], l = e[7], u = e[8], d = e[9], f = e[10], p = e[11], m = e[12], h = e[13], g = e[14], _ = e[15], v = t[0], y = t[1], b = t[2], x = t[3], S = t[4], C = t[5], w = t[6], T = t[7], E = t[8], D = t[9], O = t[10], k = t[11], A = t[12], ee = t[13], te = t[14], j = t[15];
13103
13069
  return [
13104
13070
  n * v + o * y + u * b + m * x,
@@ -13119,7 +13085,7 @@ function qf(e, t) {
13119
13085
  a * A + l * ee + p * te + _ * j
13120
13086
  ];
13121
13087
  }
13122
- function Jf(e, t, n) {
13088
+ function Xf(e, t, n) {
13123
13089
  return [
13124
13090
  1,
13125
13091
  0,
@@ -13139,7 +13105,7 @@ function Jf(e, t, n) {
13139
13105
  1
13140
13106
  ];
13141
13107
  }
13142
- function Yf(e, t, n) {
13108
+ function Zf(e, t, n) {
13143
13109
  return [
13144
13110
  e,
13145
13111
  0,
@@ -13159,7 +13125,7 @@ function Yf(e, t, n) {
13159
13125
  1
13160
13126
  ];
13161
13127
  }
13162
- function Xf(e, t, n, r) {
13128
+ function Qf(e, t, n, r) {
13163
13129
  let i = Math.hypot(t, n, r) || 1;
13164
13130
  t /= i, n /= i, r /= i;
13165
13131
  let a = e * Math.PI / 180, o = Math.cos(a), s = Math.sin(a), c = 1 - o, l = c * t * t + o, u = c * t * n - s * r, d = c * t * r + s * n, f = c * t * n + s * r, p = c * n * n + o, m = c * n * r - s * t;
@@ -13182,21 +13148,21 @@ function Xf(e, t, n, r) {
13182
13148
  1
13183
13149
  ];
13184
13150
  }
13185
- function Zf(e, t) {
13151
+ function $f(e, t) {
13186
13152
  return [
13187
13153
  e[0] - t[0],
13188
13154
  e[1] - t[1],
13189
13155
  e[2] - t[2]
13190
13156
  ];
13191
13157
  }
13192
- function Qf(e, t) {
13158
+ function ep(e, t) {
13193
13159
  return [
13194
13160
  e[1] * t[2] - e[2] * t[1],
13195
13161
  e[2] * t[0] - e[0] * t[2],
13196
13162
  e[0] * t[1] - e[1] * t[0]
13197
13163
  ];
13198
13164
  }
13199
- function $f(e) {
13165
+ function tp(e) {
13200
13166
  let t = Math.hypot(e[0], e[1], e[2]) || 1;
13201
13167
  return [
13202
13168
  e[0] / t,
@@ -13204,8 +13170,8 @@ function $f(e) {
13204
13170
  e[2] / t
13205
13171
  ];
13206
13172
  }
13207
- function ep(e, t, n) {
13208
- let r = $f(Zf(t, e)), i = $f(Qf($f(n), r)), a = Qf(r, i);
13173
+ function np(e, t, n) {
13174
+ let r = tp($f(t, e)), i = tp(ep(tp(n), r)), a = ep(r, i);
13209
13175
  return [
13210
13176
  i[0],
13211
13177
  i[1],
@@ -13225,9 +13191,9 @@ function ep(e, t, n) {
13225
13191
  1
13226
13192
  ];
13227
13193
  }
13228
- function tp(e) {
13194
+ function rp(e) {
13229
13195
  let t = e[0], n = e[1], r = e[2], i = e[3], a = e[4], o = e[5], s = e[6], c = e[7], l = e[8], u = e[9], d = e[10], f = e[11], p = e[12], m = e[13], h = e[14], g = e[15], _ = u * h * c - m * d * c + m * s * f - o * h * f - u * s * g + o * d * g, v = p * d * c - l * h * c - p * s * f + a * h * f + l * s * g - a * d * g, y = l * m * c - p * u * c + p * o * f - a * m * f - l * o * g + a * u * g, b = p * u * s - l * m * s - p * o * d + a * m * d + l * o * h - a * u * h, x = t * _ + n * v + r * y + i * b;
13230
- if (x === 0) return Kf();
13196
+ if (x === 0) return Jf();
13231
13197
  let S = 1 / x;
13232
13198
  return [
13233
13199
  _ * S,
@@ -13250,7 +13216,7 @@ function tp(e) {
13250
13216
  }
13251
13217
  //#endregion
13252
13218
  //#region src/Processor/PBRT/PBRTParser.js
13253
- var np = class {
13219
+ var ip = class {
13254
13220
  constructor(e = {}) {
13255
13221
  this.resolveInclude = e.resolveInclude || (() => {
13256
13222
  throw Error("PBRTParser: Include used but no resolveInclude provided");
@@ -13264,14 +13230,14 @@ var np = class {
13264
13230
  instances: [],
13265
13231
  objects: /* @__PURE__ */ new Map(),
13266
13232
  warnings: []
13267
- }, this.ctm = Kf(), this.state = {
13233
+ }, this.ctm = Jf(), this.state = {
13268
13234
  material: null,
13269
13235
  areaLight: null,
13270
13236
  reverseOrientation: !1
13271
13237
  }, this.attributeStack = [], this.transformStack = [], this.coordSystems = /* @__PURE__ */ new Map(), this.currentObject = null, this.objectBeginCTM = null, this.dirStack = [""], this.tokens = [], this.pos = 0, this._warnedUnknown = /* @__PURE__ */ new Set();
13272
13238
  }
13273
13239
  parse(e, t = "") {
13274
- return this.dirStack = [t], this._run(Gf(e)), this.ir;
13240
+ return this.dirStack = [t], this._run(qf(e)), this.ir;
13275
13241
  }
13276
13242
  _peek() {
13277
13243
  return this.tokens[this.pos];
@@ -13281,12 +13247,12 @@ var np = class {
13281
13247
  }
13282
13248
  _expectNumber(e) {
13283
13249
  let t = this._next();
13284
- if (!t || t.type !== Vf.NUMBER) throw Error(`PBRT parser: expected number for ${e}, got ${t ? t.value : "EOF"}`);
13250
+ if (!t || t.type !== Uf.NUMBER) throw Error(`PBRT parser: expected number for ${e}, got ${t ? t.value : "EOF"}`);
13285
13251
  return t.value;
13286
13252
  }
13287
13253
  _expectString(e) {
13288
13254
  let t = this._next();
13289
- if (!t || t.type !== Vf.STRING) throw Error(`PBRT parser: expected string for ${e}, got ${t ? t.value : "EOF"}`);
13255
+ if (!t || t.type !== Uf.STRING) throw Error(`PBRT parser: expected string for ${e}, got ${t ? t.value : "EOF"}`);
13290
13256
  return t.value;
13291
13257
  }
13292
13258
  _readNumbers(e) {
@@ -13295,17 +13261,17 @@ var np = class {
13295
13261
  return t;
13296
13262
  }
13297
13263
  _readBracketedOrBareNumbers(e) {
13298
- if (this._peek() && this._peek().type === Vf.LBRACKET) {
13264
+ if (this._peek() && this._peek().type === Uf.LBRACKET) {
13299
13265
  this._next();
13300
13266
  let e = [];
13301
- for (; this._peek() && this._peek().type !== Vf.RBRACKET;) e.push(this._expectNumber("transform element"));
13267
+ for (; this._peek() && this._peek().type !== Uf.RBRACKET;) e.push(this._expectNumber("transform element"));
13302
13268
  return this._next(), e;
13303
13269
  }
13304
13270
  return this._readNumbers(e);
13305
13271
  }
13306
13272
  _parseParams() {
13307
13273
  let e = {};
13308
- for (; this._peek() && this._peek().type === Vf.STRING;) {
13274
+ for (; this._peek() && this._peek().type === Uf.STRING;) {
13309
13275
  let t = this._next().value.trim().split(/\s+/), n = t[0], r = t[1] === void 0 ? t[0] : t[1];
13310
13276
  e[r] = {
13311
13277
  type: n,
@@ -13316,23 +13282,23 @@ var np = class {
13316
13282
  }
13317
13283
  _parseParamValue() {
13318
13284
  let e = [];
13319
- if (this._peek() && this._peek().type === Vf.LBRACKET) {
13320
- for (this._next(); this._peek() && this._peek().type !== Vf.RBRACKET;) e.push(this._coerceValueToken(this._next()));
13285
+ if (this._peek() && this._peek().type === Uf.LBRACKET) {
13286
+ for (this._next(); this._peek() && this._peek().type !== Uf.RBRACKET;) e.push(this._coerceValueToken(this._next()));
13321
13287
  this._next();
13322
13288
  } else e.push(this._coerceValueToken(this._next()));
13323
13289
  return e;
13324
13290
  }
13325
13291
  _coerceValueToken(e) {
13326
13292
  if (!e) throw Error("PBRT parser: unexpected EOF in parameter value");
13327
- if (e.type === Vf.NUMBER || e.type === Vf.STRING) return e.value;
13328
- if (e.type === Vf.WORD) return e.value === "true" ? !0 : e.value === "false" ? !1 : e.value;
13293
+ if (e.type === Uf.NUMBER || e.type === Uf.STRING) return e.value;
13294
+ if (e.type === Uf.WORD) return e.value === "true" ? !0 : e.value === "false" ? !1 : e.value;
13329
13295
  throw Error(`PBRT parser: unexpected token in parameter value: ${e.type}`);
13330
13296
  }
13331
13297
  _run(e) {
13332
13298
  let t = this.tokens, n = this.pos;
13333
13299
  for (this.tokens = e, this.pos = 0; this.pos < this.tokens.length;) {
13334
13300
  let e = this._next();
13335
- if (e.type !== Vf.WORD) throw Error(`PBRT parser: expected directive, got ${e.type} ${e.value ?? ""}`);
13301
+ if (e.type !== Uf.WORD) throw Error(`PBRT parser: expected directive, got ${e.type} ${e.value ?? ""}`);
13336
13302
  this._directive(e.value);
13337
13303
  }
13338
13304
  this.tokens = t, this.pos = n;
@@ -13340,25 +13306,25 @@ var np = class {
13340
13306
  _directive(e) {
13341
13307
  switch (e) {
13342
13308
  case "Identity":
13343
- this.ctm = Kf();
13309
+ this.ctm = Jf();
13344
13310
  break;
13345
13311
  case "Translate": {
13346
13312
  let [e, t, n] = this._readNumbers(3);
13347
- this.ctm = qf(this.ctm, Jf(e, t, n));
13313
+ this.ctm = Yf(this.ctm, Xf(e, t, n));
13348
13314
  break;
13349
13315
  }
13350
13316
  case "Scale": {
13351
13317
  let [e, t, n] = this._readNumbers(3);
13352
- this.ctm = qf(this.ctm, Yf(e, t, n));
13318
+ this.ctm = Yf(this.ctm, Zf(e, t, n));
13353
13319
  break;
13354
13320
  }
13355
13321
  case "Rotate": {
13356
13322
  let [e, t, n, r] = this._readNumbers(4);
13357
- this.ctm = qf(this.ctm, Xf(e, t, n, r));
13323
+ this.ctm = Yf(this.ctm, Qf(e, t, n, r));
13358
13324
  break;
13359
13325
  }
13360
13326
  case "LookAt": {
13361
- let e = this._readNumbers(9), t = ep([
13327
+ let e = this._readNumbers(9), t = np([
13362
13328
  e[0],
13363
13329
  e[1],
13364
13330
  e[2]
@@ -13371,7 +13337,7 @@ var np = class {
13371
13337
  e[7],
13372
13338
  e[8]
13373
13339
  ]);
13374
- this.ctm = qf(this.ctm, tp(t));
13340
+ this.ctm = Yf(this.ctm, rp(t));
13375
13341
  break;
13376
13342
  }
13377
13343
  case "Transform":
@@ -13379,7 +13345,7 @@ var np = class {
13379
13345
  break;
13380
13346
  case "ConcatTransform": {
13381
13347
  let e = this._readBracketedOrBareNumbers(16);
13382
- this.ctm = qf(this.ctm, e);
13348
+ this.ctm = Yf(this.ctm, e);
13383
13349
  break;
13384
13350
  }
13385
13351
  case "CoordinateSystem":
@@ -13395,7 +13361,7 @@ var np = class {
13395
13361
  this.ir.camera = {
13396
13362
  type: e,
13397
13363
  params: t,
13398
- cameraToWorld: tp(this.ctm)
13364
+ cameraToWorld: rp(this.ctm)
13399
13365
  };
13400
13366
  break;
13401
13367
  }
@@ -13419,7 +13385,7 @@ var np = class {
13419
13385
  this._skipTypeAndParams();
13420
13386
  break;
13421
13387
  case "WorldBegin":
13422
- this.ctm = Kf(), this.state = {
13388
+ this.ctm = Jf(), this.state = {
13423
13389
  material: null,
13424
13390
  areaLight: null,
13425
13391
  reverseOrientation: !1
@@ -13464,7 +13430,7 @@ var np = class {
13464
13430
  this._readNumbers(2);
13465
13431
  break;
13466
13432
  case "MediumInterface":
13467
- this._peek() && this._peek().type === Vf.STRING && this._next(), this._peek() && this._peek().type === Vf.STRING && this._next();
13433
+ this._peek() && this._peek().type === Uf.STRING && this._next(), this._peek() && this._peek().type === Uf.STRING && this._next();
13468
13434
  break;
13469
13435
  case "MakeNamedMedium":
13470
13436
  this._skipNamedAndParams();
@@ -13572,7 +13538,7 @@ var np = class {
13572
13538
  }
13573
13539
  }
13574
13540
  _emitShape(e) {
13575
- this.currentObject === null ? this.ir.shapes.push(e) : (e.relativeCTM = qf(tp(this.objectBeginCTM), e.ctm), this.ir.objects.get(this.currentObject).push(e));
13541
+ this.currentObject === null ? this.ir.shapes.push(e) : (e.relativeCTM = Yf(rp(this.objectBeginCTM), e.ctm), this.ir.objects.get(this.currentObject).push(e));
13576
13542
  }
13577
13543
  _include(e) {
13578
13544
  let t = this.resolveInclude(e, this.dirStack[this.dirStack.length - 1]);
@@ -13581,13 +13547,13 @@ var np = class {
13581
13547
  return;
13582
13548
  }
13583
13549
  let n = e.includes("/") ? e.slice(0, e.lastIndexOf("/")) : "";
13584
- this.dirStack.push(n), this._run(Gf(t)), this.dirStack.pop();
13550
+ this.dirStack.push(n), this._run(qf(t)), this.dirStack.pop();
13585
13551
  }
13586
13552
  _skipTypeAndParams() {
13587
- this._peek() && this._peek().type === Vf.STRING && this._next(), this._parseParams();
13553
+ this._peek() && this._peek().type === Uf.STRING && this._next(), this._parseParams();
13588
13554
  }
13589
13555
  _skipNamedAndParams() {
13590
- this._peek() && this._peek().type === Vf.STRING && this._next(), this._parseParams();
13556
+ this._peek() && this._peek().type === Uf.STRING && this._next(), this._parseParams();
13591
13557
  }
13592
13558
  _num(e, t) {
13593
13559
  return e && e.value.length ? e.value[0] : t;
@@ -13601,7 +13567,7 @@ var np = class {
13601
13567
  _warnUnknown(e) {
13602
13568
  this._warnedUnknown.has(e) || (this._warnedUnknown.add(e), this._warn(`Unsupported directive ignored: ${e}`));
13603
13569
  }
13604
- }, rp = {
13570
+ }, ap = {
13605
13571
  au: [
13606
13572
  1,
13607
13573
  .78,
@@ -13657,12 +13623,12 @@ var np = class {
13657
13623
  .9,
13658
13624
  .9
13659
13625
  ]
13660
- }, ip = [
13626
+ }, op = [
13661
13627
  .92,
13662
13628
  .92,
13663
13629
  .92
13664
13630
  ];
13665
- function ap(e) {
13631
+ function sp(e) {
13666
13632
  let t = Math.max(1e3, Math.min(4e4, e)) / 100, n, r, i;
13667
13633
  t <= 66 ? (n = 255, r = 99.47 * Math.log(t) - 161.12) : (n = 329.7 * (t - 60) ** -.1332, r = 288.12 * (t - 60) ** -.0755), i = t >= 66 ? 255 : t <= 19 ? 0 : 138.52 * Math.log(t - 10) - 305.04;
13668
13634
  let a = (e) => Math.max(0, Math.min(255, e)) / 255;
@@ -13672,15 +13638,15 @@ function ap(e) {
13672
13638
  a(i) ** 2.2
13673
13639
  ];
13674
13640
  }
13675
- function op(e, t, n) {
13641
+ function cp(e, t, n) {
13676
13642
  let r = e[t];
13677
13643
  return r && typeof r.value[0] == "number" ? r.value[0] : n;
13678
13644
  }
13679
- function sp(e, t, n) {
13645
+ function lp(e, t, n) {
13680
13646
  let r = e[t];
13681
13647
  return r && typeof r.value[0] == "string" ? r.value[0] : n;
13682
13648
  }
13683
- async function cp(e, t, n, r = null) {
13649
+ async function up(e, t, n, r = null) {
13684
13650
  let i = e[t];
13685
13651
  if (!i) return {
13686
13652
  rgb: r,
@@ -13719,14 +13685,14 @@ async function cp(e, t, n, r = null) {
13719
13685
  };
13720
13686
  }
13721
13687
  if (i.type === "blackbody") return {
13722
- rgb: ap(i.value[0]),
13688
+ rgb: sp(i.value[0]),
13723
13689
  texture: null
13724
13690
  };
13725
13691
  if (i.type === "spectrum") {
13726
13692
  if (typeof i.value[0] == "string") {
13727
- let e = lp(i.value[0]);
13728
- return e && rp[e] ? {
13729
- rgb: rp[e].slice(),
13693
+ let e = dp(i.value[0]);
13694
+ return e && ap[e] ? {
13695
+ rgb: ap[e].slice(),
13730
13696
  texture: null
13731
13697
  } : (n.warn(`named spectrum "${i.value[0]}" approximated to gray`), {
13732
13698
  rgb: [
@@ -13754,18 +13720,18 @@ async function cp(e, t, n, r = null) {
13754
13720
  texture: null
13755
13721
  };
13756
13722
  }
13757
- function lp(e) {
13723
+ function dp(e) {
13758
13724
  let t = e.toLowerCase().match(/metal-([a-z]+)/);
13759
13725
  if (t) return t[1];
13760
- for (let t of Object.keys(rp)) if (e.toLowerCase().includes(t)) return t;
13726
+ for (let t of Object.keys(ap)) if (e.toLowerCase().includes(t)) return t;
13761
13727
  return null;
13762
13728
  }
13763
- function up(e, t) {
13729
+ function fp(e, t) {
13764
13730
  if (e.roughness && typeof e.roughness.value[0] == "number") return e.roughness.value[0];
13765
- let n = op(e, "uroughness", null), r = op(e, "vroughness", null);
13731
+ let n = cp(e, "uroughness", null), r = cp(e, "vroughness", null);
13766
13732
  return n !== null && r !== null ? (n + r) / 2 : n === null ? t : n;
13767
13733
  }
13768
- async function dp(e, t) {
13734
+ async function pp(e, t) {
13769
13735
  let n = e?.type || "diffuse", r = e?.params || {}, i = new Et({
13770
13736
  side: ct,
13771
13737
  roughness: 1,
@@ -13777,7 +13743,7 @@ async function dp(e, t) {
13777
13743
  };
13778
13744
  switch (n) {
13779
13745
  case "diffuse":
13780
- o(await cp(r, "reflectance", t, [
13746
+ o(await up(r, "reflectance", t, [
13781
13747
  .5,
13782
13748
  .5,
13783
13749
  .5
@@ -13785,14 +13751,14 @@ async function dp(e, t) {
13785
13751
  break;
13786
13752
  case "conductor":
13787
13753
  case "metal": {
13788
- let e = await cp(r, "reflectance", t, null), n = r.eta, s = r.k, c = n && n.type === "spectrum" && typeof n.value[0] == "string";
13754
+ let e = await up(r, "reflectance", t, null), n = r.eta, s = r.k, c = n && n.type === "spectrum" && typeof n.value[0] == "string";
13789
13755
  if (e.rgb || e.texture) o(e);
13790
13756
  else if (n && s && !c) {
13791
- let e = (await cp(r, "eta", t, [
13757
+ let e = (await up(r, "eta", t, [
13792
13758
  .2,
13793
13759
  .92,
13794
13760
  1.1
13795
- ])).rgb, n = (await cp(r, "k", t, [
13761
+ ])).rgb, n = (await up(r, "k", t, [
13796
13762
  3.9,
13797
13763
  2.45,
13798
13764
  2.14
@@ -13802,28 +13768,28 @@ async function dp(e, t) {
13802
13768
  i(e[1], n[1]),
13803
13769
  i(e[2], n[2])
13804
13770
  ]);
13805
- } else a(n ? (await cp(r, "eta", t, ip)).rgb || ip : rp.cu);
13806
- i.metalness = 1, i.roughness = up(r, .1);
13771
+ } else a(n ? (await up(r, "eta", t, op)).rgb || op : ap.cu);
13772
+ i.metalness = 1, i.roughness = fp(r, .1);
13807
13773
  break;
13808
13774
  }
13809
13775
  case "dielectric":
13810
13776
  case "thindielectric":
13811
- i.transmission = 1, i.metalness = 0, i.color.setRGB(1, 1, 1), i.ior = op(r, "eta", 1.5), i.roughness = up(r, 0), i.thickness = n === "thindielectric" ? 0 : op(r, "thickness", 0);
13777
+ i.transmission = 1, i.metalness = 0, i.color.setRGB(1, 1, 1), i.ior = cp(r, "eta", 1.5), i.roughness = fp(r, 0), i.thickness = n === "thindielectric" ? 0 : cp(r, "thickness", 0);
13812
13778
  break;
13813
13779
  case "coateddiffuse":
13814
- o(await cp(r, "reflectance", t, [
13780
+ o(await up(r, "reflectance", t, [
13815
13781
  .5,
13816
13782
  .5,
13817
13783
  .5
13818
- ])), i.roughness = .6, i.metalness = 0, i.clearcoat = 1, i.clearcoatRoughness = up(r, 0);
13784
+ ])), i.roughness = .6, i.metalness = 0, i.clearcoat = 1, i.clearcoatRoughness = fp(r, 0);
13819
13785
  break;
13820
13786
  case "diffusetransmission": {
13821
- let e = await cp(r, "transmittance", t, [
13787
+ let e = await up(r, "transmittance", t, [
13822
13788
  .25,
13823
13789
  .25,
13824
13790
  .25
13825
13791
  ]);
13826
- o(await cp(r, "reflectance", t, [
13792
+ o(await up(r, "reflectance", t, [
13827
13793
  .25,
13828
13794
  .25,
13829
13795
  .25
@@ -13836,9 +13802,9 @@ async function dp(e, t) {
13836
13802
  i.transmission = 1, i.ior = 1, i.roughness = 0, i.color.setRGB(1, 1, 1);
13837
13803
  break;
13838
13804
  case "mix": {
13839
- let e = r.materials?.value || [], n = Math.max(0, Math.min(1, op(r, "amount", .5))), a = e[0] ? t.namedMaterials?.get(e[0]) : null, o = e[1] ? t.namedMaterials?.get(e[1]) : null;
13805
+ let e = r.materials?.value || [], n = Math.max(0, Math.min(1, cp(r, "amount", .5))), a = e[0] ? t.namedMaterials?.get(e[0]) : null, o = e[1] ? t.namedMaterials?.get(e[1]) : null;
13840
13806
  if (a && o) {
13841
- let [e, r] = await Promise.all([dp(a, t), dp(o, t)]), s = (e, t) => e * (1 - n) + t * n;
13807
+ let [e, r] = await Promise.all([pp(a, t), pp(o, t)]), s = (e, t) => e * (1 - n) + t * n;
13842
13808
  i.color.lerpColors(e.color, r.color, n), i.roughness = s(e.roughness, r.roughness), i.metalness = s(e.metalness, r.metalness), i.ior = s(e.ior ?? 1.5, r.ior ?? 1.5), i.transmission = s(e.transmission ?? 0, r.transmission ?? 0), i.thickness = s(e.thickness ?? 0, r.thickness ?? 0), i.clearcoat = s(e.clearcoat ?? 0, r.clearcoat ?? 0), i.clearcoatRoughness = s(e.clearcoatRoughness ?? 0, r.clearcoatRoughness ?? 0), i.emissive.lerpColors(e.emissive, r.emissive, n), i.emissiveIntensity = s(e.emissiveIntensity ?? 0, r.emissiveIntensity ?? 0), i.map = (n < .5 ? e.map : r.map) || null;
13843
13809
  break;
13844
13810
  }
@@ -13848,7 +13814,7 @@ async function dp(e, t) {
13848
13814
  case "subsurface":
13849
13815
  case "hair":
13850
13816
  case "measured":
13851
- t.warn(`material "${n}" not supported — using diffuse approximation`), a((await cp(r, "reflectance", t, [
13817
+ t.warn(`material "${n}" not supported — using diffuse approximation`), a((await up(r, "reflectance", t, [
13852
13818
  .5,
13853
13819
  .5,
13854
13820
  .5
@@ -13862,7 +13828,7 @@ async function dp(e, t) {
13862
13828
  }
13863
13829
  //#endregion
13864
13830
  //#region src/Processor/PBRT/PBRTSceneBuilder.js
13865
- var fp = [
13831
+ var mp = [
13866
13832
  1,
13867
13833
  0,
13868
13834
  0,
@@ -13879,7 +13845,7 @@ var fp = [
13879
13845
  0,
13880
13846
  0,
13881
13847
  1
13882
- ], pp = class {
13848
+ ], hp = class {
13883
13849
  constructor(e = {}) {
13884
13850
  this.resolvePLY = e.resolvePLY || (async () => null), this.resolveImage = e.resolveImage || (async () => null), this.resolveEnvironment = e.resolveEnvironment || e.resolveImage || (async () => null), this.convertHandedness = e.convertHandedness === !0, this.warnings = [], this.report = [], this._materialCache = /* @__PURE__ */ new Map(), this._textureCache = /* @__PURE__ */ new Map();
13885
13851
  }
@@ -13915,7 +13881,7 @@ var fp = [
13915
13881
  continue;
13916
13882
  }
13917
13883
  for (let e of i) {
13918
- let i = qf(r.ctm, e.relativeCTM || e.ctm), a = await this._buildShapeMesh(e, i, `instance_${n++}`);
13884
+ let i = Yf(r.ctm, e.relativeCTM || e.ctm), a = await this._buildShapeMesh(e, i, `instance_${n++}`);
13919
13885
  a && t.add(a);
13920
13886
  }
13921
13887
  }
@@ -13927,7 +13893,7 @@ var fp = [
13927
13893
  i.map && !a && (this.warn(`${n} (${e.type}, "${e.material?.type || "diffuse"}") has a texture map but no UVs — dropping map, using base color`), o = i.clone(), o.map = null);
13928
13894
  let s = new wt(r, o);
13929
13895
  s.name = n;
13930
- let c = this.convertHandedness ? qf(fp, t) : t;
13896
+ let c = this.convertHandedness ? Yf(mp, t) : t;
13931
13897
  new Ct().fromArray(c).decompose(s.position, s.quaternion, s.scale), s.updateMatrix(), r.computeBoundingBox();
13932
13898
  let l = r.boundingBox ? r.boundingBox.clone().applyMatrix4(s.matrix).getSize(new cn()) : new cn();
13933
13899
  return this.report.push({
@@ -13982,7 +13948,7 @@ var fp = [
13982
13948
  return i.setAttribute("position", new dt(Float32Array.from(t), 3)), i.setIndex(r), i.computeVertexNormals(), i;
13983
13949
  }
13984
13950
  async _plyMesh(e) {
13985
- let t = sp(e, "filename", null);
13951
+ let t = lp(e, "filename", null);
13986
13952
  if (!t) return this.warn("plymesh missing filename"), null;
13987
13953
  try {
13988
13954
  let e = await this.resolvePLY(t);
@@ -13992,10 +13958,10 @@ var fp = [
13992
13958
  }
13993
13959
  }
13994
13960
  _sphere(e) {
13995
- return new Zt(op(e, "radius", 1), 48, 32);
13961
+ return new Zt(cp(e, "radius", 1), 48, 32);
13996
13962
  }
13997
13963
  _disk(e) {
13998
- let t = op(e, "radius", 1), n = op(e, "innerradius", 0), r = op(e, "height", 0), i = [], a = [];
13964
+ let t = cp(e, "radius", 1), n = cp(e, "innerradius", 0), r = cp(e, "height", 0), i = [], a = [];
13999
13965
  for (let e = 0; e < 48; e++) {
14000
13966
  let o = e / 48 * Math.PI * 2, s = (e + 1) / 48 * Math.PI * 2, c = i.length / 3;
14001
13967
  i.push(Math.cos(o) * n, Math.sin(o) * n, r), i.push(Math.cos(o) * t, Math.sin(o) * t, r), i.push(Math.cos(s) * t, Math.sin(s) * t, r), i.push(Math.cos(s) * n, Math.sin(s) * n, r), a.push(c, c + 1, c + 2, c, c + 2, c + 3);
@@ -14010,15 +13976,15 @@ var fp = [
14010
13976
  resolveNamedTexture: (e) => this._resolveNamedTexture(e),
14011
13977
  namedMaterials: this.ir.namedMaterials,
14012
13978
  warn: (e) => this.warn(e)
14013
- }, r = await dp(e.material, n);
13979
+ }, r = await pp(e.material, n);
14014
13980
  return e.areaLight && await this._applyAreaLight(r, e.areaLight, n), t.set(e.areaLight, r), r;
14015
13981
  }
14016
13982
  async _applyAreaLight(e, t, n) {
14017
- let r = await cp(t.params, "L", n, [
13983
+ let r = await up(t.params, "L", n, [
14018
13984
  1,
14019
13985
  1,
14020
13986
  1
14021
- ]), i = op(t.params, "scale", 1), a = r.rgb || [
13987
+ ]), i = cp(t.params, "scale", 1), a = r.rgb || [
14022
13988
  1,
14023
13989
  1,
14024
13990
  1
@@ -14030,7 +13996,7 @@ var fp = [
14030
13996
  let t = this.ir.namedTextures.get(e), n = null;
14031
13997
  if (!t) this.warn(`named texture "${e}" not defined`);
14032
13998
  else if (t.class === "imagemap") {
14033
- let r = sp(t.params, "filename", null);
13999
+ let r = lp(t.params, "filename", null);
14034
14000
  if (r) try {
14035
14001
  let t = await this.resolveImage(r);
14036
14002
  t ? n = { texture: t } : this.warn(`image not found for texture "${e}": ${r}`);
@@ -14118,7 +14084,7 @@ var fp = [
14118
14084
  return c.name = "PBRT Camera", c.up.copy(a.normalize()), c.position.copy(r), c.lookAt(o), c.updateMatrixWorld(!0), c;
14119
14085
  }
14120
14086
  _verticalFov(e, t) {
14121
- let n = op(e, "fov", 90);
14087
+ let n = cp(e, "fov", 90);
14122
14088
  if (t >= 1) return n;
14123
14089
  let r = n * Math.PI / 180;
14124
14090
  return 2 * Math.atan(Math.tan(r / 2) / t) * 180 / Math.PI;
@@ -14126,7 +14092,7 @@ var fp = [
14126
14092
  async _buildEnvironment(e) {
14127
14093
  let t = e.find((e) => e.type === "infinite");
14128
14094
  if (!t) return null;
14129
- let n = op(t.params, "scale", 1), r = sp(t.params, "filename", null);
14095
+ let n = cp(t.params, "scale", 1), r = lp(t.params, "filename", null);
14130
14096
  if (r) try {
14131
14097
  let e = await this.resolveEnvironment(r);
14132
14098
  if (e) return e.mapping = lt, { texture: e };
@@ -14134,7 +14100,7 @@ var fp = [
14134
14100
  } catch (e) {
14135
14101
  this.warn(`failed to load infinite-light image ${r}: ${e.message}`);
14136
14102
  }
14137
- let i = ((await cp(t.params, "L", {
14103
+ let i = ((await up(t.params, "L", {
14138
14104
  resolveNamedTexture: async () => null,
14139
14105
  warn: (e) => this.warn(e)
14140
14106
  }, [
@@ -14153,20 +14119,20 @@ var fp = [
14153
14119
  _reportUnsupportedLights(e) {
14154
14120
  for (let t of e) t.type !== "infinite" && this.warn(`light "${t.type}" not supported (only infinite lights and emissive area lights are mapped)`);
14155
14121
  }
14156
- }, mp = new TextDecoder();
14157
- function hp(e) {
14122
+ }, gp = new TextDecoder();
14123
+ function _p(e) {
14158
14124
  let t = e.replace(/\\/g, "/").split("/"), n = [];
14159
14125
  for (let e of t) e === "" || e === "." || (e === ".." ? n.pop() : n.push(e));
14160
14126
  return n.join("/");
14161
14127
  }
14162
- function gp(e, t) {
14163
- return !e || t.startsWith("/") ? hp(t) : hp(`${e}/${t}`);
14128
+ function vp(e, t) {
14129
+ return !e || t.startsWith("/") ? _p(t) : _p(`${e}/${t}`);
14164
14130
  }
14165
- var _p = class {
14131
+ var yp = class {
14166
14132
  constructor(e) {
14167
14133
  this.byPath = /* @__PURE__ */ new Map(), this.byBase = /* @__PURE__ */ new Map();
14168
14134
  for (let t in e) {
14169
- let n = hp(t).toLowerCase(), r = {
14135
+ let n = _p(t).toLowerCase(), r = {
14170
14136
  norm: n,
14171
14137
  bytes: e[t]
14172
14138
  };
@@ -14176,13 +14142,13 @@ var _p = class {
14176
14142
  }
14177
14143
  }
14178
14144
  find(e) {
14179
- let t = hp(e).toLowerCase();
14145
+ let t = _p(e).toLowerCase();
14180
14146
  if (this.byPath.has(t)) return this.byPath.get(t).bytes;
14181
14147
  let n = this.byBase.get(t.split("/").pop());
14182
14148
  return n ? (n.find((e) => e.norm.endsWith("/" + t)) || n[0]).bytes : null;
14183
14149
  }
14184
14150
  };
14185
- function vp(e) {
14151
+ function bp(e) {
14186
14152
  let t = Object.keys(e).filter((e) => e.toLowerCase().endsWith(".pbrt"));
14187
14153
  if (t.length === 0) return null;
14188
14154
  let n = t.filter((e) => /(^|\/)(scene|main)\.pbrt$/i.test(e)), r = n.length ? n : t;
@@ -14191,17 +14157,17 @@ function vp(e) {
14191
14157
  return n === r ? e.length - t.length : n - r;
14192
14158
  }), r[0];
14193
14159
  }
14194
- async function yp(e) {
14195
- let { vfs: t, plyParser: n, imageFromBytes: r, envFromBytes: i, convertHandedness: a } = e, o = new _p(t), s = e.entryPath || vp(t);
14160
+ async function xp(e) {
14161
+ let { vfs: t, plyParser: n, imageFromBytes: r, envFromBytes: i, convertHandedness: a } = e, o = new yp(t), s = e.entryPath || bp(t);
14196
14162
  if (!s) throw Error("PBRT loader: no .pbrt file found in archive");
14197
14163
  let c = o.find(s);
14198
14164
  if (!c) throw Error(`PBRT loader: entry "${s}" not readable`);
14199
- let l = s.includes("/") ? s.slice(0, s.lastIndexOf("/")) : "", u = new np({ resolveInclude: (e, t) => {
14200
- let n = o.find(gp(t, e)) || o.find(e);
14201
- return n ? mp.decode(n) : null;
14202
- } }).parse(mp.decode(c), l), d = (e) => e.buffer.slice(e.byteOffset, e.byteOffset + e.byteLength);
14165
+ let l = s.includes("/") ? s.slice(0, s.lastIndexOf("/")) : "", u = new ip({ resolveInclude: (e, t) => {
14166
+ let n = o.find(vp(t, e)) || o.find(e);
14167
+ return n ? gp.decode(n) : null;
14168
+ } }).parse(gp.decode(c), l), d = (e) => e.buffer.slice(e.byteOffset, e.byteOffset + e.byteLength);
14203
14169
  return {
14204
- ...await new pp({
14170
+ ...await new hp({
14205
14171
  convertHandedness: a,
14206
14172
  resolvePLY: async (e) => {
14207
14173
  let t = o.find(e);
@@ -14221,7 +14187,7 @@ async function yp(e) {
14221
14187
  }
14222
14188
  //#endregion
14223
14189
  //#region src/Processor/AssetLoader.js
14224
- var bp = {
14190
+ var Sp = {
14225
14191
  glb: {
14226
14192
  type: "model",
14227
14193
  name: "GLB (GLTF Binary)"
@@ -14286,7 +14252,7 @@ var bp = {
14286
14252
  type: "archive",
14287
14253
  name: "ZIP Archive"
14288
14254
  }
14289
- }, xp = class e extends ut {
14255
+ }, Cp = class e extends ut {
14290
14256
  constructor(e, t, n) {
14291
14257
  super(), this.scene = e, this.camera = t, this.controls = n, this.targetModel = null, this._externalModel = null, this.floorPlane = null, this.sceneScale = 1, this.loaderCache = {}, this.uploadedFileInfo = null, this.animations = [], this.renderer = null, this._loadingManager = new vt(), this._loadCancelled = !1;
14292
14258
  }
@@ -14332,7 +14298,7 @@ var bp = {
14332
14298
  this.renderer = e;
14333
14299
  }
14334
14300
  getFileFormat(e) {
14335
- return bp[e.split(".").pop().toLowerCase()] || null;
14301
+ return Sp[e.split(".").pop().toLowerCase()] || null;
14336
14302
  }
14337
14303
  readFileAsArrayBuffer(e) {
14338
14304
  return new Promise((t, n) => {
@@ -14467,7 +14433,7 @@ var bp = {
14467
14433
  async loadArchiveFromFile(e, t) {
14468
14434
  try {
14469
14435
  let n = await this.readFileAsArrayBuffer(e), r = yn(new Uint8Array(n));
14470
- return vp(r) ? await this.loadPBRTFromZip(r, t) : await this.processObjMtlPairsInZip(r, t) || await this.findAndLoadModelFromZip(r, t);
14436
+ return bp(r) ? await this.loadPBRTFromZip(r, t) : await this.processObjMtlPairsInZip(r, t) || await this.findAndLoadModelFromZip(r, t);
14471
14437
  } catch (e) {
14472
14438
  throw console.error("Error loading ZIP archive:", e), e;
14473
14439
  }
@@ -14481,7 +14447,7 @@ var bp = {
14481
14447
  let { PLYLoader: e } = await import("three/examples/jsm/loaders/PLYLoader.js");
14482
14448
  this.loaderCache.ply = new e();
14483
14449
  }
14484
- let { group: n, environment: r, report: i, warnings: a, entryPath: o } = await yp({
14450
+ let { group: n, environment: r, report: i, warnings: a, entryPath: o } = await xp({
14485
14451
  vfs: e,
14486
14452
  plyParser: (e) => this.loaderCache.ply.parse(e),
14487
14453
  imageFromBytes: (e, t) => this._pbrtTextureFromBytes(e, t),
@@ -14580,7 +14546,7 @@ var bp = {
14580
14546
  }
14581
14547
  for (let t in e) {
14582
14548
  let n = t.split(".").pop().toLowerCase();
14583
- if (bp[n] && bp[n].type === "model") return console.log(`Loading model file from ZIP: ${t}`), await this.loadModelFromZipEntry(e[t], t, n, e);
14549
+ if (Sp[n] && Sp[n].type === "model") return console.log(`Loading model file from ZIP: ${t}`), await this.loadModelFromZipEntry(e[t], t, n, e);
14584
14550
  }
14585
14551
  throw Error("No supported model files found in the ZIP archive");
14586
14552
  }
@@ -15140,10 +15106,10 @@ var bp = {
15140
15106
  getSupportedFormats(e = null) {
15141
15107
  if (e) {
15142
15108
  let t = {};
15143
- for (let [n, r] of Object.entries(bp)) r.type === e && (t[n] = r);
15109
+ for (let [n, r] of Object.entries(Sp)) r.type === e && (t[n] = r);
15144
15110
  return t;
15145
15111
  }
15146
- return bp;
15112
+ return Sp;
15147
15113
  }
15148
15114
  dispose() {
15149
15115
  for (let e in this.loaderCache) {
@@ -15155,7 +15121,7 @@ var bp = {
15155
15121
  removeAllEventListeners() {
15156
15122
  this._listeners = void 0;
15157
15123
  }
15158
- }, Sp = {
15124
+ }, wp = {
15159
15125
  maxBounces: {
15160
15126
  uniform: "maxBounces",
15161
15127
  reset: !0
@@ -15224,6 +15190,10 @@ var bp = {
15224
15190
  uniform: "globalIlluminationIntensity",
15225
15191
  reset: !0
15226
15192
  },
15193
+ panoramaLevelHorizon: {
15194
+ uniform: "panoLevelHorizon",
15195
+ reset: !0
15196
+ },
15227
15197
  enableDOF: {
15228
15198
  uniform: "enableDOF",
15229
15199
  reset: !0
@@ -15304,6 +15274,18 @@ var bp = {
15304
15274
  uniform: "debugVisScale",
15305
15275
  reset: !0
15306
15276
  },
15277
+ cameraProjection: {
15278
+ handler: "handleCameraProjection",
15279
+ reset: !0
15280
+ },
15281
+ panoramaLonRange: {
15282
+ handler: "handlePanoramaLonRange",
15283
+ reset: !0
15284
+ },
15285
+ panoramaLatRange: {
15286
+ handler: "handlePanoramaLatRange",
15287
+ reset: !0
15288
+ },
15307
15289
  interactionModeEnabled: {
15308
15290
  handler: "handleInteractionModeEnabled",
15309
15291
  reset: !1
@@ -15326,18 +15308,27 @@ var bp = {
15326
15308
  },
15327
15309
  renderMode: { handler: "handleRenderMode" },
15328
15310
  environmentRotation: { handler: "handleEnvironmentRotation" }
15329
- }, Cp = {
15311
+ }, Tp = {
15330
15312
  bounces: "maxBounces",
15331
15313
  debugMode: "visMode"
15332
- }, wp = class extends ut {
15314
+ }, Ep = class extends ut {
15333
15315
  constructor(e = J) {
15334
15316
  super(), this._values = /* @__PURE__ */ new Map(), this._pathTracer = null, this._resetCallback = null, this._handlers = {}, this._delegates = {}, this._initDefaults(e);
15335
15317
  }
15336
- bind({ stages: e, renderer: t, resetCallback: n, reconcileCompletion: r }) {
15337
- this._pathTracer = e.pathTracer, this._resetCallback = n, this._delegates = {}, this._handlers = this._buildHandlers(e, t, r);
15318
+ bind(e) {
15319
+ this._pathTracer = e.stages.pathTracer, this._resetCallback = e.resetCallback, this._delegates = {}, this._handlers = this._buildHandlers(e);
15338
15320
  }
15339
- _buildHandlers(e, t, n) {
15321
+ _buildHandlers({ stages: e, renderer: t, reconcileCompletion: n, denoisingManager: r, cameraManager: i }) {
15322
+ let a = new sn(), o = (t, n) => {
15323
+ a.set(n?.[0] ?? 0, n?.[1] ?? 0).multiplyScalar(xt.DEG2RAD), e.pathTracer?.setUniform(t, a);
15324
+ };
15340
15325
  return {
15326
+ handleCameraProjection: (t) => {
15327
+ let n = t === "equirectangular";
15328
+ e.pathTracer?.setUniform("cameraProjection", +!!n), n && (r?.denoiserStrategy === "asvgf" && r.setDenoiserStrategy("edgeaware"), i?.setAutoFocusMode("manual"));
15329
+ },
15330
+ handlePanoramaLonRange: (e) => o("panoLonRange", e),
15331
+ handlePanoramaLatRange: (e) => o("panoLatRange", e),
15341
15332
  handleTransparentBackground: (t) => {
15342
15333
  e.pathTracer?.setUniform("transparentBackground", t), e.compositor?.setTransparentBackground(t);
15343
15334
  },
@@ -15375,7 +15366,7 @@ var bp = {
15375
15366
  let i = this._values.get(e);
15376
15367
  if (i === t) return;
15377
15368
  this._values.set(e, t);
15378
- let a = Sp[e];
15369
+ let a = wp[e];
15379
15370
  a && (this._applyRoute(a, t, i), (n === void 0 ? a.reset ?? !0 : n) && this._resetCallback?.(), r || this.dispatchEvent({
15380
15371
  type: dr.SETTING_CHANGED,
15381
15372
  key: e,
@@ -15389,7 +15380,7 @@ var bp = {
15389
15380
  let e = this._values.get(n);
15390
15381
  if (e === i) continue;
15391
15382
  this._values.set(n, i);
15392
- let a = Sp[n];
15383
+ let a = wp[n];
15393
15384
  a && (this._applyRoute(a, i, e), (a.reset ?? !0) && (r = !0), t || this.dispatchEvent({
15394
15385
  type: dr.SETTING_CHANGED,
15395
15386
  key: n,
@@ -15407,7 +15398,7 @@ var bp = {
15407
15398
  }
15408
15399
  applyAll() {
15409
15400
  for (let [e, t] of this._values) {
15410
- let n = Sp[e];
15401
+ let n = wp[e];
15411
15402
  n && this._applyRoute(n, t, void 0);
15412
15403
  }
15413
15404
  }
@@ -15415,10 +15406,10 @@ var bp = {
15415
15406
  e.uniform ? (this._pathTracer?.setUniform(e.uniform, t), e.after && this._pathTracer?.[e.after]?.()) : e.handler ? this._handlers[e.handler]?.(t, n) : e.delegate && this._delegates[e.delegate]?.updateParam?.(e.param, t);
15416
15407
  }
15417
15408
  _initDefaults(e) {
15418
- for (let t of Object.keys(Sp)) t in e && this._values.set(t, e[t]);
15419
- for (let [t, n] of Object.entries(Cp)) t in e && this._values.set(n, e[t]);
15409
+ for (let t of Object.keys(wp)) t in e && this._values.set(t, e[t]);
15410
+ for (let [t, n] of Object.entries(Tp)) t in e && this._values.set(n, e[t]);
15420
15411
  }
15421
- }, Tp = class extends ut {
15412
+ }, Dp = class extends ut {
15422
15413
  constructor(e) {
15423
15414
  super();
15424
15415
  let t = e.clientWidth, n = e.clientHeight;
@@ -15584,7 +15575,7 @@ var bp = {
15584
15575
  dispose() {
15585
15576
  this.controls?.dispose();
15586
15577
  }
15587
- }, Ep = class extends ut {
15578
+ }, Op = class extends ut {
15588
15579
  constructor(e, t, n, r = {}) {
15589
15580
  super(), this.scene = e, this.sceneHelpers = t, this.pathTracer = n, this._onReset = r.onReset || null;
15590
15581
  }
@@ -15744,14 +15735,14 @@ var bp = {
15744
15735
  ], n.distance = e.distance ?? 0, n.penumbra = e.penumbra ?? 0, n.decay = e.decay ?? 2) : e.type === "PointLight" && (n.distance = e.distance ?? 0, n.decay = e.decay ?? 2);
15745
15736
  return (e.type === "SpotLight" || e.type === "DirectionalLight") && e.userData?.gobo && (n.gobo = e.userData.gobo.name, n.goboIntensity = e.userData.gobo.intensity, n.goboInverted = !!e.userData.gobo.inverted, e.type === "DirectionalLight" && (n.goboScale = e.userData.gobo.scale ?? 5)), e.type === "SpotLight" && e.userData?.ies && (n.ies = e.userData.ies.name, n.iesIntensity = e.userData.ies.intensity ?? 1, n.fixtureLumens = e.userData.ies.fixtureLumens ?? null), n;
15746
15737
  }
15747
- }, Dp = class {
15738
+ }, kp = class {
15748
15739
  constructor(e, t = {}) {
15749
15740
  this.pathTracer = e, this._onReset = t.onReset || null, this.texture = null, this.entries = [], this._size = 256;
15750
15741
  }
15751
15742
  async loadLibrary(e, { size: t = 256 } = {}) {
15752
15743
  if (!Array.isArray(e) || e.length === 0) return [];
15753
15744
  this._size = t;
15754
- let n = await Promise.all(e.map((e) => Op(e.url))), r = t, i = t, a = n.length, o = new Uint8Array(r * i * a * 4), s = document.createElement("canvas");
15745
+ let n = await Promise.all(e.map((e) => Ap(e.url))), r = t, i = t, a = n.length, o = new Uint8Array(r * i * a * 4), s = document.createElement("canvas");
15755
15746
  s.width = r, s.height = i;
15756
15747
  let c = s.getContext("2d", { willReadFrequently: !0 });
15757
15748
  for (let e = 0; e < a; e++) {
@@ -15780,7 +15771,7 @@ var bp = {
15780
15771
  o.userData.gobo = {
15781
15772
  name: e.name,
15782
15773
  index: e.index,
15783
- intensity: kp(r),
15774
+ intensity: jp(r),
15784
15775
  inverted: !!i,
15785
15776
  scale: Math.max(1e-4, a)
15786
15777
  };
@@ -15822,28 +15813,28 @@ var bp = {
15822
15813
  return t && t.isSpotLight ? t : null;
15823
15814
  }
15824
15815
  };
15825
- function Op(e) {
15816
+ function Ap(e) {
15826
15817
  return new Promise((t, n) => {
15827
15818
  let r = new Image();
15828
15819
  r.crossOrigin = "anonymous", r.onload = () => t(r), r.onerror = () => n(/* @__PURE__ */ Error(`Failed to load gobo image: ${e}`)), r.src = e;
15829
15820
  });
15830
15821
  }
15831
- function kp(e) {
15822
+ function jp(e) {
15832
15823
  return Math.max(0, Math.min(1, e));
15833
15824
  }
15834
15825
  //#endregion
15835
15826
  //#region src/Processor/IESParser.js
15836
- function Ap(e, t = "ies") {
15827
+ function Mp(e, t = "ies") {
15837
15828
  let n = e.search(/TILT\s*=/i);
15838
15829
  if (n < 0) throw Error(`IES (${t}): missing TILT line`);
15839
15830
  let r = e.indexOf("\n", n);
15840
15831
  if (r < 0) throw Error(`IES (${t}): truncated TILT line`);
15841
15832
  let i = e.slice(n, r).match(/TILT\s*=\s*(\w+)/i), a = i ? i[1].toUpperCase() : "NONE", o = e.slice(r);
15842
15833
  if (a === "INCLUDE") {
15843
- let e = Pp(o), t = 2 + 2 * Number(e[1]);
15844
- o = Fp(o, t);
15834
+ let e = Ip(o), t = 2 + 2 * Number(e[1]);
15835
+ o = Lp(o, t);
15845
15836
  }
15846
- let s = Pp(o), c = 0, l = () => Number(s[c++]), u = l(), d = l(), f = l(), p = l(), m = l(), h = l();
15837
+ let s = Ip(o), c = 0, l = () => Number(s[c++]), u = l(), d = l(), f = l(), p = l(), m = l(), h = l();
15847
15838
  l(), l(), l(), l();
15848
15839
  let g = l();
15849
15840
  if (l(), l(), !Number.isFinite(p) || p <= 0) throw Error(`IES (${t}): invalid vertical angle count ${p}`);
@@ -15869,18 +15860,18 @@ function Ap(e, t = "ies") {
15869
15860
  name: t
15870
15861
  };
15871
15862
  }
15872
- function jp(e, t, n) {
15863
+ function Np(e, t, n) {
15873
15864
  let r = new Uint8Array(t * n), { verticalAngles: i, horizontalAngles: a, candela: o, maxCandela: s } = e;
15874
15865
  if (s <= 0) return r;
15875
15866
  let c = i[i.length - 1], l = a[a.length - 1], u = a[0], d = a.length === 1 || l === u;
15876
15867
  for (let e = 0; e < n; e++) {
15877
- let f = (e + .5) / n * c, p = Ip(i, f), m = Math.min(p + 1, i.length - 1), h = i[m] - i[p], g = h > 0 ? (f - i[p]) / h : 0;
15868
+ let f = (e + .5) / n * c, p = Rp(i, f), m = Math.min(p + 1, i.length - 1), h = i[m] - i[p], g = h > 0 ? (f - i[p]) / h : 0;
15878
15869
  for (let n = 0; n < t; n++) {
15879
15870
  let i;
15880
- if (d) i = Lp(o[p][0], o[m][0], g);
15871
+ if (d) i = zp(o[p][0], o[m][0], g);
15881
15872
  else {
15882
- let e = u + (n + .5) / t * (l - u), r = Ip(a, e), s = Math.min(r + 1, a.length - 1), c = a[s] - a[r], d = c > 0 ? (e - a[r]) / c : 0, f = o[p][r], h = o[p][s], _ = o[m][r], v = o[m][s];
15883
- i = Lp(Lp(f, h, d), Lp(_, v, d), g);
15873
+ let e = u + (n + .5) / t * (l - u), r = Rp(a, e), s = Math.min(r + 1, a.length - 1), c = a[s] - a[r], d = c > 0 ? (e - a[r]) / c : 0, f = o[p][r], h = o[p][s], _ = o[m][r], v = o[m][s];
15874
+ i = zp(zp(f, h, d), zp(_, v, d), g);
15884
15875
  }
15885
15876
  let c = Math.min(1, Math.max(0, i / s));
15886
15877
  r[e * t + n] = Math.round(c * 255);
@@ -15888,7 +15879,7 @@ function jp(e, t, n) {
15888
15879
  }
15889
15880
  return r;
15890
15881
  }
15891
- function Mp(e, t = .1) {
15882
+ function Pp(e, t = .1) {
15892
15883
  let { verticalAngles: n, horizontalAngles: r, candela: i, maxCandela: a } = e, o = Math.PI / 4;
15893
15884
  if (a <= 0 || !n?.length) return o;
15894
15885
  let s = a * t, c = r.length, l = n[n.length - 1], u = !1;
@@ -15903,7 +15894,7 @@ function Mp(e, t = .1) {
15903
15894
  let d = l * Math.PI / 180;
15904
15895
  return Math.min(Math.max(d, 5 * Math.PI / 180), 89 * Math.PI / 180);
15905
15896
  }
15906
- function Np(e, t, n = .7) {
15897
+ function Fp(e, t, n = .7) {
15907
15898
  let { verticalAngles: r, horizontalAngles: i, candela: a, maxCandela: o } = e;
15908
15899
  if (o <= 0 || !r?.length || t <= 0) return 0;
15909
15900
  let s = o * n, c = i.length, l = 0;
@@ -15916,15 +15907,15 @@ function Np(e, t, n = .7) {
15916
15907
  let u = t * 180 / Math.PI, d = u > 0 ? 1 - l / u : 0;
15917
15908
  return Math.min(Math.max(d, 0), 1);
15918
15909
  }
15919
- function Pp(e) {
15910
+ function Ip(e) {
15920
15911
  return e.split(/\s+/).filter((e) => e.length > 0);
15921
15912
  }
15922
- function Fp(e, t) {
15913
+ function Lp(e, t) {
15923
15914
  let n = /\S+/g, r = 0;
15924
15915
  for (; n.exec(e) !== null;) if (r++, r === t) return e.slice(n.lastIndex);
15925
15916
  return "";
15926
15917
  }
15927
- function Ip(e, t) {
15918
+ function Rp(e, t) {
15928
15919
  if (t <= e[0]) return 0;
15929
15920
  if (t >= e[e.length - 1]) return e.length - 1;
15930
15921
  let n = 0, r = e.length - 1;
@@ -15934,12 +15925,12 @@ function Ip(e, t) {
15934
15925
  }
15935
15926
  return n;
15936
15927
  }
15937
- function Lp(e, t, n) {
15928
+ function zp(e, t, n) {
15938
15929
  return e + (t - e) * n;
15939
15930
  }
15940
15931
  //#endregion
15941
15932
  //#region src/managers/IESManager.js
15942
- var Rp = class {
15933
+ var Bp = class {
15943
15934
  constructor(e, t = {}) {
15944
15935
  this.pathTracer = e, this._onReset = t.onReset || null, this.texture = null, this.entries = [], this._gridWidth = 128, this._gridHeight = 128;
15945
15936
  }
@@ -15950,11 +15941,11 @@ var Rp = class {
15950
15941
  try {
15951
15942
  let r = await fetch(e.url);
15952
15943
  if (!r.ok) throw Error(`HTTP ${r.status}`);
15953
- let i = Ap(await r.text(), e.name);
15944
+ let i = Mp(await r.text(), e.name);
15954
15945
  return {
15955
15946
  it: e,
15956
15947
  profile: i,
15957
- grid: jp(i, t, n)
15948
+ grid: Np(i, t, n)
15958
15949
  };
15959
15950
  } catch (t) {
15960
15951
  return console.warn(`IESManager: failed to load "${e.name}": ${t.message}`), null;
@@ -15968,14 +15959,14 @@ var Rp = class {
15968
15959
  let r = t[e];
15969
15960
  o[n + e * 4 + 0] = r, o[n + e * 4 + 1] = r, o[n + e * 4 + 2] = r, o[n + e * 4 + 3] = 255;
15970
15961
  }
15971
- let i = r[e].profile, c = Mp(i);
15962
+ let i = r[e].profile, c = Pp(i);
15972
15963
  s.push({
15973
15964
  name: r[e].it.name,
15974
15965
  index: e,
15975
15966
  maxCandela: i.maxCandela,
15976
15967
  photometricType: i.photometricType,
15977
15968
  suggestedAngle: c,
15978
- suggestedPenumbra: Np(i, c),
15969
+ suggestedPenumbra: Fp(i, c),
15979
15970
  lumens: i.lumens
15980
15971
  });
15981
15972
  }
@@ -16008,7 +15999,7 @@ var Rp = class {
16008
15999
  l = Number.isFinite(e.lumens) ? e.lumens : null, i.userData.ies = {
16009
16000
  name: e.name,
16010
16001
  index: e.index,
16011
- intensity: zp(n),
16002
+ intensity: Vp(n),
16012
16003
  fixtureLumens: l
16013
16004
  }, r && (Number.isFinite(e.suggestedAngle) && (i.angle = e.suggestedAngle, o = e.suggestedAngle), Number.isFinite(e.suggestedPenumbra) && (i.penumbra = e.suggestedPenumbra, s = e.suggestedPenumbra), i.decay = 2, c = 2);
16014
16005
  }
@@ -16031,44 +16022,44 @@ var Rp = class {
16031
16022
  return t && t.isSpotLight ? t : null;
16032
16023
  }
16033
16024
  };
16034
- function zp(e) {
16025
+ function Vp(e) {
16035
16026
  return Math.max(0, Math.min(1, e));
16036
16027
  }
16037
16028
  //#endregion
16038
16029
  //#region src/Processor/ToneMapCPU.js
16039
- var Bp = (e) => Math.min(Math.max(e, 0), 1);
16040
- function Vp(e, t, n, r, i) {
16041
- i[0] = Bp(e), i[1] = Bp(t), i[2] = Bp(n);
16042
- }
16043
- function Hp(e, t, n, r, i) {
16044
- i[0] = Bp(e * r), i[1] = Bp(t * r), i[2] = Bp(n * r);
16045
- }
16030
+ var Hp = (e) => Math.min(Math.max(e, 0), 1);
16046
16031
  function Up(e, t, n, r, i) {
16047
- e *= r, t *= r, n *= r, i[0] = Bp(e / (e + 1)), i[1] = Bp(t / (t + 1)), i[2] = Bp(n / (n + 1));
16032
+ i[0] = Hp(e), i[1] = Hp(t), i[2] = Hp(n);
16048
16033
  }
16049
16034
  function Wp(e, t, n, r, i) {
16035
+ i[0] = Hp(e * r), i[1] = Hp(t * r), i[2] = Hp(n * r);
16036
+ }
16037
+ function Gp(e, t, n, r, i) {
16038
+ e *= r, t *= r, n *= r, i[0] = Hp(e / (e + 1)), i[1] = Hp(t / (t + 1)), i[2] = Hp(n / (n + 1));
16039
+ }
16040
+ function Kp(e, t, n, r, i) {
16050
16041
  e = Math.max(e * r - .004, 0), t = Math.max(t * r - .004, 0), n = Math.max(n * r - .004, 0);
16051
16042
  let a = (e) => (e * (6.2 * e + .5) / (e * (6.2 * e + 1.7) + .06)) ** 2.2;
16052
16043
  i[0] = a(e), i[1] = a(t), i[2] = a(n);
16053
16044
  }
16054
- function Gp(e, t, n, r, i) {
16045
+ function qp(e, t, n, r, i) {
16055
16046
  e = e * r / .6, t = t * r / .6, n = n * r / .6;
16056
16047
  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);
16057
- a = c(a), o = c(o), s = c(s), i[0] = Bp(1.60475 * a - .53108 * o - .07367 * s), i[1] = Bp(-.10208 * a + 1.10813 * o - .00605 * s), i[2] = Bp(-.00327 * a - .07276 * o + 1.07602 * s);
16048
+ a = c(a), o = c(o), s = c(s), i[0] = Hp(1.60475 * a - .53108 * o - .07367 * s), i[1] = Hp(-.10208 * a + 1.10813 * o - .00605 * s), i[2] = Hp(-.00327 * a - .07276 * o + 1.07602 * s);
16058
16049
  }
16059
- function Kp(e, t, n, r, i) {
16050
+ function Jp(e, t, n, r, i) {
16060
16051
  e *= r, t *= r, n *= r;
16061
16052
  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;
16062
- c = Bp((Math.log2(Math.max(c, 1e-10)) - d) / f), l = Bp((Math.log2(Math.max(l, 1e-10)) - d) / f), u = Bp((Math.log2(Math.max(u, 1e-10)) - d) / f);
16053
+ c = Hp((Math.log2(Math.max(c, 1e-10)) - d) / f), l = Hp((Math.log2(Math.max(l, 1e-10)) - d) / f), u = Hp((Math.log2(Math.max(u, 1e-10)) - d) / f);
16063
16054
  let p = (e) => {
16064
16055
  let t = e * e, n = t * t;
16065
16056
  return 15.5 * n * t - 40.14 * n * e + 31.96 * n - 6.868 * t * e + .4298 * t + .1191 * e - .00232;
16066
16057
  };
16067
16058
  c = p(c), l = p(l), u = p(u);
16068
16059
  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;
16069
- m = Math.max(0, m) ** 2.2, h = Math.max(0, h) ** 2.2, g = Math.max(0, g) ** 2.2, i[0] = Bp(1.6605 * m - .5876 * h - .0728 * g), i[1] = Bp(-.1246 * m + 1.1329 * h - .0083 * g), i[2] = Bp(-.0182 * m - .1006 * h + 1.1187 * g);
16060
+ m = Math.max(0, m) ** 2.2, h = Math.max(0, h) ** 2.2, g = Math.max(0, g) ** 2.2, i[0] = Hp(1.6605 * m - .5876 * h - .0728 * g), i[1] = Hp(-.1246 * m + 1.1329 * h - .0083 * g), i[2] = Hp(-.0182 * m - .1006 * h + 1.1187 * g);
16070
16061
  }
16071
- function qp(e, t, n, r, i) {
16062
+ function Yp(e, t, n, r, i) {
16072
16063
  let a = .76;
16073
16064
  e *= r, t *= r, n *= r;
16074
16065
  let o = Math.min(e, Math.min(t, n)), s = o < .08 ? o - 6.25 * o * o : .04;
@@ -16083,43 +16074,43 @@ function qp(e, t, n, r, i) {
16083
16074
  let f = 1 - 1 / (.15 * (c - u) + 1);
16084
16075
  i[0] = e + (u - e) * f, i[1] = t + (u - t) * f, i[2] = n + (u - n) * f;
16085
16076
  }
16086
- var Jp = new Map([
16087
- [jt, Vp],
16088
- [q, Hp],
16089
- [Kt, Up],
16090
- [Qe, Wp],
16091
- [Ue, Gp],
16092
- [Ge, Kp],
16093
- [kt, qp]
16094
- ]), Yp = 1 / 2.2;
16095
- function Xp(e) {
16077
+ var Xp = new Map([
16078
+ [jt, Up],
16079
+ [q, Wp],
16080
+ [Kt, Gp],
16081
+ [Qe, Kp],
16082
+ [Ue, qp],
16083
+ [Ge, Jp],
16084
+ [kt, Yp]
16085
+ ]), Zp = 1 / 2.2;
16086
+ function Qp(e) {
16096
16087
  return e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055;
16097
16088
  }
16098
- var Zp = .2126, Qp = .7152, $p = .0722;
16099
- function em(e, t) {
16089
+ var $p = .2126, em = .7152, tm = .0722;
16090
+ function nm(e, t) {
16100
16091
  if (t === 1) return;
16101
- let n = e[0] * Zp + e[1] * Qp + e[2] * $p;
16092
+ let n = e[0] * $p + e[1] * em + e[2] * tm;
16102
16093
  e[0] = n + (e[0] - n) * t, e[1] = n + (e[1] - n) * t, e[2] = n + (e[2] - n) * t;
16103
16094
  }
16104
16095
  //#endregion
16105
16096
  //#region src/Passes/OIDNDenoiser.js
16106
- var tm = ai("oidn"), nm = null, rm = null;
16107
- async function im() {
16108
- if (!nm) {
16097
+ var rm = ai("oidn"), im = null, am = null;
16098
+ async function om() {
16099
+ if (!im) {
16109
16100
  let [e, t] = await Promise.all([import("oidn-web"), import("@tensorflow/tfjs-core")]);
16110
- nm = e.initUNetFromURL, rm = t.engine;
16101
+ im = e.initUNetFromURL, am = t.engine;
16111
16102
  }
16112
- return nm;
16103
+ return im;
16113
16104
  }
16114
- function am() {
16115
- if (rm) try {
16116
- let e = rm();
16105
+ function sm() {
16106
+ if (am) try {
16107
+ let e = am();
16117
16108
  e?.registryFactory && "webgpu-oidn" in e.registryFactory && e.removeBackend("webgpu-oidn");
16118
16109
  } catch (e) {
16119
- tm.warn("failed to clear cached TFJS backend", e);
16110
+ rm.warn("failed to clear cached TFJS backend", e);
16120
16111
  }
16121
16112
  }
16122
- var om = new Float32Array(3), sm = {
16113
+ var cm = new Float32Array(3), lm = {
16123
16114
  QUALITY_MODELS: {
16124
16115
  fast: "rt_hdr_alb_nrm_small",
16125
16116
  balance: "rt_hdr_alb_nrm",
@@ -16131,7 +16122,7 @@ var om = new Float32Array(3), sm = {
16131
16122
  debugGbufferMaps: !0,
16132
16123
  tileSize: 256
16133
16124
  }
16134
- }, cm = class extends ut {
16125
+ }, um = class extends ut {
16135
16126
  constructor(e, t, n, r, i = {}) {
16136
16127
  if (super(), !e || !t || !n || !r) throw Error("OIDNDenoiser requires output canvas, renderer, scene, and camera");
16137
16128
  this.renderer = t, this.scene = n, this.camera = r, this.input = t.domElement, this.output = e, this.extractGBufferData = i.extractGBufferData || null, this.getMRTRenderTarget = i.getMRTRenderTarget || null, this.backendParamsGetter = i.backendParams || null, this.getGPUTextures = i.getGPUTextures || null, this.getExposure = i.getExposure || (() => 1), this.getToneMapping = i.getToneMapping || (() => Ue), this.getSaturation = i.getSaturation || (() => 1), this.getTransparentBackground = i.getTransparentBackground || (() => !1), this.isGPUMode = !!this.backendParamsGetter, this.gpuDevice = null, this._gpuInputBuffers = {
@@ -16142,14 +16133,14 @@ var om = new Float32Array(3), sm = {
16142
16133
  width: 0,
16143
16134
  height: 0
16144
16135
  }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._alphaReadbackBuffer = null, this._alphaReadbackMapped = !1, this._cachedAlpha = null, this._cachedAlphaWidth = 0, this.config = {
16145
- ...sm.DEFAULT_OPTIONS,
16136
+ ...lm.DEFAULT_OPTIONS,
16146
16137
  ...i
16147
16138
  }, this.enabled = this.config.enableOIDN, this.quality = this.config.oidnQuality, this.debugGbufferMaps = this.config.debugGbufferMaps, this.tileSize = this.config.tileSize, this.state = {
16148
16139
  isDenoising: !1,
16149
16140
  isLoading: !1,
16150
16141
  abortController: null
16151
16142
  }, this._pendingStagingBuffers = /* @__PURE__ */ new Set(), this._pendingTileBlits = [], this.currentTZAUrl = null, this.unet = null, this._pendingStart = !1, this._initialize().catch((e) => {
16152
- tm.error("init failed:", e), this.dispatchEvent({
16143
+ rm.error("init failed:", e), this.dispatchEvent({
16153
16144
  type: "error",
16154
16145
  error: e
16155
16146
  });
@@ -16195,13 +16186,13 @@ var om = new Float32Array(3), sm = {
16195
16186
  let e = this.backendParamsGetter();
16196
16187
  this.gpuDevice = e?.device ?? null, t = e?.device ? e : void 0;
16197
16188
  }
16198
- this.unet = await (await im())(e, t, {
16189
+ this.unet = await (await om())(e, t, {
16199
16190
  aux: !0,
16200
16191
  hdr: !0,
16201
16192
  maxTileSize: this.tileSize
16202
- }), this.currentTZAUrl = e, this.dispatchEvent({ type: "loaded" }), tm.debug("UNet weights loaded:", e);
16193
+ }), this.currentTZAUrl = e, this.dispatchEvent({ type: "loaded" }), rm.debug("UNet weights loaded:", e);
16203
16194
  } catch (e) {
16204
- tm.error("UNet weights failed to load:", e), this.dispatchEvent({
16195
+ rm.error("UNet weights failed to load:", e), this.dispatchEvent({
16205
16196
  type: "error",
16206
16197
  error: /* @__PURE__ */ Error(`Denoiser loading failed: ${e.message}`)
16207
16198
  });
@@ -16210,14 +16201,14 @@ var om = new Float32Array(3), sm = {
16210
16201
  }
16211
16202
  }
16212
16203
  _generateTzaUrl() {
16213
- let { oidnWeightsBaseUrl: e } = cl(), { QUALITY_MODELS: t } = sm;
16204
+ let { oidnWeightsBaseUrl: e } = cl(), { QUALITY_MODELS: t } = lm;
16214
16205
  return `${e}${t[this.quality] || t.balance}.tza`;
16215
16206
  }
16216
16207
  async updateConfiguration(e) {
16217
16208
  Object.keys(e).some((t) => this.config[t] !== e[t]) && (Object.assign(this.config, e), this.quality = this.config.oidnQuality, this.debugGbufferMaps = this.config.debugGbufferMaps, this.tileSize = this.config.tileSize, await this._setupUNetDenoiser());
16218
16209
  }
16219
16210
  async updateQuality(e) {
16220
- if (!Object.prototype.hasOwnProperty.call(sm.QUALITY_MODELS, e)) throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(sm.QUALITY_MODELS).join(", ")}`);
16211
+ if (!Object.prototype.hasOwnProperty.call(lm.QUALITY_MODELS, e)) throw Error(`Invalid quality setting: ${e}. Must be one of: ${Object.keys(lm.QUALITY_MODELS).join(", ")}`);
16221
16212
  await this.updateConfiguration({ oidnQuality: e });
16222
16213
  }
16223
16214
  async start() {
@@ -16228,7 +16219,7 @@ var om = new Float32Array(3), sm = {
16228
16219
  if (t) {
16229
16220
  this.renderer?.resetState?.(), this.input.style.opacity = "0";
16230
16221
  let t = performance.now() - e;
16231
- tm.debug(`denoise complete in ${Q.ms(t)} · quality ${this.quality}`);
16222
+ rm.debug(`denoise complete in ${Q.ms(t)} · quality ${this.quality}`);
16232
16223
  }
16233
16224
  return t;
16234
16225
  }
@@ -16238,7 +16229,7 @@ var om = new Float32Array(3), sm = {
16238
16229
  try {
16239
16230
  return await this._executeUNet(), !0;
16240
16231
  } catch (e) {
16241
- return e.name === "AbortError" ? tm.debug("denoise aborted") : tm.error("denoise error:", e), this.input.style.opacity = "1", !1;
16232
+ return e.name === "AbortError" ? rm.debug("denoise aborted") : rm.error("denoise error:", e), this.input.style.opacity = "1", !1;
16242
16233
  } finally {
16243
16234
  this.state.isDenoising = !1, this.state.abortController = null, this.dispatchEvent({ type: "end" });
16244
16235
  }
@@ -16248,11 +16239,11 @@ var om = new Float32Array(3), sm = {
16248
16239
  }
16249
16240
  async _executeUNetGPU() {
16250
16241
  let { width: e, height: t } = this.output;
16251
- if (!this.getGPUTextures) return tm.warn("GPU mode enabled but getGPUTextures not provided"), !1;
16242
+ if (!this.getGPUTextures) return rm.warn("GPU mode enabled but getGPUTextures not provided"), !1;
16252
16243
  let n = this.getGPUTextures();
16253
- if (!n?.color) return tm.warn("GPU textures not ready yet"), !1;
16244
+ if (!n?.color) return rm.warn("GPU textures not ready yet"), !1;
16254
16245
  let r = this.gpuDevice;
16255
- if (!r) return tm.warn("gpuDevice not available"), !1;
16246
+ if (!r) return rm.warn("gpuDevice not available"), !1;
16256
16247
  this._ensureGPUInputBuffers(e, t);
16257
16248
  let i = r.createCommandEncoder({ label: "oidn-tex-to-buf" }), a = e * 16, o = this._gpuInputPaddedRowBytes, s = o > a, c = this._gpuInputPadBuffer, l = (n, r) => {
16258
16249
  if (!s) i.copyTextureToBuffer({
@@ -16402,10 +16393,10 @@ var om = new Float32Array(3), sm = {
16402
16393
  }
16403
16394
  r.queue.submit([d.finish()]);
16404
16395
  let f = u.mapAsync(GPUMapMode.READ).then(() => {
16405
- let e = new Float32Array(u.getMappedRange()), t = new ImageData(o, s), r = this.getExposure(), c = this.getSaturation(), l = Jp.get(this.getToneMapping()) || Jp.get(Ue), d = this._cachedAlpha, f = this._cachedAlphaWidth;
16396
+ let e = new Float32Array(u.getMappedRange()), t = new ImageData(o, s), r = this.getExposure(), c = this.getSaturation(), l = Xp.get(this.getToneMapping()) || Xp.get(Ue), d = this._cachedAlpha, f = this._cachedAlphaWidth;
16406
16397
  for (let i = 0, a = e.length; i < a; i += 4) {
16407
16398
  let a = e[i] * r, s = e[i + 1] * r, u = e[i + 2] * r;
16408
- if (c !== 1 && (om[0] = a, om[1] = s, om[2] = u, em(om, c), a = om[0], s = om[1], u = om[2]), l(a, s, u, 1, om), t.data[i] = Xp(om[0]) * 255 + .5 | 0, t.data[i + 1] = Xp(om[1]) * 255 + .5 | 0, t.data[i + 2] = Xp(om[2]) * 255 + .5 | 0, d) {
16399
+ if (c !== 1 && (cm[0] = a, cm[1] = s, cm[2] = u, nm(cm, c), a = cm[0], s = cm[1], u = cm[2]), l(a, s, u, 1, cm), t.data[i] = Qp(cm[0]) * 255 + .5 | 0, t.data[i + 1] = Qp(cm[1]) * 255 + .5 | 0, t.data[i + 2] = Qp(cm[2]) * 255 + .5 | 0, d) {
16409
16400
  let e = (i >> 2) % o, r = (i >> 2) / o | 0;
16410
16401
  t.data[i + 3] = d[(n.y + r) * f + n.x + e];
16411
16402
  } else t.data[i + 3] = 255;
@@ -16432,7 +16423,7 @@ var om = new Float32Array(3), sm = {
16432
16423
  async _displayGPUOutput({ data: e, width: t, height: n }) {
16433
16424
  let r = this.gpuDevice;
16434
16425
  if (!r) {
16435
- tm.error("gpuDevice not available for output readback");
16426
+ rm.error("gpuDevice not available for output readback");
16436
16427
  return;
16437
16428
  }
16438
16429
  let i = t * n * 4 * 4, a = r.createBuffer({
@@ -16443,10 +16434,10 @@ var om = new Float32Array(3), sm = {
16443
16434
  try {
16444
16435
  let o = r.createCommandEncoder({ label: "oidn-readback" });
16445
16436
  o.copyBufferToBuffer(e, 0, a, 0, i), r.queue.submit([o.finish()]), await a.mapAsync(GPUMapMode.READ);
16446
- let s = new Float32Array(a.getMappedRange()), c = new ImageData(t, n), l = this.getExposure(), u = this.getSaturation(), d = Jp.get(this.getToneMapping()) || Jp.get(Ue), f = this._cachedAlpha;
16437
+ let s = new Float32Array(a.getMappedRange()), c = new ImageData(t, n), l = this.getExposure(), u = this.getSaturation(), d = Xp.get(this.getToneMapping()) || Xp.get(Ue), f = this._cachedAlpha;
16447
16438
  for (let e = 0, t = s.length; e < t; e += 4) {
16448
16439
  let t = s[e] * l, n = s[e + 1] * l, r = s[e + 2] * l;
16449
- u !== 1 && (om[0] = t, om[1] = n, om[2] = r, em(om, u), t = om[0], n = om[1], r = om[2]), d(t, n, r, 1, om), c.data[e] = Xp(om[0]) * 255 + .5 | 0, c.data[e + 1] = Xp(om[1]) * 255 + .5 | 0, c.data[e + 2] = Xp(om[2]) * 255 + .5 | 0, c.data[e + 3] = f ? f[e >> 2] : 255;
16440
+ u !== 1 && (cm[0] = t, cm[1] = n, cm[2] = r, nm(cm, u), t = cm[0], n = cm[1], r = cm[2]), d(t, n, r, 1, cm), c.data[e] = Qp(cm[0]) * 255 + .5 | 0, c.data[e + 1] = Qp(cm[1]) * 255 + .5 | 0, c.data[e + 2] = Qp(cm[2]) * 255 + .5 | 0, c.data[e + 3] = f ? f[e >> 2] : 255;
16450
16441
  }
16451
16442
  a.unmap(), this.ctx.putImageData(c, 0, 0);
16452
16443
  } finally {
@@ -16454,12 +16445,12 @@ var om = new Float32Array(3), sm = {
16454
16445
  }
16455
16446
  }
16456
16447
  abort() {
16457
- this._pendingStart = !1, !(!this.enabled || !this.state.isDenoising) && (this.state.abortController?.abort(), this._destroyPendingStagingBuffers(), this.input.style.opacity = "1", this.state.isDenoising = !1, this.dispatchEvent({ type: "end" }), tm.debug("denoise aborted"));
16448
+ this._pendingStart = !1, !(!this.enabled || !this.state.isDenoising) && (this.state.abortController?.abort(), this._destroyPendingStagingBuffers(), this.input.style.opacity = "1", this.state.isDenoising = !1, this.dispatchEvent({ type: "end" }), rm.debug("denoise aborted"));
16458
16449
  }
16459
16450
  setSize(e, t) {
16460
16451
  if (e <= 0 || t <= 0) throw Error(`Invalid dimensions: ${e}x${t}`);
16461
16452
  this.output.width = e, this.output.height = t, this._setupUNetDenoiser().catch((e) => {
16462
- tm.error("reinitialize after size change failed:", e);
16453
+ rm.error("reinitialize after size change failed:", e);
16463
16454
  });
16464
16455
  }
16465
16456
  _destroyPendingStagingBuffers() {
@@ -16467,13 +16458,13 @@ var om = new Float32Array(3), sm = {
16467
16458
  this._pendingStagingBuffers.clear();
16468
16459
  }
16469
16460
  dispose() {
16470
- this.abort(), this._destroyPendingStagingBuffers(), this.unet?.dispose(), am(), this._destroyGPUInputBuffers(), this.output?.parentNode && this.output.remove(), this.unet = null, this.ctx = null, this.state.abortController = null, this.removeAllListeners?.(), tm.debug("disposed");
16461
+ this.abort(), this._destroyPendingStagingBuffers(), this.unet?.dispose(), sm(), this._destroyGPUInputBuffers(), this.output?.parentNode && this.output.remove(), this.unet = null, this.ctx = null, this.state.abortController = null, this.removeAllListeners?.(), rm.debug("disposed");
16471
16462
  }
16472
- }, lm = "let e={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/`,cacheNamespace:`rayzee`},t=null;async function n(){return t||(t=await import(e.ortRuntimeUrl),t.env.wasm.wasmPaths=e.ortWasmPaths,t.env.logLevel=`error`,t)}function r(){return`${e.cacheNamespace}:ai-upscaler-models`}const i=`models`;let a=null,o=null;function s(){return new Promise((e,t)=>{let n=indexedDB.open(r(),1);n.onupgradeneeded=()=>n.result.createObjectStore(i),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}async function c(e){try{let t=await s();return await new Promise((n,r)=>{let a=t.transaction(i,`readonly`).objectStore(i).get(e);a.onsuccess=()=>n(a.result||null),a.onerror=()=>r(a.error)})}catch{return null}}async function l(e,t){try{let n=await s();await new Promise((r,a)=>{let o=n.transaction(i,`readwrite`);o.objectStore(i).put(t,e),o.oncomplete=()=>r(),o.onerror=()=>a(o.error)})}catch{}}async function u(e){let t=await c(e);if(t)return console.log(`AI Upscaler Worker: model loaded from cache (${(t.byteLength/1024/1024).toFixed(1)}MB)`),t;let n=await fetch(e);if(!n.ok)throw Error(`Failed to fetch model: ${n.status}`);let r=await n.arrayBuffer();return l(e,r.slice(0)),r}async function d(e,t){if(a&&o===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}a&&=(await a.release(),null);let[r,i]=await Promise.all([u(e),n()]);a=await i.InferenceSession.create(r,t),o=e;let s=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);s=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${s}`)}catch{}let c=(r.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${c}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:s})}async function f(e,t,r,i){let o=await n(),s=a.inputNames[0],c=a.outputNames[0],l=new o.Tensor(`float32`,e,[1,3,r,t]),u=(await a.run({[s]:l}))[c].data;self.postMessage({type:`inferred`,outputData:u,id:i},[u.buffer])}self.onmessage=async t=>{let{type:n}=t.data;try{n===`load`?(t.data.ortRuntimeUrl&&(e.ortRuntimeUrl=t.data.ortRuntimeUrl),t.data.ortWasmPaths&&(e.ortWasmPaths=t.data.ortWasmPaths),t.data.cacheNamespace&&(e.cacheNamespace=t.data.cacheNamespace),await d(t.data.url,t.data.sessionOptions)):n===`infer`?await f(t.data.tileData,t.data.width,t.data.height,t.data.id):n===`dispose`&&a&&(await a.release(),a=null,o=null)}catch(e){self.postMessage({type:`error`,message:e.message,id:t.data?.id})}};", um = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", lm], { type: "text/javascript;charset=utf-8" });
16473
- function dm(e) {
16463
+ }, dm = "let e={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/`,cacheNamespace:`rayzee`},t=null;async function n(){return t||(t=await import(e.ortRuntimeUrl),t.env.wasm.wasmPaths=e.ortWasmPaths,t.env.logLevel=`error`,t)}function r(){return`${e.cacheNamespace}:ai-upscaler-models`}const i=`models`;let a=null,o=null;function s(){return new Promise((e,t)=>{let n=indexedDB.open(r(),1);n.onupgradeneeded=()=>n.result.createObjectStore(i),n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}async function c(e){try{let t=await s();return await new Promise((n,r)=>{let a=t.transaction(i,`readonly`).objectStore(i).get(e);a.onsuccess=()=>n(a.result||null),a.onerror=()=>r(a.error)})}catch{return null}}async function l(e,t){try{let n=await s();await new Promise((r,a)=>{let o=n.transaction(i,`readwrite`);o.objectStore(i).put(t,e),o.oncomplete=()=>r(),o.onerror=()=>a(o.error)})}catch{}}async function u(e){let t=await c(e);if(t)return console.log(`AI Upscaler Worker: model loaded from cache (${(t.byteLength/1024/1024).toFixed(1)}MB)`),t;let n=await fetch(e);if(!n.ok)throw Error(`Failed to fetch model: ${n.status}`);let r=await n.arrayBuffer();return l(e,r.slice(0)),r}async function d(e,t){if(a&&o===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}a&&=(await a.release(),null);let[r,i]=await Promise.all([u(e),n()]);a=await i.InferenceSession.create(r,t),o=e;let s=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);s=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${s}`)}catch{}let c=(r.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${c}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:s})}async function f(e,t,r,i){let o=await n(),s=a.inputNames[0],c=a.outputNames[0],l=new o.Tensor(`float32`,e,[1,3,r,t]),u=(await a.run({[s]:l}))[c].data;self.postMessage({type:`inferred`,outputData:u,id:i},[u.buffer])}self.onmessage=async t=>{let{type:n}=t.data;try{n===`load`?(t.data.ortRuntimeUrl&&(e.ortRuntimeUrl=t.data.ortRuntimeUrl),t.data.ortWasmPaths&&(e.ortWasmPaths=t.data.ortWasmPaths),t.data.cacheNamespace&&(e.cacheNamespace=t.data.cacheNamespace),await d(t.data.url,t.data.sessionOptions)):n===`infer`?await f(t.data.tileData,t.data.width,t.data.height,t.data.id):n===`dispose`&&a&&(await a.release(),a=null,o=null)}catch(e){self.postMessage({type:`error`,message:e.message,id:t.data?.id})}};", fm = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", dm], { type: "text/javascript;charset=utf-8" });
16464
+ function pm(e) {
16474
16465
  let t;
16475
16466
  try {
16476
- if (t = um && (self.URL || self.webkitURL).createObjectURL(um), !t) throw "";
16467
+ if (t = fm && (self.URL || self.webkitURL).createObjectURL(fm), !t) throw "";
16477
16468
  let n = new Worker(t, {
16478
16469
  type: "module",
16479
16470
  name: e?.name
@@ -16482,7 +16473,7 @@ function dm(e) {
16482
16473
  (self.URL || self.webkitURL).revokeObjectURL(t);
16483
16474
  }), n;
16484
16475
  } catch {
16485
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(lm), {
16476
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(dm), {
16486
16477
  type: "module",
16487
16478
  name: e?.name
16488
16479
  });
@@ -16490,7 +16481,7 @@ function dm(e) {
16490
16481
  }
16491
16482
  //#endregion
16492
16483
  //#region src/Passes/AIUpscaler.js
16493
- var fm = {
16484
+ var mm = {
16494
16485
  fast: {
16495
16486
  2: "2x-spanx2-ch48.onnx",
16496
16487
  4: "4xNomos8k_span_otf_strong_fp32_opset17.onnx"
@@ -16504,17 +16495,17 @@ var fm = {
16504
16495
  4: "4xNomos2_hq_mosr_fp32.onnx"
16505
16496
  }
16506
16497
  };
16507
- function pm() {
16498
+ function hm() {
16508
16499
  let { upscalerModelBaseUrl: e } = cl(), t = {};
16509
- for (let n in fm) {
16500
+ for (let n in mm) {
16510
16501
  t[n] = {};
16511
- for (let r in fm[n]) t[n][r] = e + fm[n][r];
16502
+ for (let r in mm[n]) t[n][r] = e + mm[n][r];
16512
16503
  }
16513
16504
  return t;
16514
16505
  }
16515
- var mm = {
16506
+ var gm = {
16516
16507
  get QUALITY_PRESETS() {
16517
- return pm();
16508
+ return hm();
16518
16509
  },
16519
16510
  TILE_SIZE: 512,
16520
16511
  TILE_OVERLAP: 16,
@@ -16525,17 +16516,17 @@ var mm = {
16525
16516
  }],
16526
16517
  graphOptimizationLevel: "all"
16527
16518
  }
16528
- }, hm = class extends ut {
16519
+ }, _m = class extends ut {
16529
16520
  constructor(e, t, n = {}) {
16530
16521
  if (super(), !e || !t) throw Error("AIUpscaler requires output canvas and renderer");
16531
- this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => Ue), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.tileSize = n.tileSize || mm.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
16522
+ this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => Ue), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.tileSize = n.tileSize || gm.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
16532
16523
  isUpscaling: !1,
16533
16524
  isLoading: !1,
16534
16525
  abortController: null
16535
16526
  }, this._worker = null, this._currentModelUrl = null, this._tileId = 0, this._pendingWorkerHandlers = /* @__PURE__ */ new Set(), this._upscaledAlpha = null, this._upscaledAlphaWidth = 0, this._backupCanvas = null, this._baseWidth = e.width, this._baseHeight = e.height, this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0;
16536
16527
  }
16537
16528
  async _ensureSession() {
16538
- let e = mm.QUALITY_PRESETS[this.quality];
16529
+ let e = gm.QUALITY_PRESETS[this.quality];
16539
16530
  if (!e) throw Error(`Unknown quality preset: ${this.quality}`);
16540
16531
  let t = e[this.scaleFactor];
16541
16532
  if (!t) throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);
@@ -16545,14 +16536,14 @@ var mm = {
16545
16536
  message: `Loading ${this.scaleFactor}x upscale model...`
16546
16537
  });
16547
16538
  try {
16548
- this._worker ||= new dm(), await new Promise((e, n) => {
16539
+ this._worker ||= new pm(), await new Promise((e, n) => {
16549
16540
  let r = (t) => {
16550
16541
  t.data.type === "loaded" ? (this._worker.removeEventListener("message", r), t.data.tileSize && !this._tileSizeOverride && (this.tileSize = t.data.tileSize), console.log(`AI Upscaler: ${this.scaleFactor}x model loaded, backend: ${t.data.backend}, tileSize: ${this.tileSize}`), e()) : t.data.type === "error" && (this._worker.removeEventListener("message", r), n(Error(t.data.message)));
16551
16542
  }, { ortRuntimeUrl: i, ortWasmPaths: a, cacheNamespace: o } = cl();
16552
16543
  this._worker.addEventListener("message", r), this._worker.postMessage({
16553
16544
  type: "load",
16554
16545
  url: t,
16555
- sessionOptions: mm.SESSION_OPTIONS,
16546
+ sessionOptions: gm.SESSION_OPTIONS,
16556
16547
  ortRuntimeUrl: i,
16557
16548
  ortWasmPaths: a,
16558
16549
  cacheNamespace: o
@@ -16622,8 +16613,8 @@ var mm = {
16622
16613
  willReadFrequently: !0,
16623
16614
  alpha: !0
16624
16615
  });
16625
- this._cacheUpscaledAlpha(t, n * i, r * i), t.isHDR && (this._hdrToneMapFn = Jp.get(this.getToneMapping()) || Jp.get(Ue), this._hdrExposure = this.getExposure(), this._hdrSaturation = this.getSaturation(), this._tmOut = new Float32Array(3));
16626
- let o = mm.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
16616
+ this._cacheUpscaledAlpha(t, n * i, r * i), t.isHDR && (this._hdrToneMapFn = Xp.get(this.getToneMapping()) || Xp.get(Ue), this._hdrExposure = this.getExposure(), this._hdrSaturation = this.getSaturation(), this._tmOut = new Float32Array(3));
16617
+ let o = gm.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
16627
16618
  for (let o = 0; o < u; o++) for (let u = 0; u < l; u++) {
16628
16619
  if (e.aborted) throw new DOMException("Aborted", "AbortError");
16629
16620
  let l = Math.min(u * c, Math.max(0, n - s)), p = Math.min(o * c, Math.max(0, r - s)), m = Math.min(s, n - l), h = Math.min(s, r - p), g = this._extractTile(t, l, p, m, h), _ = await this._inferTile(g, m, h), v = l * i, y = p * i, b = m * i, x = h * i, S = this._tensorToImageData(_, b, x, v, y);
@@ -16696,7 +16687,7 @@ var mm = {
16696
16687
  let u = ((n + e) * o + (t + i)) * 4, d = e * r + i;
16697
16688
  if (s) {
16698
16689
  let e = this._hdrToneMapFn, t = this._hdrExposure, n = this._hdrSaturation, r = a[u] * t, i = a[u + 1] * t, o = a[u + 2] * t;
16699
- n !== 1 && (this._tmOut[0] = r, this._tmOut[1] = i, this._tmOut[2] = o, em(this._tmOut, n), r = this._tmOut[0], i = this._tmOut[1], o = this._tmOut[2]), e(r, i, o, 1, this._tmOut), l[d] = this._tmOut[0] ** +Yp, l[c + d] = this._tmOut[1] ** +Yp, l[2 * c + d] = this._tmOut[2] ** +Yp;
16690
+ n !== 1 && (this._tmOut[0] = r, this._tmOut[1] = i, this._tmOut[2] = o, nm(this._tmOut, n), r = this._tmOut[0], i = this._tmOut[1], o = this._tmOut[2]), e(r, i, o, 1, this._tmOut), l[d] = this._tmOut[0] ** +Zp, l[c + d] = this._tmOut[1] ** +Zp, l[2 * c + d] = this._tmOut[2] ** +Zp;
16700
16691
  } else l[d] = a[u] / 255, l[c + d] = a[u + 1] / 255, l[2 * c + d] = a[u + 2] / 255;
16701
16692
  }
16702
16693
  return l;
@@ -16754,10 +16745,10 @@ var mm = {
16754
16745
  this._backupCanvas = document.createElement("canvas"), this._backupCanvas.width = e.width, this._backupCanvas.height = e.height;
16755
16746
  let t = this._backupCanvas.getContext("2d");
16756
16747
  if (e.isHDR) {
16757
- let { data: n, width: r, height: i } = e, a = t.createImageData(r, i), o = a.data, s = Jp.get(this.getToneMapping()) || Jp.get(Ue), c = this.getExposure(), l = this.getSaturation(), u = new Float32Array(3);
16748
+ let { data: n, width: r, height: i } = e, a = t.createImageData(r, i), o = a.data, s = Xp.get(this.getToneMapping()) || Xp.get(Ue), c = this.getExposure(), l = this.getSaturation(), u = new Float32Array(3);
16758
16749
  for (let e = 0, t = r * i; e < t; e++) {
16759
16750
  let t = e * 4, r = n[t] * c, i = n[t + 1] * c, a = n[t + 2] * c;
16760
- l !== 1 && (u[0] = r, u[1] = i, u[2] = a, em(u, l), r = u[0], i = u[1], a = u[2]), s(r, i, a, 1, u), o[t] = u[0] ** +Yp * 255 + .5 | 0, o[t + 1] = u[1] ** +Yp * 255 + .5 | 0, o[t + 2] = u[2] ** +Yp * 255 + .5 | 0, o[t + 3] = 255;
16751
+ l !== 1 && (u[0] = r, u[1] = i, u[2] = a, nm(u, l), r = u[0], i = u[1], a = u[2]), s(r, i, a, 1, u), o[t] = u[0] ** +Zp * 255 + .5 | 0, o[t + 1] = u[1] ** +Zp * 255 + .5 | 0, o[t + 2] = u[2] ** +Zp * 255 + .5 | 0, o[t + 3] = 255;
16761
16752
  }
16762
16753
  t.putImageData(a, 0, 0);
16763
16754
  } else t.putImageData(e, 0, 0);
@@ -16769,7 +16760,7 @@ var mm = {
16769
16760
  this.hdr = !!e;
16770
16761
  }
16771
16762
  setQuality(e) {
16772
- if (!mm.QUALITY_PRESETS[e]) {
16763
+ if (!gm.QUALITY_PRESETS[e]) {
16773
16764
  console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);
16774
16765
  return;
16775
16766
  }
@@ -16792,7 +16783,7 @@ var mm = {
16792
16783
  async dispose() {
16793
16784
  this.abort(), this._cleanupPendingWorkerHandlers(), this._worker &&= (this._worker.postMessage({ type: "dispose" }), this._worker.terminate(), null), this._currentModelUrl = null, this._backupCanvas = null, this._upscaledAlpha = null, this.state.abortController = null, this._hdrStagingBuffer?.destroy(), this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0, console.log("AIUpscaler disposed");
16794
16785
  }
16795
- }, gm = class extends ut {
16786
+ }, vm = class extends ut {
16796
16787
  constructor({ renderer: e, mainCanvas: t, scene: n, camera: r, stages: i, pipeline: a, getExposure: o, getSaturation: s, getTransparentBg: c }) {
16797
16788
  super(), this.renderer = e, this.mainCanvas = t, this.denoiserCanvas = this._createDenoiserCanvas(t), this.scene = n, this.camera = r, this.pipeline = a, this._stages = i, this._getExposure = o, this._getSaturation = s, this._getTransparentBg = c, this.denoiser = null, this.upscaler = null, this._lastRenderWidth = 0, this._lastRenderHeight = 0, this._pendingStartUpscaler = null, this._denoiserStartHandler = null, this._denoiserEndHandler = null, this._upscalerResChangedHandler = null, this._upscalerStartHandler = null, this._upscalerProgressHandler = null, this._upscalerEndHandler = null;
16798
16789
  }
@@ -16813,7 +16804,7 @@ var mm = {
16813
16804
  setupDenoiser() {
16814
16805
  if (!this.denoiserCanvas) return;
16815
16806
  let e = this._stages.pathTracer;
16816
- this.denoiser = new cm(this.denoiserCanvas, this.renderer, this.scene, this.camera, {
16807
+ this.denoiser = new um(this.denoiserCanvas, this.renderer, this.scene, this.camera, {
16817
16808
  ...J,
16818
16809
  backendParams: () => ({
16819
16810
  device: this.renderer.backend.device,
@@ -16838,7 +16829,7 @@ var mm = {
16838
16829
  setupUpscaler() {
16839
16830
  if (!this.denoiserCanvas) return;
16840
16831
  let e = this._stages.pathTracer;
16841
- this.upscaler = new hm(this.denoiserCanvas, this.renderer, {
16832
+ this.upscaler = new _m(this.denoiserCanvas, this.renderer, {
16842
16833
  scaleFactor: J.upscalerScale || 2,
16843
16834
  quality: J.upscalerQuality || "fast",
16844
16835
  getSourceCanvas: () => this.denoiser?.enabled ? null : this.renderer.domElement,
@@ -16859,6 +16850,9 @@ var mm = {
16859
16850
  progress: e.progress
16860
16851
  }), this._upscalerEndHandler = () => this.dispatchEvent({ type: dr.UPSCALING_END }), this.upscaler.addEventListener("resolution_changed", this._upscalerResChangedHandler), this.upscaler.addEventListener("start", this._upscalerStartHandler), this.upscaler.addEventListener("progress", this._upscalerProgressHandler), this.upscaler.addEventListener("end", this._upscalerEndHandler);
16861
16852
  }
16853
+ get denoiserStrategy() {
16854
+ return this._stages.asvgf?.enabled ? "asvgf" : this._stages.edgeFilter?.enabled ? "edgeaware" : "none";
16855
+ }
16862
16856
  setDenoiserStrategy(e, t) {
16863
16857
  let n = this._stages;
16864
16858
  switch (n.asvgf && (n.asvgf.enabled = !1), n.variance && (n.variance.enabled = !1), n.bilateralFilter && (n.bilateralFilter.enabled = !1), n.edgeFilter && n.edgeFilter.setFilteringEnabled(!1), this._clearDenoiserTextures(), e) {
@@ -16983,7 +16977,7 @@ var mm = {
16983
16977
  let t = kr[e];
16984
16978
  t && (this._stages.asvgf?.updateParameters(t), this._stages.bilateralFilter?.updateParameters(t), this._stages.variance && t.varianceBoost !== void 0 && (this._stages.variance.varianceBoost.value = t.varianceBoost));
16985
16979
  }
16986
- }, _m = class {
16980
+ }, ym = class {
16987
16981
  constructor() {
16988
16982
  this.layer = "hud", this.visible = !1, this._tileBounds = null, this._imageWidth = 1, this._imageHeight = 1, this.enabled = !0, this._borderColor = "rgba(255, 0, 0, 0.6)", this._borderWidthRatio = 1 / 540, this._borderWidthMin = 1.5, this._borderWidthMax = 4;
16989
16983
  }
@@ -17007,7 +17001,7 @@ var mm = {
17007
17001
  dispose() {
17008
17002
  this.visible = !1;
17009
17003
  }
17010
- }, vm = class {
17004
+ }, bm = class {
17011
17005
  constructor(n, r) {
17012
17006
  this.layer = "scene", this._enabled = !0, this._outlineNode = xn(n, r, {
17013
17007
  selectedObjects: [],
@@ -17038,11 +17032,11 @@ var mm = {
17038
17032
  this._enabled = !1, this._outlineNode?.dispose(), this._material?.dispose(), this._quad = null;
17039
17033
  }
17040
17034
  };
17041
- function ym(e = !1) {
17035
+ function xm(e = !1) {
17042
17036
  let t = document.createElement("canvas");
17043
17037
  return t.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" + (e ? "display:none;" : ""), t;
17044
17038
  }
17045
- function bm(e, t = Infinity) {
17039
+ function Sm(e, t = Infinity) {
17046
17040
  let n = e?.getBoundingClientRect();
17047
17041
  if (!n || n.width === 0 || n.height === 0) return null;
17048
17042
  let r = Math.min(window.devicePixelRatio || 1, 2), i = Math.round(n.width * r), a = Math.round(n.height * r), o = t / Math.max(i, a);
@@ -17053,9 +17047,9 @@ function bm(e, t = Infinity) {
17053
17047
  }
17054
17048
  //#endregion
17055
17049
  //#region src/managers/helpers/ViewOverlayRenderer.js
17056
- var xm = 4096, Sm = class {
17050
+ var Cm = 4096, wm = class {
17057
17051
  constructor() {
17058
- this.canvas = ym(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
17052
+ this.canvas = xm(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
17059
17053
  }
17060
17054
  async init({ device: e, sizeSource: t }) {
17061
17055
  this._sizeSource = t;
@@ -17072,7 +17066,7 @@ var xm = 4096, Sm = class {
17072
17066
  }
17073
17067
  syncSize() {
17074
17068
  if (!this.renderer) return;
17075
- let e = bm(this._sizeSource, xm);
17069
+ let e = Sm(this._sizeSource, Cm);
17076
17070
  !e || e.width === this.canvas.width && e.height === this.canvas.height || this.renderer.setSize(e.width, e.height, !1);
17077
17071
  }
17078
17072
  begin() {
@@ -17084,18 +17078,18 @@ var xm = 4096, Sm = class {
17084
17078
  dispose() {
17085
17079
  xr(this.renderer), this.renderer = null, this.canvas.parentElement?.removeChild(this.canvas);
17086
17080
  }
17087
- }, Cm = ai("overlay"), wm = (e, t) => e.visible && e.layer === t && e.render, Tm = class {
17081
+ }, Tm = ai("overlay"), Em = (e, t) => e.visible && e.layer === t && e.render, Dm = class {
17088
17082
  constructor(e) {
17089
- this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = ym(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
17083
+ this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = xm(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
17090
17084
  }
17091
17085
  async initViewRenderer({ device: e, sizeSource: t }) {
17092
17086
  if (!(!e || !t)) try {
17093
- this._viewOverlay = await new Sm().init({
17087
+ this._viewOverlay = await new wm().init({
17094
17088
  device: e,
17095
17089
  sizeSource: t
17096
17090
  });
17097
17091
  } catch (e) {
17098
- Cm.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
17092
+ Tm.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
17099
17093
  }
17100
17094
  }
17101
17095
  setHelperScene(e) {
@@ -17111,11 +17105,11 @@ var xm = 4096, Sm = class {
17111
17105
  }
17112
17106
  setupDefaultHelpers({ helperScene: e, meshScene: t, pipeline: n, denoisingManager: r, app: i, renderWidth: a, renderHeight: o }) {
17113
17107
  this.setHelperScene(e);
17114
- let s = new _m();
17108
+ let s = new ym();
17115
17109
  this.register("tiles", s), s.setRenderSize(a || 1, o || 1), i.addEventListener("resolution_changed", (e) => {
17116
17110
  s.setRenderSize(e.width, e.height);
17117
17111
  }), n.eventBus.on("pipeline:reset", () => s.hide()), this._wireDenoiserTileEvents(s, r);
17118
- let c = new vm(t, this.camera);
17112
+ let c = new bm(t, this.camera);
17119
17113
  this.register("outline", c);
17120
17114
  }
17121
17115
  _wireDenoiserTileEvents(e, t) {
@@ -17127,7 +17121,7 @@ var xm = 4096, Sm = class {
17127
17121
  }));
17128
17122
  }
17129
17123
  register(e, t) {
17130
- this._helpers.has(e) && (Cm.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
17124
+ this._helpers.has(e) && (Tm.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
17131
17125
  }
17132
17126
  unregister(e) {
17133
17127
  let t = this._helpers.get(e);
@@ -17165,16 +17159,16 @@ var xm = 4096, Sm = class {
17165
17159
  }
17166
17160
  _renderSceneLayer(e) {
17167
17161
  this._helperScene?.render(e, this.camera);
17168
- for (let t of this._helpers.values()) wm(t, "scene") && t.render(e, this.camera);
17162
+ for (let t of this._helpers.values()) Em(t, "scene") && t.render(e, this.camera);
17169
17163
  }
17170
17164
  _hasVisibleSceneOverlay() {
17171
17165
  if (this._helperScene?.isDrawing) return !0;
17172
- for (let e of this._helpers.values()) if (wm(e, "scene")) return !0;
17166
+ for (let e of this._helpers.values()) if (Em(e, "scene")) return !0;
17173
17167
  return !1;
17174
17168
  }
17175
17169
  refreshHUD() {
17176
17170
  let e = this._hudCanvas, t = this._hudCtx, n = !1;
17177
- for (let e of this._helpers.values()) if (wm(e, "hud")) {
17171
+ for (let e of this._helpers.values()) if (Em(e, "hud")) {
17178
17172
  n = !0;
17179
17173
  break;
17180
17174
  }
@@ -17183,10 +17177,10 @@ var xm = 4096, Sm = class {
17183
17177
  return;
17184
17178
  }
17185
17179
  e.style.display !== "" && (e.style.display = "");
17186
- let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? bm(e) : null;
17180
+ let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? Sm(e) : null;
17187
17181
  if (a) {
17188
17182
  (e.width !== a.width || e.height !== a.height) && (e.width = a.width, e.height = a.height), t.clearRect(0, 0, a.width, a.height), t.save(), t.scale(a.width / r, a.height / i);
17189
- for (let e of this._helpers.values()) wm(e, "hud") && e.render(t, r, i);
17183
+ for (let e of this._helpers.values()) Em(e, "hud") && e.render(t, r, i);
17190
17184
  t.restore(), e.style.display !== "" && (e.style.display = "");
17191
17185
  }
17192
17186
  }
@@ -17194,7 +17188,7 @@ var xm = 4096, Sm = class {
17194
17188
  for (let e of this._helpers.values()) e.dispose?.();
17195
17189
  this._helpers.clear(), this._viewOverlay?.dispose(), this._viewOverlay = null, this._hudCanvas.parentElement && this._hudCanvas.parentElement.removeChild(this._hudCanvas);
17196
17190
  }
17197
- }, Em = class extends ut {
17191
+ }, Om = class extends ut {
17198
17192
  constructor() {
17199
17193
  super(), this.mixer = null, this.timer = new nn(), this.actions = [], this.isPlaying = !1, this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._tempVec = new cn(), this._skinnedCache = null, this._clipsCache = null, this._savedTimeScale = 1, this.onFinished = null, this.wakeCallback = null;
17200
17194
  }
@@ -17294,7 +17288,7 @@ var xm = 4096, Sm = class {
17294
17288
  dispose() {
17295
17289
  this.mixer &&= (this.mixer.stopAllAction(), this.mixer.uncacheRoot(this._mixerRoot), null), this.actions = [], this.isPlaying = !1, this.timer.reset(), this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._skinnedCache = null, this._clipsCache = null;
17296
17290
  }
17297
- }, Dm = new cn(0, 0, -1), Om = class {
17291
+ }, km = new cn(0, 0, -1), Am = class {
17298
17292
  constructor({ camera: e, canvas: t, orbitControls: n, app: r }) {
17299
17293
  this._app = r, this._orbitControls = n, this._camera = e, this._controls = new Sn(e, t), this._gizmoScene = new Yt(), this._gizmoScene.add(this._controls.getHelper()), this._attached = null, this._isDragging = !1, this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._normalBuffer = null, this._skinnedCache = null, this._normalCache = null, this._tempVec = new cn(), this._normalMatrix = new St(), this._refitInFlight = !1, this._baselineComputed = !1, this._tempForward = new cn(), this._lightTargetDistance = null, this._lastLightPosition = null, this._onDraggingChanged = this._onDraggingChanged.bind(this), this._onObjectChange = this._onObjectChange.bind(this), this._controls.addEventListener("dragging-changed", this._onDraggingChanged), this._controls.addEventListener("objectChange", this._onObjectChange);
17300
17294
  }
@@ -17315,7 +17309,7 @@ var xm = 4096, Sm = class {
17315
17309
  attach(e) {
17316
17310
  if (this._attached !== e && (this._controls.attach(e), this._attached = e, this._lightTargetDistance = null, this._lastLightPosition = null, e.isLight && e.target)) {
17317
17311
  let t = e.target.position.clone().sub(e.position), n = t.length();
17318
- n > 1e-4 ? (e.quaternion.setFromUnitVectors(Dm, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1, this._lastLightPosition = e.position.clone();
17312
+ n > 1e-4 ? (e.quaternion.setFromUnitVectors(km, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1, this._lastLightPosition = e.position.clone();
17319
17313
  }
17320
17314
  }
17321
17315
  detach() {
@@ -17427,7 +17421,7 @@ var xm = 4096, Sm = class {
17427
17421
  dispose() {
17428
17422
  this._controls.removeEventListener("dragging-changed", this._onDraggingChanged), this._controls.removeEventListener("objectChange", this._onObjectChange), this.detach(), this._gizmoScene.remove(this._controls.getHelper()), this._controls.dispose(), this._meshes = null, this._meshTriRanges = null, this._posBuffer = null, this._normalBuffer = null, this._skinnedCache = null, this._normalCache = null, this._baselineComputed = !1, this._tempForward = null, this._lightTargetDistance = null, this._lastLightPosition = null, this._app = null, this._orbitControls = null, this._camera = null, this._controls = null, this._gizmoScene = null;
17429
17423
  }
17430
- }, km = class {
17424
+ }, jm = class {
17431
17425
  constructor(e) {
17432
17426
  this.layer = "scene", this._transformManager = e, this._enabled = !0;
17433
17427
  }
@@ -17446,15 +17440,15 @@ var xm = 4096, Sm = class {
17446
17440
  dispose() {
17447
17441
  this._enabled = !1;
17448
17442
  }
17449
- }, Am = /* @__PURE__ */ new WeakMap(), jm = ai("engine"), Mm = class extends ut {
17443
+ }, Mm = /* @__PURE__ */ new WeakMap(), Nm = ai("engine"), Pm = class extends ut {
17450
17444
  constructor(e, t = {}) {
17451
17445
  super();
17452
17446
  try {
17453
- Am.get(e)?.dispose();
17447
+ Mm.get(e)?.dispose();
17454
17448
  } catch (e) {
17455
- jm.warn("prior canvas owner dispose failed", e);
17449
+ Nm.warn("prior canvas owner dispose failed", e);
17456
17450
  }
17457
- Am.set(e, this), this.canvas = e, this._autoResize = t.autoResize !== !1, this._container = t.container || null, this.settings = new wp(J), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._maxTextureSize = J.maxTextureSize, this.pipeline = null, this.stages = {}, this.cameraManager = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new Em(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this.pathTracerEnabled = !0, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new zf(), this._resizeDebounceTimer = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null;
17451
+ Mm.set(e, this), this.canvas = e, this._autoResize = t.autoResize !== !1, this._container = t.container || null, this.settings = new Ep(J), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._maxTextureSize = J.maxTextureSize, this.pipeline = null, this.stages = {}, this.cameraManager = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new Om(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this.pathTracerEnabled = !0, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new Vf(), this._resizeDebounceTimer = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null;
17458
17452
  }
17459
17453
  _addTrackedListener(e, t, n) {
17460
17454
  e && (e.addEventListener(t, n), this._trackedListeners.push({
@@ -17467,12 +17461,12 @@ var xm = 4096, Sm = class {
17467
17461
  for (let { target: e, type: t, handler: n } of this._trackedListeners) try {
17468
17462
  e.removeEventListener(t, n);
17469
17463
  } catch (e) {
17470
- jm.warn("failed to remove listener", t, e);
17464
+ Nm.warn("failed to remove listener", t, e);
17471
17465
  }
17472
17466
  this._trackedListeners.length = 0;
17473
17467
  }
17474
17468
  async init() {
17475
- return await this._initRenderer(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), this.stages.pathTracer.setTriangleData(new Float32Array(32), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, jm.debug("WebGPU path tracer app initialized"), this;
17469
+ return await this._initRenderer(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), this.stages.pathTracer.setTriangleData(new Float32Array(32), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, Nm.debug("WebGPU path tracer app initialized"), this;
17476
17470
  }
17477
17471
  animate() {
17478
17472
  if (!this._deviceLost) {
@@ -17482,7 +17476,7 @@ var xm = 4096, Sm = class {
17482
17476
  }
17483
17477
  if (this.cameraManager.controls && this.cameraManager.controls.update(), this.animationManager?.isPlaying && !this._animRefitInFlight) {
17484
17478
  let e = this.animationManager.update();
17485
- e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => jm.error("animation refit error:", e)).finally(() => {
17479
+ e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => Nm.error("animation refit error:", e)).finally(() => {
17486
17480
  this._animRefitInFlight = !1;
17487
17481
  }));
17488
17482
  }
@@ -17516,7 +17510,7 @@ var xm = 4096, Sm = class {
17516
17510
  this.animationManagerId &&= (cancelAnimationFrame(this.animationManagerId), null);
17517
17511
  }
17518
17512
  _handleDeviceLost(e) {
17519
- this._deviceLost || (this._deviceLost = !0, jm.error(`WebGPU device lost (${e?.reason || "unknown"}): ${e?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
17513
+ this._deviceLost || (this._deviceLost = !0, Nm.error(`WebGPU device lost (${e?.reason || "unknown"}): ${e?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
17520
17514
  type: dr.DEVICE_LOST,
17521
17515
  reason: e?.reason,
17522
17516
  message: e?.message
@@ -17554,7 +17548,7 @@ var xm = 4096, Sm = class {
17554
17548
  let e = je().value, t = k().value;
17555
17549
  e?._listeners?.dispose && (e._listeners.dispose.length = 0), t?._listeners?.dispose && (t._listeners.dispose.length = 0);
17556
17550
  } catch (e) {
17557
- jm.warn("failed to clear TSL texture singleton listeners", e);
17551
+ Nm.warn("failed to clear TSL texture singleton listeners", e);
17558
17552
  }
17559
17553
  xr(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
17560
17554
  }
@@ -17640,7 +17634,7 @@ var xm = 4096, Sm = class {
17640
17634
  try {
17641
17635
  await this.renderer.compileAsync(this.meshScene, this.cameraManager.camera);
17642
17636
  } catch (e) {
17643
- jm.warn("raster fallback precompile failed", e);
17637
+ Nm.warn("raster fallback precompile failed", e);
17644
17638
  }
17645
17639
  e.end("Pipeline precompile"), n && (hr({
17646
17640
  status: "Finalizing environment map...",
@@ -17778,7 +17772,7 @@ var xm = 4096, Sm = class {
17778
17772
  return Y;
17779
17773
  }
17780
17774
  _isRenderSizeSupported(e, t) {
17781
- return e > Y || t > Y ? (jm.warn(`render resolution ${e}×${t} exceeds the ${Y}px limit (compute storage textures are pre-allocated at ${Y}px). Ignoring resize — use a resolution ≤ ${Y}.`), !1) : !0;
17775
+ return e > Y || t > Y ? (Nm.warn(`render resolution ${e}×${t} exceeds the ${Y}px limit (compute storage textures are pre-allocated at ${Y}px). Ignoring resize — use a resolution ≤ ${Y}.`), !1) : !0;
17782
17776
  }
17783
17777
  onResize() {
17784
17778
  let e = this.canvas.clientWidth, t = this.canvas.clientHeight;
@@ -17890,6 +17884,39 @@ var xm = 4096, Sm = class {
17890
17884
  total: t + n
17891
17885
  };
17892
17886
  }
17887
+ async getKernelGPUTimings() {
17888
+ let e = this.renderer;
17889
+ if (!e?.backend?.trackTimestamp) return null;
17890
+ await e.resolveTimestampsAsync("compute");
17891
+ let t = e.backend.timestampQueryPool?.compute?.timestamps;
17892
+ if (!t || t.size === 0) return null;
17893
+ let n = /* @__PURE__ */ new Map(), r = this.stages?.pathTracer?._kernelManager?.kernels;
17894
+ if (r) for (let [e, t] of r) n.set(t.id, e);
17895
+ let i = [], a = -1;
17896
+ for (let [e, n] of t) {
17897
+ let t = e.split(":");
17898
+ if (t.length !== 4) continue;
17899
+ let r = Number(t[3].slice(1));
17900
+ Number.isFinite(r) && (i.push({
17901
+ nodeId: Number(t[2]),
17902
+ f: r,
17903
+ ms: n
17904
+ }), r > a && (a = r));
17905
+ }
17906
+ let o = {}, s = 0, c = 0;
17907
+ for (let e of i) {
17908
+ if (e.f !== a) continue;
17909
+ s += e.ms;
17910
+ let t = n.get(e.nodeId);
17911
+ t === void 0 ? c += e.ms : o[t] = (o[t] ?? 0) + e.ms;
17912
+ }
17913
+ return {
17914
+ kernels: o,
17915
+ total: s,
17916
+ unattributed: c,
17917
+ frame: a
17918
+ };
17919
+ }
17893
17920
  getCanvas() {
17894
17921
  if (!this.renderer?.domElement) return null;
17895
17922
  let e = this.denoisingManager;
@@ -18008,40 +18035,40 @@ var xm = 4096, Sm = class {
18008
18035
  let n = this.renderer.backend?.device;
18009
18036
  n?.lost && (n.lost.then((e) => {
18010
18037
  this._disposed || this._handleDeviceLost(e);
18011
- }), n.onuncapturederror = (e) => jm.error("WebGPU uncaptured error:", e.error)), r.setLTC(ln.init()), this.renderer.outputColorSpace = a, this.renderer.toneMapping = Ue, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1);
18038
+ }), n.onuncapturederror = (e) => Nm.error("WebGPU uncaptured error:", e.error)), r.setLTC(ln.init()), this.renderer.outputColorSpace = a, this.renderer.toneMapping = Ue, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1);
18012
18039
  }
18013
18040
  _initCameraManager() {
18014
- this.cameraManager = new Tp(this.canvas);
18041
+ this.cameraManager = new Dp(this.canvas);
18015
18042
  }
18016
18043
  _initScenes() {
18017
18044
  this.scene = new Yt(), this.meshScene = new Yt(), this._sceneHelpers = new Pn();
18018
18045
  }
18019
18046
  _initAssetPipeline() {
18020
- this._sdf = new Qc(), this.assetLoader = new xp(this.meshScene, this.cameraManager.camera, this.cameraManager.controls), this.assetLoader.setRenderer(this.renderer), this.assetLoader.createFloorPlane(), this._addTrackedListener(this.cameraManager.controls, "change", () => {
18047
+ this._sdf = new Qc(), this.assetLoader = new Cp(this.meshScene, this.cameraManager.camera, this.cameraManager.controls), this.assetLoader.setRenderer(this.renderer), this.assetLoader.createFloorPlane(), this._addTrackedListener(this.cameraManager.controls, "change", () => {
18021
18048
  this.needsReset = !0, this.wake();
18022
18049
  });
18023
18050
  }
18024
18051
  _initPipeline() {
18025
18052
  this._createStages();
18026
18053
  let { clientWidth: e, clientHeight: t } = this.canvas;
18027
- this.pipeline = new Rf(this.renderer, e || 1, t || 1), this.pipeline.addStage(this.stages.pathTracer), this.pipeline.addStage(this.stages.normalDepth), this.pipeline.addStage(this.stages.motionVector), this.pipeline.addStage(this.stages.asvgf), this.pipeline.addStage(this.stages.variance), this.pipeline.addStage(this.stages.bilateralFilter), this.pipeline.addStage(this.stages.edgeFilter), this.pipeline.addStage(this.stages.autoExposure), this.pipeline.addStage(this.stages.compositor);
18054
+ this.pipeline = new Bf(this.renderer, e || 1, t || 1), this.pipeline.addStage(this.stages.pathTracer), this.pipeline.addStage(this.stages.normalDepth), this.pipeline.addStage(this.stages.motionVector), this.pipeline.addStage(this.stages.asvgf), this.pipeline.addStage(this.stages.variance), this.pipeline.addStage(this.stages.bilateralFilter), this.pipeline.addStage(this.stages.edgeFilter), this.pipeline.addStage(this.stages.autoExposure), this.pipeline.addStage(this.stages.compositor);
18028
18055
  let n = this.canvas.clientWidth || 1, r = this.canvas.clientHeight || 1;
18029
18056
  this.pipeline.setSize(n, r);
18030
18057
  }
18031
18058
  async _initManagers() {
18032
- this.interactionManager = new Bf({
18059
+ this.interactionManager = new Hf({
18033
18060
  scene: this.meshScene,
18034
18061
  camera: this.cameraManager.camera,
18035
18062
  canvas: this.canvas,
18036
18063
  assetLoader: this.assetLoader,
18037
18064
  pathTracer: null,
18038
18065
  floorPlane: this.assetLoader.floorPlane
18039
- }), this.interactionManager.wireAppEvents(this), this.cameraManager.setInteractionManager(this.interactionManager), this.lightManager = new Ep(this.scene, this._sceneHelpers, this.stages.pathTracer, { onReset: () => this.reset() }), this.goboManager = new Dp(this.stages.pathTracer, { onReset: () => this.reset() }), this.iesManager = new Rp(this.stages.pathTracer, { onReset: () => this.reset() }), this._setupDenoisingManager(), await this._setupOverlayManager(), this.transformManager = new Om({
18066
+ }), this.interactionManager.wireAppEvents(this), this.cameraManager.setInteractionManager(this.interactionManager), this.lightManager = new Op(this.scene, this._sceneHelpers, this.stages.pathTracer, { onReset: () => this.reset() }), this.goboManager = new kp(this.stages.pathTracer, { onReset: () => this.reset() }), this.iesManager = new Bp(this.stages.pathTracer, { onReset: () => this.reset() }), this._setupDenoisingManager(), await this._setupOverlayManager(), this.transformManager = new Am({
18040
18067
  camera: this.cameraManager.camera,
18041
18068
  canvas: this.canvas,
18042
18069
  orbitControls: this.cameraManager.controls,
18043
18070
  app: this
18044
- }), this.overlayManager.register("transform", new km(this.transformManager)), this.interactionManager.setDependencies({
18071
+ }), this.overlayManager.register("transform", new jm(this.transformManager)), this.interactionManager.setDependencies({
18045
18072
  overlayManager: this.overlayManager,
18046
18073
  transformManager: this.transformManager,
18047
18074
  appDispatch: (e) => this.dispatchEvent(e),
@@ -18085,7 +18112,9 @@ var xm = 4096, Sm = class {
18085
18112
  stages: this.stages,
18086
18113
  renderer: this.renderer,
18087
18114
  resetCallback: () => this.reset(),
18088
- reconcileCompletion: () => this._reconcileCompletion()
18115
+ reconcileCompletion: () => this._reconcileCompletion(),
18116
+ denoisingManager: this.denoisingManager,
18117
+ cameraManager: this.cameraManager
18089
18118
  }), this.renderer.toneMappingExposure = this.settings.get("exposure") ?? 1, this.onResize(), this.resizeHandler = () => this.onResize(), this._autoResize && this._addTrackedListener(window, "resize", this.resizeHandler), this._onAssetLoaded = async (e) => {
18090
18119
  if (!this._loadingInProgress) {
18091
18120
  if (e.model) this._clearAppendedModels(), await this.loadSceneData();
@@ -18111,10 +18140,10 @@ var xm = 4096, Sm = class {
18111
18140
  this.transformManager?.setMeshData(this._sdf.meshes);
18112
18141
  }
18113
18142
  _createStages() {
18114
- this.stages.pathTracer = new tf(this.renderer, this.scene, this.cameraManager.camera), this.stages.normalDepth = new nf(this.renderer, { pathTracer: this.stages.pathTracer }), this.stages.motionVector = new rf(this.renderer, this.cameraManager.camera, { pathTracer: this.stages.pathTracer }), this.stages.asvgf = new sf(this.renderer, { enabled: !1 }), this.stages.variance = new uf(this.renderer, { enabled: !1 }), this.stages.bilateralFilter = new ff(this.renderer, { enabled: !1 }), this.stages.edgeFilter = new _f(this.renderer, { enabled: !1 }), this.stages.autoExposure = new wf(this.renderer, { enabled: J.autoExposure ?? !1 }), this.stages.compositor = new Tf(this.renderer, { saturation: this.settings.get("saturation") ?? J.saturation });
18143
+ this.stages.pathTracer = new rf(this.renderer, this.scene, this.cameraManager.camera), this.stages.normalDepth = new af(this.renderer, { pathTracer: this.stages.pathTracer }), this.stages.motionVector = new of(this.renderer, this.cameraManager.camera, { pathTracer: this.stages.pathTracer }), this.stages.asvgf = new lf(this.renderer, { enabled: !1 }), this.stages.variance = new ff(this.renderer, { enabled: !1 }), this.stages.bilateralFilter = new mf(this.renderer, { enabled: !1 }), this.stages.edgeFilter = new yf(this.renderer, { enabled: !1 }), this.stages.autoExposure = new Ef(this.renderer, { enabled: J.autoExposure ?? !1 }), this.stages.compositor = new Df(this.renderer, { saturation: this.settings.get("saturation") ?? J.saturation });
18115
18144
  }
18116
18145
  _setupDenoisingManager() {
18117
- this.denoisingManager = new gm({
18146
+ this.denoisingManager = new vm({
18118
18147
  renderer: this.renderer,
18119
18148
  mainCanvas: this.canvas,
18120
18149
  scene: this.scene,
@@ -18157,7 +18186,7 @@ var xm = 4096, Sm = class {
18157
18186
  this.scene.updateMatrixWorld(), this.overlayManager?.render();
18158
18187
  }
18159
18188
  async _setupOverlayManager() {
18160
- this.overlayManager = new Tm(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
18189
+ this.overlayManager = new Dm(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
18161
18190
  helperScene: this._sceneHelpers,
18162
18191
  meshScene: this.meshScene,
18163
18192
  pipeline: this.pipeline,
@@ -18188,7 +18217,7 @@ var xm = 4096, Sm = class {
18188
18217
  _forwardEvents(e, t) {
18189
18218
  if (e) for (let n of t) this._addTrackedListener(e, n, (e) => this.dispatchEvent(e));
18190
18219
  }
18191
- }, Nm = class {
18220
+ }, Fm = class {
18192
18221
  constructor(e) {
18193
18222
  this._app = e, this._cancelled = !1, this._rendering = !1;
18194
18223
  }
@@ -18286,4 +18315,4 @@ var xm = 4096, Sm = class {
18286
18315
  }
18287
18316
  };
18288
18317
  //#endregion
18289
- export { Pr as AF_DEFAULTS, kr as ASVGF_QUALITY_PRESETS, Nr as AUTO_FOCUS_MODES, Em as AnimationManager, Fr as BVH_LEAF_MARKERS, Mr as CAMERA_PRESETS, Ar as CAMERA_RANGES, Tp as CameraManager, Br as DEFAULT_TEXTURE_MATRIX, gm as DenoisingManager, J as ENGINE_DEFAULTS, dr as EngineEvents, Dp as GoboManager, Rp as IESManager, Hr as INTERACTIVE_RENDER_CONFIG, Bf as InteractionManager, Wr as LOG_LEVELS, Ep as LightManager, ii as Logger, Ur as MEMORY_CONSTANTS, Tm as OverlayManager, Vr as PRODUCTION_RENDER_CONFIG, Mm as PathTracerApp, Ef as PipelineContext, Rf as RenderPipeline, wp as RenderSettings, lr as RenderStage, jr as SKY_PRESETS, cr as StageExecutionMode, Ir as TEXTURE_CONSTANTS, X as TRIANGLE_DATA_LAYOUT, Om as TransformManager, uu as VRAMTracker, Nm as VideoRenderManager, cu as bufferBytes, Nf as clearBindingAuditFindings, sl as configureAssets, ai as createLogger, Q as fmt, cl as getAssetConfig, Mf as getBindingAuditFindings, jf as setBindingAudit, lu as textureBytes };
18318
+ export { Pr as AF_DEFAULTS, kr as ASVGF_QUALITY_PRESETS, Nr as AUTO_FOCUS_MODES, Om as AnimationManager, Fr as BVH_LEAF_MARKERS, Mr as CAMERA_PRESETS, Ar as CAMERA_RANGES, Dp as CameraManager, Br as DEFAULT_TEXTURE_MATRIX, vm as DenoisingManager, J as ENGINE_DEFAULTS, dr as EngineEvents, kp as GoboManager, Bp as IESManager, Hr as INTERACTIVE_RENDER_CONFIG, Hf as InteractionManager, Wr as LOG_LEVELS, Op as LightManager, ii as Logger, Ur as MEMORY_CONSTANTS, Dm as OverlayManager, Vr as PRODUCTION_RENDER_CONFIG, Pm as PathTracerApp, Of as PipelineContext, Bf as RenderPipeline, Ep as RenderSettings, lr as RenderStage, jr as SKY_PRESETS, cr as StageExecutionMode, Ir as TEXTURE_CONSTANTS, X as TRIANGLE_DATA_LAYOUT, Am as TransformManager, uu as VRAMTracker, Fm as VideoRenderManager, cu as bufferBytes, Ff as clearBindingAuditFindings, sl as configureAssets, ai as createLogger, Q as fmt, cl as getAssetConfig, Pf as getBindingAuditFindings, Nf as setBindingAudit, lu as textureBytes };