rayzee 11.16.0 → 11.16.1

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.
@@ -1219,7 +1219,7 @@ var Ze = class {
1219
1219
  samples: this.samples.slice()
1220
1220
  };
1221
1221
  }
1222
- }, Qe = "11.16.0", $e = [
1222
+ }, Qe = "11.16.1", $e = [
1223
1223
  [/\.jpe?g(\?|#|$)/i, "image/jpeg"],
1224
1224
  [/\.webp(\?|#|$)/i, "image/webp"],
1225
1225
  [/\.avif(\?|#|$)/i, "image/avif"]
@@ -1,6 +1,6 @@
1
1
  import { n as e } from "./BidirectionalIntegrator-KWRQrMXX.js";
2
2
  import { n as t, r as n, t as r } from "./EngineIssues-DHAU18xh.js";
3
- import { I as i, M as a, N as o, O as s, T as c, c as l, i as u, t as d, u as f, z as p } from "./ArchiveFormats-CWi6IbSp.js";
3
+ import { I as i, M as a, N as o, O as s, T as c, c as l, i as u, t as d, u as f, z as p } from "./ArchiveFormats-_1o7EfSy.js";
4
4
  import { f as m, i as h, n as g, o as _, r as v, s as y } from "./FileIdentity-BXmPNvJP.js";
5
5
  import { a as b } from "./EngineEvents-oQGofgRf.js";
6
6
  import { n as x, t as S } from "./ZipReader-D6LbMsfZ.js";
@@ -269,7 +269,7 @@ function Je(e, t, n) {
269
269
  return `${e}\u0000${t}\u0000${n ? JSON.stringify(n) : ""}`;
270
270
  }
271
271
  function Ye() {
272
- for (let e of Ke.values()) e.dispose?.();
272
+ for (let e of Ke.values()) e?.dispose?.();
273
273
  Ke.clear(), W.clear(), G.clear();
274
274
  }
275
275
  function Xe(e, t, { context: n = null } = {}) {
@@ -1143,7 +1143,7 @@ function $t(e, t) {
1143
1143
  for (let e of n?.readdir(r) ?? []) {
1144
1144
  if (e[0] === ".") continue;
1145
1145
  let i = `${r}/${e}`;
1146
- if (n.readdir(i).some((e) => e.endsWith(".ocio") && new TextDecoder().decode(n.readFile(`${i}/${e}`)) === t)) return i;
1146
+ if (n.readdir(i).some((e) => /\.ocio$/i.test(e) && new TextDecoder().decode(n.readFile(`${i}/${e}`)) === t)) return i;
1147
1147
  }
1148
1148
  } catch {}
1149
1149
  return "";
@@ -1,4 +1,4 @@
1
- import { I as e, L as t, N as n } from "./RayzeeRenderer-ClGfovbz.js";
1
+ import { I as e, L as t, N as n } from "./RayzeeRenderer-DcoDAmCU.js";
2
2
  import { TextureNode as r } from "three/webgpu";
3
3
  import { Vector4 as i } from "three";
4
4
  import { Fn as a, If as o, Loop as s, atomicAdd as c, atomicLoad as l, atomicStore as u, attributeArray as d, dot as f, exp as p, exp2 as m, float as h, floatBitsToUint as g, floor as _, int as v, ivec2 as y, localId as b, log2 as x, max as S, min as C, mix as w, select as T, storage as E, textureLoad as D, toneMappingExposure as O, uint as k, uniform as A, vec2 as j, vec4 as M, workgroupArray as N, workgroupBarrier as P, workgroupId as F } from "three/tsl";
@@ -734,7 +734,7 @@ var L = class {
734
734
  }, this._ready = this.call("init", {
735
735
  namespace: e,
736
736
  root: t
737
- });
737
+ }), this._ready.catch(() => {});
738
738
  }
739
739
  call(e, t, n = []) {
740
740
  return this._worker ? new Promise((r, i) => {
@@ -1,6 +1,6 @@
1
- import { h as e, i as t, m as n, n as r } from "./RayzeeRenderer-ClGfovbz.js";
2
- import { n as i } from "./LocalExposure-CMO6fd8G.js";
3
- import { r as a } from "./ColorManagement-B6SgefNi.js";
1
+ import { h as e, i as t, m as n, n as r } from "./RayzeeRenderer-DcoDAmCU.js";
2
+ import { n as i } from "./LocalExposure-hMqUG2UR.js";
3
+ import { r as a } from "./ColorManagement-BSjTsrve.js";
4
4
  import { DataTexture as o, HalfFloatType as s, NearestFilter as c, RGBAFormat as l } from "three";
5
5
  //#region src/viewer/picture/PictureView.js
6
6
  var u = 1 << 18, d = class {
@@ -5,7 +5,7 @@ import { a as It, i as Lt, l as j, n as Rt, o as zt, r as Bt, s as Vt, t as M }
5
5
  import { $t as Ht, At as Ut, B as Wt, Bt as Gt, C as Kt, Ct as qt, D as Jt, Dt as Yt, E as Xt, F as Zt, Ft as Qt, G as $t, Gt as en, H as tn, Ht as nn, I as rn, It as an, J as on, Jt as sn, K as cn, Kt as ln, L as un, Lt as dn, M as fn, Mt as pn, N as mn, Nt as hn, O as gn, Ot as _n, P as vn, Pt as yn, Q as bn, Qt as xn, R as Sn, Rt as Cn, S as wn, St as Tn, T as En, U as Dn, Ut as On, V as kn, Vt as An, W as jn, Wt as N, X as Mn, Xt as P, Y as Nn, Yt as F, Z as Pn, Zt as Fn, _ as In, _t as Ln, a as Rn, at as zn, b as Bn, bt as Vn, c as Hn, ct as Un, d as Wn, dt as Gn, en as Kn, et as qn, f as Jn, ft as Yn, g as Xn, gt as Zn, h as Qn, ht as $n, i as I, it as er, jt as tr, kt as nr, l as rr, lt as ir, m as ar, mt as or, n as sr, nt as cr, o as lr, ot as ur, p as dr, pt as fr, r as pr, rt as mr, s as hr, st as gr, t as _r, tt as vr, u as yr, ut as br, v as xr, vt as Sr, w as Cr, x as wr, xt as Tr, y as Er, z as Dr, zt as Or } from "./CompactKernel-C6TCBB6i.js";
6
6
  import { _ as kr, a as Ar, b as jr, d as Mr, f as L, g as Nr, h as Pr, l as R, m as Fr, n as Ir, o as Lr, p as Rr, r as zr, s as Br, t as Vr, u as Hr, v as Ur } from "./BufferLayout-ny3WneEc.js";
7
7
  import { i as Wr, n as Gr, t as Kr } from "./EngineIssues-DHAU18xh.js";
8
- import { A as qr, B as Jr, C as Yr, D as Xr, F as Zr, H as Qr, I as $r, K as ei, M as ti, N as ni, O as ri, P as ii, R as ai, S as oi, T as si, U as z, V as B, W as V, _ as ci, b as li, d as ui, f as di, g as fi, h as pi, i as mi, j as hi, k as gi, l as _i, m as vi, n as yi, o as bi, q as xi, r as Si, s as Ci, u as wi, v as Ti, w as Ei, x as Di, y as Oi } from "./ArchiveFormats-CWi6IbSp.js";
8
+ import { A as qr, B as Jr, C as Yr, D as Xr, F as Zr, H as Qr, I as $r, K as ei, M as ti, N as ni, O as ri, P as ii, R as ai, S as oi, T as si, U as z, V as B, W as V, _ as ci, b as li, d as ui, f as di, g as fi, h as pi, i as mi, j as hi, k as gi, l as _i, m as vi, n as yi, o as bi, q as xi, r as Si, s as Ci, u as wi, v as Ti, w as Ei, x as Di, y as Oi } from "./ArchiveFormats-_1o7EfSy.js";
9
9
  import { c as ki, d as H, i as Ai, n as ji, r as Mi, s as Ni } from "./FileIdentity-BXmPNvJP.js";
10
10
  import { a as Pi, i as Fi, n as Ii, r as Li, t as Ri } from "./WorkingMatrix-CDGicYGE.js";
11
11
  import { i as zi, r as Bi, t as U } from "./ActiveColor-DakLCifA.js";
@@ -1275,7 +1275,7 @@ var ac = (e) => [
1275
1275
  let r = n.get(e), i = r.parent;
1276
1276
  if (!i) return null;
1277
1277
  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 = [];
1278
- do {
1278
+ for (;;) {
1279
1279
  for (y.length = 0, y.push(u, _); y.length > 0;) {
1280
1280
  let t = y.pop(), n = y.pop();
1281
1281
  if (n - o <= l) continue;
@@ -1294,7 +1294,7 @@ var ac = (e) => [
1294
1294
  }
1295
1295
  let r = t.parent;
1296
1296
  _ = t.isLeft ? r.rightChild : r.leftChild, v = r;
1297
- } while (n.get(v).parent !== null);
1297
+ }
1298
1298
  return c === a || c === i ? null : c ? {
1299
1299
  from: e,
1300
1300
  to: c,
@@ -1963,7 +1963,7 @@ var Fc = L.FLOATS_PER_TRIANGLE, Ic = (e) => e instanceof Float32Array ? e : new
1963
1963
  let o = r - e, s = i - t, c = a - n;
1964
1964
  return 2 * (o * s + s * c + c * o);
1965
1965
  }
1966
- }, zc = "var e=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 t={silent:0,error:1,warn:2,info:3,debug:4},n=`info`,r=`rayzeeLogLevel`,i=`rayzeeLogNamespaces`,a=`color:#7c8494`,o=`color:inherit`;let s=null,c=null;function l(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function u(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function d(){if(s!==null)return s;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in t?(s=t[e],s):(s=t[l(r)]??t[n],s)}function f(){if(c!==null)return c;let e=globalThis.__RAYZEE_LOG_NS__??l(i);return c=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],c}function p(e,n){if(n<t.debug)return!0;let r=f();return r.length===0||r.some(t=>e===t||e.startsWith(`${t}:`))}function m(e,n,r){if(e>d()||!p(n,e))return;let i=e===t.error?console.error:e===t.warn?console.warn:console.log,s=`[${n}]`;typeof r[0]==`string`?i(`%c${s}%c ${r[0]}`,a,o,...r.slice(1)):i(`%c${s}`,a,...r)}const h={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`)=>`${h.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},g={levels:t,setLevel(e){return e in t?(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e],u(r,e===n?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(t).join(`, `)}`),this.getLevel())},getLevel(){let e=d();return Object.keys(t).find(n=>t[n]===e)},isEnabled(e){return(t[e]??t.debug)<=d()},only(...e){let t=e.flat().filter(Boolean);return c=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),u(i,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return s=null,c=null,this.getLevel()}};function _(e){return{namespace:e,error:(...n)=>m(t.error,e,n),warn:(...n)=>m(t.warn,e,n),info:(...n)=>m(t.info,e,n),debug:(...n)=>m(t.debug,e,n),isEnabled:e=>g.isEnabled(e),summary(n,r=[]){let i=r.filter(Boolean);if(i.length===0||!console.groupCollapsed){m(t.info,e,[n]),i.forEach(n=>m(t.debug,e,[n]));return}t.info>d()||((d()>=t.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${n}`,a,o),i.forEach(e=>console.log(e)),console.groupEnd())}}}function v(e){e&&e in t&&(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e])}const y={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11,UV_AB_OFFSET:12,UV_C_OFFSET:16,MATERIAL_FLAGS_OFFSET:18,MESH_INDEX_OFFSET:19},b={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826,CLUSTER_LEAF:1073741827};new Uint32Array(new Float32Array(1).buffer);function x(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function S(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}const C=b.TRIANGLE_LEAF,w=(e,t)=>~(e<<4|t)>>>0;function T(e){let t=new Uint32Array(e.buffer,e.byteOffset,e.length),n=e.length/16,r=e=>{let n=e*16;return t[n+3]===C&&t[n+1]>0&&t[n+1]<=15},i=new Uint32Array(n),a=new Uint32Array(n),o=0,s=[0];for(;s.length;){let e=s.pop();i[e]=o,a[o++]=e;let n=e*16;t[n+3]>=1073741824||(r(t[n+7])||s.push(t[n+7]),r(t[n+3])||s.push(t[n+3]))}let c=new Float32Array(o*16),l=new Uint32Array(c.buffer);for(let n=0;n<o;n++){let o=a[n]*16,s=n*16;c.set(e.subarray(o,o+16),s),!(t[o+3]>=1073741824)&&(l[s+3]=E(t,t[o+3],r,i),l[s+7]=E(t,t[o+7],r,i))}return c}function E(e,t,n,r){let i=t*16;return n(t)?w(e[i],e[i+1]):r[t]}const D=_(`bvh`),O=b.TRIANGLE_LEAF,k=b.FRONTIER,A=y.FLOATS_PER_TRIANGLE,j=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var M=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(){this.useWorker=!0,this.maxLeafSize=8,this.foldLeaves=!1,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,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},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)}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=j(this.triangles),n=y.POSITION_A_OFFSET,r=y.POSITION_B_OFFSET,i=y.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*A,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(A*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),i=this.flattenBVH(r);return{bvhData:this.foldLeaves?T(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,n=30,r=null,i=null){let a=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(A*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let o=this.totalTriangles,s=performance.now();this.centroids=new Float32Array(o*3),this.bMin=new Float32Array(o*3),this.bMax=new Float32Array(o*3),this.indices=new Uint32Array(o),this.mortonCodes=new Uint32Array(o),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-s,this.sortTrianglesByMortonCode();let c=performance.now(),l=this.buildNodeRecursive(0,o,n,r);if(this.splitStats.sahBuildTime=performance.now()-c,this.enableReinsertionOptimization&&this.totalTriangles>1e3){let t=new e(this.traversalCost,this.intersectionCost);t.setBatchSizeRatio(this.reinsertionBatchSizeRatio),t.setMaxIterations(this.reinsertionMaxIterations);let n=r?e=>{r(e)}:null;try{t.optimizeBVH(l,n)}catch(e){D.error(`reinsertion optimizer failed:`,e)}let i=t.getStatistics();this.splitStats.reinsertionOptimizationTime=i.timeMs,this.splitStats.reinsertionsApplied=i.reinsertionsApplied,this.splitStats.reinsertionIterations=i.iterations}let u=performance.now();this.applySAOrdering(l),this.splitStats.saOrderTime=performance.now()-u;let d=performance.now(),f=this.triangles,p=i||new f.constructor(o*A);for(let e=0;e<o;e++){let t=this.indices[e]*A,n=e*A;p.set(f.subarray(t,t+A),n)}this.reorderedTriangleData=p;let m=new Uint32Array(o);for(let e=0;e<o;e++)m[this.indices[e]]=e;this.originalToBvhMap=m,this.splitStats.reorderTime=performance.now()-d,this.splitStats.totalBuildTime=performance.now()-a;let g=this.splitStats.totalBuildTime,_=this.splitStats;return D.debug(`${h.n(o)} tris → ${h.n(this.totalNodes)} nodes in ${h.ms(g)} | SAH ${_.sahSplits} objMed ${_.objectMedianSplits} spatMed ${_.spatialMedianSplits} failed ${_.failedSplits}`+(_.reinsertionsApplied?` | reinsertions ${_.reinsertionsApplied}`:``)),r&&r(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,l}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 M;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new M;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}S(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=x(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=O}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)}S(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=x(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=k,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=O}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;S(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=x(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<O&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const P=_(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;v(t.logLevel),n===`buildPhase1`?F(t):n===`assemble`?I(t):L(t)};function F(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u}=e;try{let e=new N,d=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let f=performance.now(),p=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-p,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let m=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,d);e.splitStats.sahBuildTime=performance.now()-m,e.applySAOrdering(g);let _=performance.now(),{flatData:v,frontierMap:y,nodeCount:b}=e.flattenBVHWithFrontier(g),x=performance.now()-_,S=performance.now()-f;P.debug(`phase 1 ${h.ms(S)} (init ${h.ms(e.splitStats.initTime)} · morton ${h.ms(e.splitStats.mortonSortTime)} · SAH ${h.ms(e.splitStats.sahBuildTime)} · flatten ${h.ms(x)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:v,topNodeCount:b,frontierTasks:e.frontierTasks,frontierMap:y,splitStats:e.splitStats},[v.buffer])}catch(e){P.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function I(e){let{topFlatData:t,topNodeCount:n,frontierMap:r,subtreeResults:i,sharedTriangleData:a,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c,foldLeaves:l}=e;try{let e=performance.now(),u=new N().assembleParallelBVH(t,n,r,i),d=l?T(u):u,f=new Uint32Array(o);if(s){let e=new Uint32Array(a),t=new Uint32Array(s);for(let n=0;n<c;n++){let r=f[n]*20,i=n*20;t.set(e.subarray(r,r+20),i)}}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[f[e]]=e;let m=performance.now()-e;P.debug(`phase 3 assemble + reorder ${h.ms(m)} (${h.mb(d.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:d,originalToBvh:p,triangleCount:c},[d.buffer,p.buffer])}catch(e){P.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function L(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,reinsertionOptimization:o,sharedReorderBuffer:s,maxLeafSize:c,numBins:l,maxBins:u,minBins:d,foldLeaves:f}=e,p=new N;c!==void 0&&(p.maxLeafSize=c),l!==void 0&&(p.numBins=l),u!==void 0&&(p.maxBins=u),d!==void 0&&(p.minBins=d);try{o&&p.setReinsertionConfig(o);let e=a?e=>{self.postMessage({progress:e})}:null,c=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),l=s?new Uint32Array(s):null,u=p.buildSync(c,i,e,l),d=performance.now(),m=p.flattenBVH(u),g=f?T(m):m,_=performance.now()-d;P.debug(`flatten ${h.ms(_)} (${h.mb(g.byteLength)})`);let v=p.originalToBvhMap||null;if(s){let e=[g.buffer];v&&e.push(v.buffer),self.postMessage({bvhData:g,originalToBvh:v,triangleCount:c.length/20,splitStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/80,n=[g.buffer,e.buffer];v&&n.push(v.buffer),self.postMessage({bvhData:g,triangles:e,originalToBvh:v,triangleCount:t,splitStats:p.splitStats},n)}}catch(e){P.error(`build failed:`,e),self.postMessage({error:e.message})}}", Bc = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", zc], { type: "text/javascript;charset=utf-8" });
1966
+ }, zc = "var e=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=[];for(;;){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}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 t={silent:0,error:1,warn:2,info:3,debug:4},n=`info`,r=`rayzeeLogLevel`,i=`rayzeeLogNamespaces`,a=`color:#7c8494`,o=`color:inherit`;let s=null,c=null;function l(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function u(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function d(){if(s!==null)return s;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in t?(s=t[e],s):(s=t[l(r)]??t[n],s)}function f(){if(c!==null)return c;let e=globalThis.__RAYZEE_LOG_NS__??l(i);return c=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],c}function p(e,n){if(n<t.debug)return!0;let r=f();return r.length===0||r.some(t=>e===t||e.startsWith(`${t}:`))}function m(e,n,r){if(e>d()||!p(n,e))return;let i=e===t.error?console.error:e===t.warn?console.warn:console.log,s=`[${n}]`;typeof r[0]==`string`?i(`%c${s}%c ${r[0]}`,a,o,...r.slice(1)):i(`%c${s}`,a,...r)}const h={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`)=>`${h.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},g={levels:t,setLevel(e){return e in t?(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e],u(r,e===n?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(t).join(`, `)}`),this.getLevel())},getLevel(){let e=d();return Object.keys(t).find(n=>t[n]===e)},isEnabled(e){return(t[e]??t.debug)<=d()},only(...e){let t=e.flat().filter(Boolean);return c=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),u(i,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return s=null,c=null,this.getLevel()}};function _(e){return{namespace:e,error:(...n)=>m(t.error,e,n),warn:(...n)=>m(t.warn,e,n),info:(...n)=>m(t.info,e,n),debug:(...n)=>m(t.debug,e,n),isEnabled:e=>g.isEnabled(e),summary(n,r=[]){let i=r.filter(Boolean);if(i.length===0||!console.groupCollapsed){m(t.info,e,[n]),i.forEach(n=>m(t.debug,e,[n]));return}t.info>d()||((d()>=t.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${n}`,a,o),i.forEach(e=>console.log(e)),console.groupEnd())}}}function v(e){e&&e in t&&(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e])}const y={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11,UV_AB_OFFSET:12,UV_C_OFFSET:16,MATERIAL_FLAGS_OFFSET:18,MESH_INDEX_OFFSET:19},b={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826,CLUSTER_LEAF:1073741827};new Uint32Array(new Float32Array(1).buffer);function x(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function S(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}const C=b.TRIANGLE_LEAF,w=(e,t)=>~(e<<4|t)>>>0;function T(e){let t=new Uint32Array(e.buffer,e.byteOffset,e.length),n=e.length/16,r=e=>{let n=e*16;return t[n+3]===C&&t[n+1]>0&&t[n+1]<=15},i=new Uint32Array(n),a=new Uint32Array(n),o=0,s=[0];for(;s.length;){let e=s.pop();i[e]=o,a[o++]=e;let n=e*16;t[n+3]>=1073741824||(r(t[n+7])||s.push(t[n+7]),r(t[n+3])||s.push(t[n+3]))}let c=new Float32Array(o*16),l=new Uint32Array(c.buffer);for(let n=0;n<o;n++){let o=a[n]*16,s=n*16;c.set(e.subarray(o,o+16),s),!(t[o+3]>=1073741824)&&(l[s+3]=E(t,t[o+3],r,i),l[s+7]=E(t,t[o+7],r,i))}return c}function E(e,t,n,r){let i=t*16;return n(t)?w(e[i],e[i+1]):r[t]}const D=_(`bvh`),O=b.TRIANGLE_LEAF,k=b.FRONTIER,A=y.FLOATS_PER_TRIANGLE,j=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var M=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(){this.useWorker=!0,this.maxLeafSize=8,this.foldLeaves=!1,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,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},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)}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=j(this.triangles),n=y.POSITION_A_OFFSET,r=y.POSITION_B_OFFSET,i=y.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*A,o=t[e+n],s=t[e+n+1],c=t[e+n+2],l=t[e+r],u=t[e+r+1],d=t[e+r+2],f=t[e+i],p=t[e+i+1],m=t[e+i+2],h=a*3;this.centroids[h]=(o+l+f)/3,this.centroids[h+1]=(s+u+p)/3,this.centroids[h+2]=(c+d+m)/3,this.bMin[h]=o<l?o<f?o:f:l<f?l:f,this.bMin[h+1]=s<u?s<p?s:p:u<p?u:p,this.bMin[h+2]=c<d?c<m?c:m:d<m?d:m,this.bMax[h]=o>l?o>f?o:f:l>f?l:f,this.bMax[h+1]=s>u?s>p?s:p:u>p?u:p,this.bMax[h+2]=c>d?c>m?c:m:d>m?d:m,this.indices[a]=a}}expandBits(e){return e=e*65537&4278190335,e=e*257&251719695,e=e*17&3272356035,e=e*5&1227133513,e}morton3D(e,t,n){return(this.expandBits(n)<<2)+(this.expandBits(t)<<1)+this.expandBits(e)}computeMortonCodeForIndex(e,t,n,r,i,a,o){let s=this.centroids,c=e*3,l=(1<<this.mortonBits)-1,u=i>0?(s[c]-t)/i:0,d=a>0?(s[c+1]-n)/a:0,f=o>0?(s[c+2]-r)/o:0,p=Math.max(0,Math.min(l,Math.floor(u*l))),m=Math.max(0,Math.min(l,Math.floor(d*l))),h=Math.max(0,Math.min(l,Math.floor(f*l)));return this.morton3D(p,m,h)}sortTrianglesByMortonCode(){let e=this.totalTriangles;if(!this.useMortonCodes||e<this.mortonClusterThreshold)return;let t=performance.now(),n=this.centroids,r=this.indices,i=1/0,a=1/0,o=1/0,s=-1/0,c=-1/0,l=-1/0;for(let t=0;t<e;t++){let e=r[t]*3,u=n[e],d=n[e+1],f=n[e+2];u<i&&(i=u),d<a&&(a=d),f<o&&(o=f),u>s&&(s=u),d>c&&(c=d),f>l&&(l=f)}let u=s-i,d=c-a,f=l-o,p=this.mortonCodes,m=(1<<this.mortonBits)-1,h=u>0?m/u:0,g=d>0?m/d:0,_=f>0?m/f:0;for(let t=0;t<e;t++){let e=r[t],s=e*3,c=(n[s]-i)*h,l=(n[s+1]-a)*g,u=(n[s+2]-o)*_;c=c<0?0:(c>m?m:c)|0,l=l<0?0:(l>m?m:l)|0,u=u<0?0:(u>m?m:u)|0,c=c*65537&4278190335,c=c*257&251719695,c=c*17&3272356035,c=c*5&1227133513,l=l*65537&4278190335,l=l*257&251719695,l=l*17&3272356035,l=l*5&1227133513,u=u*65537&4278190335,u=u*257&251719695,u=u*17&3272356035,u=u*5&1227133513,p[e]=(u<<2)+(l<<1)+c}let v=new Uint32Array(e),y=new Uint32Array(256);for(let t=0;t<32;t+=8){y.fill(0);for(let n=0;n<e;n++)y[p[r[n]]>>>t&255]++;let n=0;for(let e=0;e<256;e++){let t=y[e];y[e]=n,n+=t}for(let n=0;n<e;n++){let e=p[r[n]]>>>t&255;v[y[e]++]=r[n]}r.set(v)}this.splitStats.mortonSortTime+=performance.now()-t}build(e,t=30,n=null){if(this.totalTriangles=e.byteLength/(A*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),i=this.flattenBVH(r);return{bvhData:this.foldLeaves?T(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,n=30,r=null,i=null){let a=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(A*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let o=this.totalTriangles,s=performance.now();this.centroids=new Float32Array(o*3),this.bMin=new Float32Array(o*3),this.bMax=new Float32Array(o*3),this.indices=new Uint32Array(o),this.mortonCodes=new Uint32Array(o),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-s,this.sortTrianglesByMortonCode();let c=performance.now(),l=this.buildNodeRecursive(0,o,n,r);if(this.splitStats.sahBuildTime=performance.now()-c,this.enableReinsertionOptimization&&this.totalTriangles>1e3){let t=new e(this.traversalCost,this.intersectionCost);t.setBatchSizeRatio(this.reinsertionBatchSizeRatio),t.setMaxIterations(this.reinsertionMaxIterations);let n=r?e=>{r(e)}:null;try{t.optimizeBVH(l,n)}catch(e){D.error(`reinsertion optimizer failed:`,e)}let i=t.getStatistics();this.splitStats.reinsertionOptimizationTime=i.timeMs,this.splitStats.reinsertionsApplied=i.reinsertionsApplied,this.splitStats.reinsertionIterations=i.iterations}let u=performance.now();this.applySAOrdering(l),this.splitStats.saOrderTime=performance.now()-u;let d=performance.now(),f=this.triangles,p=i||new f.constructor(o*A);for(let e=0;e<o;e++){let t=this.indices[e]*A,n=e*A;p.set(f.subarray(t,t+A),n)}this.reorderedTriangleData=p;let m=new Uint32Array(o);for(let e=0;e<o;e++)m[this.indices[e]]=e;this.originalToBvhMap=m,this.splitStats.reorderTime=performance.now()-d,this.splitStats.totalBuildTime=performance.now()-a;let g=this.splitStats.totalBuildTime,_=this.splitStats;return D.debug(`${h.n(o)} tris → ${h.n(this.totalNodes)} nodes in ${h.ms(g)} | SAH ${_.sahSplits} objMed ${_.objectMedianSplits} spatMed ${_.spatialMedianSplits} failed ${_.failedSplits}`+(_.reinsertionsApplied?` | reinsertions ${_.reinsertionsApplied}`:``)),r&&r(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,l}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 M;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new M;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}S(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=x(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=O}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)}S(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=x(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=k,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=O}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;S(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=x(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<O&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};const P=_(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;v(t.logLevel),n===`buildPhase1`?F(t):n===`assemble`?I(t):L(t)};function F(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u}=e;try{let e=new N,d=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let f=performance.now(),p=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-p,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let m=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,d);e.splitStats.sahBuildTime=performance.now()-m,e.applySAOrdering(g);let _=performance.now(),{flatData:v,frontierMap:y,nodeCount:b}=e.flattenBVHWithFrontier(g),x=performance.now()-_,S=performance.now()-f;P.debug(`phase 1 ${h.ms(S)} (init ${h.ms(e.splitStats.initTime)} · morton ${h.ms(e.splitStats.mortonSortTime)} · SAH ${h.ms(e.splitStats.sahBuildTime)} · flatten ${h.ms(x)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:v,topNodeCount:b,frontierTasks:e.frontierTasks,frontierMap:y,splitStats:e.splitStats},[v.buffer])}catch(e){P.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function I(e){let{topFlatData:t,topNodeCount:n,frontierMap:r,subtreeResults:i,sharedTriangleData:a,sharedIndices:o,sharedReorderBuffer:s,triangleCount:c,foldLeaves:l}=e;try{let e=performance.now(),u=new N().assembleParallelBVH(t,n,r,i),d=l?T(u):u,f=new Uint32Array(o);if(s){let e=new Uint32Array(a),t=new Uint32Array(s);for(let n=0;n<c;n++){let r=f[n]*20,i=n*20;t.set(e.subarray(r,r+20),i)}}let p=new Uint32Array(c);for(let e=0;e<c;e++)p[f[e]]=e;let m=performance.now()-e;P.debug(`phase 3 assemble + reorder ${h.ms(m)} (${h.mb(d.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:d,originalToBvh:p,triangleCount:c},[d.buffer,p.buffer])}catch(e){P.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function L(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,reinsertionOptimization:o,sharedReorderBuffer:s,maxLeafSize:c,numBins:l,maxBins:u,minBins:d,foldLeaves:f}=e,p=new N;c!==void 0&&(p.maxLeafSize=c),l!==void 0&&(p.numBins=l),u!==void 0&&(p.maxBins=u),d!==void 0&&(p.minBins=d);try{o&&p.setReinsertionConfig(o);let e=a?e=>{self.postMessage({progress:e})}:null,c=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),l=s?new Uint32Array(s):null,u=p.buildSync(c,i,e,l),d=performance.now(),m=p.flattenBVH(u),g=f?T(m):m,_=performance.now()-d;P.debug(`flatten ${h.ms(_)} (${h.mb(g.byteLength)})`);let v=p.originalToBvhMap||null;if(s){let e=[g.buffer];v&&e.push(v.buffer),self.postMessage({bvhData:g,originalToBvh:v,triangleCount:c.length/20,splitStats:p.splitStats},e)}else{let e=p.reorderedTriangleData,t=e.byteLength/80,n=[g.buffer,e.buffer];v&&n.push(v.buffer),self.postMessage({bvhData:g,triangles:e,originalToBvh:v,triangleCount:t,splitStats:p.splitStats},n)}}catch(e){P.error(`build failed:`,e),self.postMessage({error:e.message})}}", Bc = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", zc], { type: "text/javascript;charset=utf-8" });
1967
1967
  function Vc(e) {
1968
1968
  let t;
1969
1969
  try {
@@ -1984,7 +1984,7 @@ function Vc(e) {
1984
1984
  }
1985
1985
  //#endregion
1986
1986
  //#region src/bvh/BVHSubtreeWorker.js?worker&inline
1987
- var Hc = "var e=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 t={silent:0,error:1,warn:2,info:3,debug:4},n=`info`,r=`rayzeeLogLevel`,i=`rayzeeLogNamespaces`,a=`color:#7c8494`,o=`color:inherit`;let s=null,c=null;function l(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function u(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function d(){if(s!==null)return s;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in t?(s=t[e],s):(s=t[l(r)]??t[n],s)}function f(){if(c!==null)return c;let e=globalThis.__RAYZEE_LOG_NS__??l(i);return c=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],c}function p(e,n){if(n<t.debug)return!0;let r=f();return r.length===0||r.some(t=>e===t||e.startsWith(`${t}:`))}function m(e,n,r){if(e>d()||!p(n,e))return;let i=e===t.error?console.error:e===t.warn?console.warn:console.log,s=`[${n}]`;typeof r[0]==`string`?i(`%c${s}%c ${r[0]}`,a,o,...r.slice(1)):i(`%c${s}`,a,...r)}const h={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`)=>`${h.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},g={levels:t,setLevel(e){return e in t?(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e],u(r,e===n?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(t).join(`, `)}`),this.getLevel())},getLevel(){let e=d();return Object.keys(t).find(n=>t[n]===e)},isEnabled(e){return(t[e]??t.debug)<=d()},only(...e){let t=e.flat().filter(Boolean);return c=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),u(i,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return s=null,c=null,this.getLevel()}};function _(e){return{namespace:e,error:(...n)=>m(t.error,e,n),warn:(...n)=>m(t.warn,e,n),info:(...n)=>m(t.info,e,n),debug:(...n)=>m(t.debug,e,n),isEnabled:e=>g.isEnabled(e),summary(n,r=[]){let i=r.filter(Boolean);if(i.length===0||!console.groupCollapsed){m(t.info,e,[n]),i.forEach(n=>m(t.debug,e,[n]));return}t.info>d()||((d()>=t.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${n}`,a,o),i.forEach(e=>console.log(e)),console.groupEnd())}}}const v={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11,UV_AB_OFFSET:12,UV_C_OFFSET:16,MATERIAL_FLAGS_OFFSET:18,MESH_INDEX_OFFSET:19},y={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826,CLUSTER_LEAF:1073741827};new Uint32Array(new Float32Array(1).buffer);function b(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function x(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}const S=y.TRIANGLE_LEAF,C=(e,t)=>~(e<<4|t)>>>0;function w(e){let t=new Uint32Array(e.buffer,e.byteOffset,e.length),n=e.length/16,r=e=>{let n=e*16;return t[n+3]===S&&t[n+1]>0&&t[n+1]<=15},i=new Uint32Array(n),a=new Uint32Array(n),o=0,s=[0];for(;s.length;){let e=s.pop();i[e]=o,a[o++]=e;let n=e*16;t[n+3]>=1073741824||(r(t[n+7])||s.push(t[n+7]),r(t[n+3])||s.push(t[n+3]))}let c=new Float32Array(o*16),l=new Uint32Array(c.buffer);for(let n=0;n<o;n++){let o=a[n]*16,s=n*16;c.set(e.subarray(o,o+16),s),!(t[o+3]>=1073741824)&&(l[s+3]=T(t,t[o+3],r,i),l[s+7]=T(t,t[o+7],r,i))}return c}function T(e,t,n,r){let i=t*16;return n(t)?C(e[i],e[i+1]):r[t]}const E=_(`bvh`),D=y.TRIANGLE_LEAF,O=y.FRONTIER,k=v.FLOATS_PER_TRIANGLE,A=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var j=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}},M=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.foldLeaves=!1,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,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},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)}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=A(this.triangles),n=v.POSITION_A_OFFSET,r=v.POSITION_B_OFFSET,i=v.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*k,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/(k*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),i=this.flattenBVH(r);return{bvhData:this.foldLeaves?w(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,n=30,r=null,i=null){let a=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(k*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let o=this.totalTriangles,s=performance.now();this.centroids=new Float32Array(o*3),this.bMin=new Float32Array(o*3),this.bMax=new Float32Array(o*3),this.indices=new Uint32Array(o),this.mortonCodes=new Uint32Array(o),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-s,this.sortTrianglesByMortonCode();let c=performance.now(),l=this.buildNodeRecursive(0,o,n,r);if(this.splitStats.sahBuildTime=performance.now()-c,this.enableReinsertionOptimization&&this.totalTriangles>1e3){let t=new e(this.traversalCost,this.intersectionCost);t.setBatchSizeRatio(this.reinsertionBatchSizeRatio),t.setMaxIterations(this.reinsertionMaxIterations);let n=r?e=>{r(e)}:null;try{t.optimizeBVH(l,n)}catch(e){E.error(`reinsertion optimizer failed:`,e)}let i=t.getStatistics();this.splitStats.reinsertionOptimizationTime=i.timeMs,this.splitStats.reinsertionsApplied=i.reinsertionsApplied,this.splitStats.reinsertionIterations=i.iterations}let u=performance.now();this.applySAOrdering(l),this.splitStats.saOrderTime=performance.now()-u;let d=performance.now(),f=this.triangles,p=i||new f.constructor(o*k);for(let e=0;e<o;e++){let t=this.indices[e]*k,n=e*k;p.set(f.subarray(t,t+k),n)}this.reorderedTriangleData=p;let m=new Uint32Array(o);for(let e=0;e<o;e++)m[this.indices[e]]=e;this.originalToBvhMap=m,this.splitStats.reorderTime=performance.now()-d,this.splitStats.totalBuildTime=performance.now()-a;let g=this.splitStats.totalBuildTime,_=this.splitStats;return E.debug(`${h.n(o)} tris → ${h.n(this.totalNodes)} nodes in ${h.ms(g)} | SAH ${_.sahSplits} objMed ${_.objectMedianSplits} spatMed ${_.spatialMedianSplits} failed ${_.failedSplits}`+(_.reinsertionsApplied?` | reinsertions ${_.reinsertionsApplied}`:``)),r&&r(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,l}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 j;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new j;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}x(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=b(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=D}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)}x(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=b(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=O,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=D}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;x(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=b(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<D&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:n,sharedTriangleData:r,sharedCentroids:i,sharedBMin:a,sharedBMax:o,sharedIndices:s,triangleCount:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f,reinsertionConfig:p,reportProgress:m}=t.data;for(let t=0;t<n.length;t++){let h=n[t];try{let t=new M;t.maxLeafSize=l,t.numBins=u,t.maxBins=d,t.minBins=f,t.triangles=new Float32Array(r),t.centroids=new Float32Array(i),t.bMin=new Float32Array(a),t.bMax=new Float32Array(o),t.indices=new Uint32Array(s),t.totalTriangles=c,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,initTime:0,sahBuildTime:0,reorderTime:0};let n=m?e=>{self.postMessage({type:`progress`,taskId:h.taskId,progress:e})}:null,g=performance.now(),_=t.buildNodeRecursive(h.start,h.end,h.depth,n,h.preMinX,h.preMinY,h.preMinZ,h.preMaxX,h.preMaxY,h.preMaxZ);if(p&&p.enabled&&h.end-h.start>1e3){let n=new e(t.traversalCost,t.intersectionCost);p.batchSizeRatio&&n.setBatchSizeRatio(p.batchSizeRatio),p.maxIterations&&n.setMaxIterations(p.maxIterations);try{n.optimizeBVH(_,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(_);let v=t.flattenBVH(_),y=v.length/16,b=performance.now()-g;console.log(`[BVHSubtreeWorker] Task ${h.taskId}: ${(h.end-h.start).toLocaleString()} triangles, ${y} nodes, ${Math.round(b)}ms`),self.postMessage({type:`subtreeResult`,taskId:h.taskId,flatData:v,nodeCount:y},[v.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${h.taskId} error:`,e),self.postMessage({type:`error`,taskId:h.taskId,error:e.message})}}};", Uc = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Hc], { type: "text/javascript;charset=utf-8" });
1987
+ var Hc = "var e=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=[];for(;;){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}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 t={silent:0,error:1,warn:2,info:3,debug:4},n=`info`,r=`rayzeeLogLevel`,i=`rayzeeLogNamespaces`,a=`color:#7c8494`,o=`color:inherit`;let s=null,c=null;function l(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function u(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function d(){if(s!==null)return s;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in t?(s=t[e],s):(s=t[l(r)]??t[n],s)}function f(){if(c!==null)return c;let e=globalThis.__RAYZEE_LOG_NS__??l(i);return c=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],c}function p(e,n){if(n<t.debug)return!0;let r=f();return r.length===0||r.some(t=>e===t||e.startsWith(`${t}:`))}function m(e,n,r){if(e>d()||!p(n,e))return;let i=e===t.error?console.error:e===t.warn?console.warn:console.log,s=`[${n}]`;typeof r[0]==`string`?i(`%c${s}%c ${r[0]}`,a,o,...r.slice(1)):i(`%c${s}`,a,...r)}const h={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`)=>`${h.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},g={levels:t,setLevel(e){return e in t?(globalThis.__RAYZEE_LOG_LEVEL__=e,s=t[e],u(r,e===n?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(t).join(`, `)}`),this.getLevel())},getLevel(){let e=d();return Object.keys(t).find(n=>t[n]===e)},isEnabled(e){return(t[e]??t.debug)<=d()},only(...e){let t=e.flat().filter(Boolean);return c=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),u(i,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return s=null,c=null,this.getLevel()}};function _(e){return{namespace:e,error:(...n)=>m(t.error,e,n),warn:(...n)=>m(t.warn,e,n),info:(...n)=>m(t.info,e,n),debug:(...n)=>m(t.debug,e,n),isEnabled:e=>g.isEnabled(e),summary(n,r=[]){let i=r.filter(Boolean);if(i.length===0||!console.groupCollapsed){m(t.info,e,[n]),i.forEach(n=>m(t.debug,e,[n]));return}t.info>d()||((d()>=t.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${n}`,a,o),i.forEach(e=>console.log(e)),console.groupEnd())}}}const v={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8,NORMAL_A_PACKED_OFFSET:3,NORMAL_B_PACKED_OFFSET:7,NORMAL_C_PACKED_OFFSET:11,UV_AB_OFFSET:12,UV_C_OFFSET:16,MATERIAL_FLAGS_OFFSET:18,MESH_INDEX_OFFSET:19},y={TRIANGLE_LEAF:1073741824,BLAS_POINTER_LEAF:1073741825,FRONTIER:1073741826,CLUSTER_LEAF:1073741827};new Uint32Array(new Float32Array(1).buffer);function b(e){return new Uint32Array(e.buffer,e.byteOffset,e.length)}function x(e,t){if(e>=1073741824)throw RangeError(`${t} is ${e.toLocaleString()}, at or past the BVH index limit of ${1073741824 .toLocaleString()}. Node indices are stored as u32 bit patterns and the leaf tags occupy everything above that.`);return e}const S=y.TRIANGLE_LEAF,C=(e,t)=>~(e<<4|t)>>>0;function w(e){let t=new Uint32Array(e.buffer,e.byteOffset,e.length),n=e.length/16,r=e=>{let n=e*16;return t[n+3]===S&&t[n+1]>0&&t[n+1]<=15},i=new Uint32Array(n),a=new Uint32Array(n),o=0,s=[0];for(;s.length;){let e=s.pop();i[e]=o,a[o++]=e;let n=e*16;t[n+3]>=1073741824||(r(t[n+7])||s.push(t[n+7]),r(t[n+3])||s.push(t[n+3]))}let c=new Float32Array(o*16),l=new Uint32Array(c.buffer);for(let n=0;n<o;n++){let o=a[n]*16,s=n*16;c.set(e.subarray(o,o+16),s),!(t[o+3]>=1073741824)&&(l[s+3]=T(t,t[o+3],r,i),l[s+7]=T(t,t[o+7],r,i))}return c}function T(e,t,n,r){let i=t*16;return n(t)?C(e[i],e[i+1]):r[t]}const E=_(`bvh`),D=y.TRIANGLE_LEAF,O=y.FRONTIER,k=v.FLOATS_PER_TRIANGLE,A=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var j=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}},M=class{constructor(){this.useWorker=!0,this.maxLeafSize=8,this.foldLeaves=!1,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,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},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)}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=A(this.triangles),n=v.POSITION_A_OFFSET,r=v.POSITION_B_OFFSET,i=v.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*k,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/(k*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),i=this.flattenBVH(r);return{bvhData:this.foldLeaves?w(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,n=30,r=null,i=null){let a=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(k*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let o=this.totalTriangles,s=performance.now();this.centroids=new Float32Array(o*3),this.bMin=new Float32Array(o*3),this.bMax=new Float32Array(o*3),this.indices=new Uint32Array(o),this.mortonCodes=new Uint32Array(o),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-s,this.sortTrianglesByMortonCode();let c=performance.now(),l=this.buildNodeRecursive(0,o,n,r);if(this.splitStats.sahBuildTime=performance.now()-c,this.enableReinsertionOptimization&&this.totalTriangles>1e3){let t=new e(this.traversalCost,this.intersectionCost);t.setBatchSizeRatio(this.reinsertionBatchSizeRatio),t.setMaxIterations(this.reinsertionMaxIterations);let n=r?e=>{r(e)}:null;try{t.optimizeBVH(l,n)}catch(e){E.error(`reinsertion optimizer failed:`,e)}let i=t.getStatistics();this.splitStats.reinsertionOptimizationTime=i.timeMs,this.splitStats.reinsertionsApplied=i.reinsertionsApplied,this.splitStats.reinsertionIterations=i.iterations}let u=performance.now();this.applySAOrdering(l),this.splitStats.saOrderTime=performance.now()-u;let d=performance.now(),f=this.triangles,p=i||new f.constructor(o*k);for(let e=0;e<o;e++){let t=this.indices[e]*k,n=e*k;p.set(f.subarray(t,t+k),n)}this.reorderedTriangleData=p;let m=new Uint32Array(o);for(let e=0;e<o;e++)m[this.indices[e]]=e;this.originalToBvhMap=m,this.splitStats.reorderTime=performance.now()-d,this.splitStats.totalBuildTime=performance.now()-a;let g=this.splitStats.totalBuildTime,_=this.splitStats;return E.debug(`${h.n(o)} tris → ${h.n(this.totalNodes)} nodes in ${h.ms(g)} | SAH ${_.sahSplits} objMed ${_.objectMedianSplits} spatMed ${_.spatialMedianSplits} failed ${_.failedSplits}`+(_.reinsertionsApplied?` | reinsertions ${_.reinsertionsApplied}`:``)),r&&r(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,l}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 j;this.totalNodes++;let f=t-e;if(a===void 0?this.updateNodeBounds(d,e,t):(d.minX=a,d.minY=o,d.minZ=s,d.maxX=c,d.maxY=l,d.maxZ=u),f<=this.maxLeafSize||n<=0)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;if(r<=0&&f>this.maxLeafSize*16){let r=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=r,this.frontierTasks.push({taskId:r,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}let p=this.findBestSplitPositionSAH(e,t,d);if(!p.success){if(this.splitStats.failedSplits++,r>0||f<=this.maxLeafSize*16)return d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d;let a=this.frontierTasks.length;return d.triangleOffset=e,d.triangleCount=f,d.isFrontier=!0,d.frontierTaskId=a,this.frontierTasks.push({taskId:a,start:e,end:t,depth:n,preMinX:d.minX,preMinY:d.minY,preMinZ:d.minZ,preMaxX:d.maxX,preMaxY:d.maxY,preMaxZ:d.maxZ}),d}p.method===`SAH`?this.splitStats.sahSplits++:p.method===`object_median`?this.splitStats.objectMedianSplits++:p.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,p.axis,p.pos);let m=this._partResult,h=m.mid,g=m.lMinX,_=m.lMinY,v=m.lMinZ,y=m.lMaxX,b=m.lMaxY,x=m.lMaxZ,S=m.rMinX,C=m.rMinY,w=m.rMinZ,T=m.rMaxX,E=m.rMaxY,D=m.rMaxZ;return h===e||h===t?(d.triangleOffset=e,d.triangleCount=f,this.updateProgress(f,i),d):(d.leftChild=this.buildNodeRecursiveToDepth(e,h,n-1,r-1,i,g,_,v,y,b,x),d.rightChild=this.buildNodeRecursiveToDepth(h,t,n-1,r-1,i,S,C,w,T,E,D),d)}buildNodeRecursive(e,t,n,r,i,a,o,s,c,l){let u=new j;this.totalNodes++;let d=t-e;if(i===void 0?this.updateNodeBounds(u,e,t):(u.minX=i,u.minY=a,u.minZ=o,u.maxX=s,u.maxY=c,u.maxZ=l),d<=this.maxLeafSize||n<=0)return u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;let f=this.findBestSplitPositionSAH(e,t,u);if(!f.success)return this.splitStats.failedSplits++,u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u;f.method===`SAH`?this.splitStats.sahSplits++:f.method===`object_median`?this.splitStats.objectMedianSplits++:f.method===`spatial_median`&&this.splitStats.spatialMedianSplits++,this.partitionWithBounds(e,t,f.axis,f.pos);let p=this._partResult,m=p.mid,h=p.lMinX,g=p.lMinY,_=p.lMinZ,v=p.lMaxX,y=p.lMaxY,b=p.lMaxZ,x=p.rMinX,S=p.rMinY,C=p.rMinZ,w=p.rMaxX,T=p.rMaxY,E=p.rMaxZ;return m===e||m===t?(u.triangleOffset=e,u.triangleCount=d,this.updateProgress(d,r),u):(u.leftChild=this.buildNodeRecursive(e,m,n-1,r,h,g,_,v,y,b),u.rightChild=this.buildNodeRecursive(m,t,n-1,r,x,S,C,w,T,E),u)}partitionWithBounds(e,t,n,r){let i=this.indices,a=this.centroids,o=this.bMin,s=this.bMax,c=e,l=t-1,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0,g=1/0,_=1/0,v=1/0,y=-1/0,b=-1/0,x=-1/0;for(;c<=l;){let e=i[c],t=e*3;a[t+n]<=r?(o[t]<u&&(u=o[t]),o[t+1]<d&&(d=o[t+1]),o[t+2]<f&&(f=o[t+2]),s[t]>p&&(p=s[t]),s[t+1]>m&&(m=s[t+1]),s[t+2]>h&&(h=s[t+2]),c++):(o[t]<g&&(g=o[t]),o[t+1]<_&&(_=o[t+1]),o[t+2]<v&&(v=o[t+2]),s[t]>y&&(y=s[t]),s[t+1]>b&&(b=s[t+1]),s[t+2]>x&&(x=s[t+2]),i[c]=i[l],i[l]=e,l--)}let S=this._partResult;return S.mid=c,S.lMinX=u,S.lMinY=d,S.lMinZ=f,S.lMaxX=p,S.lMaxY=m,S.lMaxZ=h,S.rMinX=g,S.rMinY=_,S.rMinZ=v,S.rMaxX=y,S.rMaxY=b,S.rMaxZ=x,S}updateNodeBounds(e,t,n){let r=1/0,i=1/0,a=1/0,o=-1/0,s=-1/0,c=-1/0,l=this.indices,u=this.bMin,d=this.bMax;for(let e=t;e<n;e++){let t=l[e]*3;u[t]<r&&(r=u[t]),u[t+1]<i&&(i=u[t+1]),u[t+2]<a&&(a=u[t+2]),d[t]>o&&(o=d[t]),d[t+1]>s&&(s=d[t+1]),d[t+2]>c&&(c=d[t+2])}e.minX=r,e.minY=i,e.minZ=a,e.maxX=o,e.maxY=s,e.maxZ=c}findBestSplitPositionSAH(e,t,n){let r=1/0,i=-1,a=0,o=this.computeSurfaceAreaFlat(n.minX,n.minY,n.minZ,n.maxX,n.maxY,n.maxZ),s=t-e,c=this.intersectionCost*s,l=this.getOptimalBinCount(s);this.splitStats.totalSplitAttempts++,this.splitStats.avgBinsUsed=(this.splitStats.avgBinsUsed*(this.splitStats.totalSplitAttempts-1)+l)/this.splitStats.totalSplitAttempts;let u=this.indices,d=this.centroids,f=this.bMin,p=this.bMax,m=this.binBoundsMin,h=this.binBoundsMax,g=this.binCounts,_=this.leftPrefixMin,v=this.leftPrefixMax,y=this.leftPrefixCount,b=this.rightPrefixMin,x=this.rightPrefixMax,S=this.rightPrefixCount,C=1/0,w=-1/0,T=1/0,E=-1/0,D=1/0,O=-1/0;for(let n=e;n<t;n++){let e=u[n]*3,t=d[e],r=d[e+1],i=d[e+2];t<C&&(C=t),t>w&&(w=t),r<T&&(T=r),r>E&&(E=r),i<D&&(D=i),i>O&&(O=i)}let k=[C,T,D],A=[w,E,O];for(let n=0;n<3;n++){let s=k[n],C=A[n];if(C-s<1e-6)continue;for(let e=0;e<l;e++){g[e]=0;let t=e*3;m[t]=1/0,m[t+1]=1/0,m[t+2]=1/0,h[t]=-1/0,h[t+1]=-1/0,h[t+2]=-1/0}let w=l/(C-s);for(let r=e;r<t;r++){let e=u[r],t=d[e*3+n],i=Math.floor((t-s)*w);i>=l&&(i=l-1),g[i]++;let a=i*3,o=e*3;f[o]<m[a]&&(m[a]=f[o]),f[o+1]<m[a+1]&&(m[a+1]=f[o+1]),f[o+2]<m[a+2]&&(m[a+2]=f[o+2]),p[o]>h[a]&&(h[a]=p[o]),p[o+1]>h[a+1]&&(h[a+1]=p[o+1]),p[o+2]>h[a+2]&&(h[a+2]=p[o+2])}y[0]=g[0],_[0]=m[0],_[1]=m[1],_[2]=m[2],v[0]=h[0],v[1]=h[1],v[2]=h[2];for(let e=1;e<l;e++){let t=e*3,n=(e-1)*3;y[e]=y[e-1]+g[e];let r=_[n],i=m[t],a=_[n+1],o=m[t+1],s=_[n+2],c=m[t+2];_[t]=r<i?r:i,_[t+1]=a<o?a:o,_[t+2]=s<c?s:c;let l=v[n],u=h[t],d=v[n+1],f=h[t+1],p=v[n+2],b=h[t+2];v[t]=l>u?l:u,v[t+1]=d>f?d:f,v[t+2]=p>b?p:b}let T=l-1,E=T*3;S[T]=g[T],b[E]=m[E],b[E+1]=m[E+1],b[E+2]=m[E+2],x[E]=h[E],x[E+1]=h[E+1],x[E+2]=h[E+2];for(let e=T-1;e>=0;e--){let t=e*3,n=(e+1)*3;S[e]=S[e+1]+g[e];let r=b[n],i=m[t],a=b[n+1],o=m[t+1],s=b[n+2],c=m[t+2];b[t]=r<i?r:i,b[t+1]=a<o?a:o,b[t+2]=s<c?s:c;let l=x[n],u=h[t],d=x[n+1],f=h[t+1],p=x[n+2],_=h[t+2];x[t]=l>u?l:u,x[t+1]=d>f?d:f,x[t+2]=p>_?p:_}for(let e=1;e<l;e++){let t=(e-1)*3,u=e*3,d=y[e-1],f=S[e];if(d===0||f===0)continue;let p=v[t]-_[t],m=v[t+1]-_[t+1],h=v[t+2]-_[t+2],g=2*(p*m+m*h+h*p),w=x[u]-b[u],T=x[u+1]-b[u+1],E=x[u+2]-b[u+2],D=2*(w*T+T*E+E*w),O=this.traversalCost+g/o*d*this.intersectionCost+D/o*f*this.intersectionCost;O<r&&O<c&&(r=O,i=n,a=s+(C-s)*e/l)}}return i===-1?this.enableObjectMedianFallback?this.findObjectMedianSplit(e,t):this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`fallbacks_disabled`}:{success:!0,axis:i,pos:a,method:`SAH`,binsUsed:l}}findObjectMedianSplit(e,t){let n=this.indices,r=this.centroids,i=-1,a=-1;for(let o=0;o<3;o++){let s=1/0,c=-1/0;for(let i=e;i<t;i++){let e=r[n[i]*3+o];e<s&&(s=e),e>c&&(c=e)}let l=c-s;l>a&&(a=l,i=o)}if(i===-1||a<1e-10)return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_failed`};let o=t-e,s=e+Math.floor(o/2);this.quickselect(e,t,s,i);let c=r[n[s]*3+i],l=!0;for(let e=s+1;e<t;e++)if(r[n[e]*3+i]>c){l=!1;break}if(l){let a=-1/0;for(let t=e;t<s;t++){let e=r[n[t]*3+i];e>a&&(a=e)}if(a<c)c=(a+c)*.5;else return this.enableSpatialMedianFallback?this.findSpatialMedianSplit(e,t):{success:!1,method:`object_median_degenerate`}}return{success:!0,axis:i,pos:c,method:`object_median`}}findSpatialMedianSplit(e,t){let n=this.indices,r=this.centroids,i=this.bMin,a=this.bMax,o=-1,s=-1,c=0,l=0;for(let r=0;r<3;r++){let u=1/0,d=-1/0;for(let o=e;o<t;o++){let e=n[o]*3+r;i[e]<u&&(u=i[e]),a[e]>d&&(d=a[e])}let f=d-u;f>s&&(s=f,o=r,c=u,l=d)}if(o===-1||s<1e-12)return{success:!1,method:`spatial_median_failed`};let u=(c+l)*.5,d=t-e,f=0;for(let i=e;i<t;i++)r[n[i]*3+o]<=u&&f++;if(f===0||f===d){let i=e+Math.floor(d/2);this.quickselect(e,t,i,o);let a=r[n[i]*3+o],s=!0;for(let i=e;i<t;i++)if(r[n[i]*3+o]!==a){s=!1;break}if(s)return{success:!1,method:`spatial_median_degenerate`};let c=-1/0;for(let t=e;t<i;t++){let e=r[n[t]*3+o];e>c&&(c=e)}if(c<a)u=(c+a)*.5;else{let e=1/0;for(let a=i+1;a<t;a++){let t=r[n[a]*3+o];t<e&&(e=t)}u=(a+e)*.5}}return{success:!0,axis:o,pos:u,method:`spatial_median`}}quickselect(e,t,n,r){let i=this.indices,a=this.centroids,o=e,s=t-1;for(;o<s;){let e=o+s>>>1,t=a[i[o]*3+r],c=a[i[e]*3+r],l=a[i[s]*3+r];if(t>c){let t=i[o];i[o]=i[e],i[e]=t}if(t>l){let e=i[o];i[o]=i[s],i[s]=e}if(c>l){let t=i[e];i[e]=i[s],i[s]=t}let u=a[i[e]*3+r],d=o,f=s;for(;d<=f;){for(;a[i[d]*3+r]<u;)d++;for(;a[i[f]*3+r]>u;)f--;if(d<=f){let e=i[d];i[d]=i[f],i[f]=e,d++,f--}}f<n&&(o=d),d>n&&(s=f)}}applySAOrdering(e){if(!e||!e.leftChild)return;let t=[e],n=[];for(;t.length>0;){let e=t.pop();!e.leftChild||!e.rightChild||(n.push(e),t.push(e.leftChild),t.push(e.rightChild))}for(let e=n.length-1;e>=0;e--){let t=n[e],r=t.leftChild,i=t.rightChild,a=r.maxX-r.minX,o=r.maxY-r.minY,s=r.maxZ-r.minZ,c=i.maxX-i.minX,l=i.maxY-i.minY,u=i.maxZ-i.minZ;c*l+l*u+u*c>a*o+o*s+s*a&&(t.leftChild=i,t.rightChild=r)}}flattenBVH(e){let t=[],n=[e];for(;n.length>0;){let e=n.pop();e._flatIndex=t.length,t.push(e),e.rightChild&&n.push(e.rightChild),e.leftChild&&n.push(e.leftChild)}x(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=b(r);for(let e=0;e<t.length;e++){let n=t[e],a=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[a]=e.minX,r[a+1]=e.minY,r[a+2]=e.minZ,i[a+3]=e._flatIndex,r[a+4]=e.maxX,r[a+5]=e.maxY,r[a+6]=e.maxZ,i[a+7]=t._flatIndex,r[a+8]=t.minX,r[a+9]=t.minY,r[a+10]=t.minZ,r[a+12]=t.maxX,r[a+13]=t.maxY,r[a+14]=t.maxZ}else i[a]=n.triangleOffset,i[a+1]=n.triangleCount,i[a+3]=D}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)}x(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=b(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=O,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=D}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;x(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=b(o);o.set(e);let c=new Map;for(let e of n)c.set(e.taskId,e.flatIndex);let l=t;for(let e=0;e<i.length;e++){let t=i[e],n=t.flatData,r=t.nodeCount,a=l*16;o.set(n,a);for(let e=0;e<r;e++){let t=a+e*16;s[t+3]<D&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:n,sharedTriangleData:r,sharedCentroids:i,sharedBMin:a,sharedBMax:o,sharedIndices:s,triangleCount:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f,reinsertionConfig:p,reportProgress:m}=t.data;for(let t=0;t<n.length;t++){let h=n[t];try{let t=new M;t.maxLeafSize=l,t.numBins=u,t.maxBins=d,t.minBins=f,t.triangles=new Float32Array(r),t.centroids=new Float32Array(i),t.bMin=new Float32Array(a),t.bMax=new Float32Array(o),t.indices=new Uint32Array(s),t.totalTriangles=c,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,initTime:0,sahBuildTime:0,reorderTime:0};let n=m?e=>{self.postMessage({type:`progress`,taskId:h.taskId,progress:e})}:null,g=performance.now(),_=t.buildNodeRecursive(h.start,h.end,h.depth,n,h.preMinX,h.preMinY,h.preMinZ,h.preMaxX,h.preMaxY,h.preMaxZ);if(p&&p.enabled&&h.end-h.start>1e3){let n=new e(t.traversalCost,t.intersectionCost);p.batchSizeRatio&&n.setBatchSizeRatio(p.batchSizeRatio),p.maxIterations&&n.setMaxIterations(p.maxIterations);try{n.optimizeBVH(_,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(_);let v=t.flattenBVH(_),y=v.length/16,b=performance.now()-g;console.log(`[BVHSubtreeWorker] Task ${h.taskId}: ${(h.end-h.start).toLocaleString()} triangles, ${y} nodes, ${Math.round(b)}ms`),self.postMessage({type:`subtreeResult`,taskId:h.taskId,flatData:v,nodeCount:y},[v.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${h.taskId} error:`,e),self.postMessage({type:`error`,taskId:h.taskId,error:e.message})}}};", Uc = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Hc], { type: "text/javascript;charset=utf-8" });
1988
1988
  function Wc(e) {
1989
1989
  let t;
1990
1990
  try {
@@ -7948,7 +7948,7 @@ var Up = (e) => Math.max(0, Number(e.userData?.radius) || 0), Wp = class {
7948
7948
  }), this.areaLightCache.length > 0 && console.log(`Preprocessed ${this.areaLightCache.length} area lights by importance`), this.pointLightCache.length > 0 && console.log(`Preprocessed ${this.pointLightCache.length} point lights by importance`), this.spotLightCache.length > 0 && console.log(`Preprocessed ${this.spotLightCache.length} spot lights by importance`);
7949
7949
  }
7950
7950
  updateShaderUniforms(e) {
7951
- let t = Math.floor(this.lightData.directional.length / 12), n = Math.floor(this.lightData.rectArea.length / 16), r = Math.floor(this.lightData.point.length / 9), i = Math.floor(this.lightData.spot.length / 20);
7951
+ let t = Math.floor(this.lightData.directional.length / xn.directional), n = Math.floor(this.lightData.rectArea.length / xn.area), r = Math.floor(this.lightData.point.length / xn.point), i = Math.floor(this.lightData.spot.length / xn.spot);
7952
7952
  e.defines.MAX_DIRECTIONAL_LIGHTS = t, e.defines.MAX_AREA_LIGHTS = n, e.defines.MAX_POINT_LIGHTS = r, e.defines.MAX_SPOT_LIGHTS = i, e.uniforms.directionalLights.value = new Float32Array(this.lightData.directional), e.uniforms.areaLights.value = new Float32Array(this.lightData.rectArea), e.uniforms.pointLights.value = new Float32Array(this.lightData.point), e.uniforms.spotLights.value = new Float32Array(this.lightData.spot), e.needsUpdate = !0;
7953
7953
  }
7954
7954
  processSceneLights(e, t) {
@@ -12150,7 +12150,7 @@ var Dh = {
12150
12150
  }
12151
12151
  }, Ah = class extends Ja {
12152
12152
  constructor(e, t, n, r) {
12153
- super(e, t, n, r), this.orthographic = !1, this.orthoHalfHeight = 1;
12153
+ super(e, t > 0 && Number.isFinite(t) ? t : 1, n, r), this.orthographic = !1, this.orthoHalfHeight = 1;
12154
12154
  }
12155
12155
  get isPerspectiveCamera() {
12156
12156
  return !this.orthographic;
@@ -12396,7 +12396,7 @@ var Dh = {
12396
12396
  n.width = e.width, n.height = e.height, n.normalize = e.userData?.normalize ?? !0, n.spread = za.radToDeg(e.userData?.spread ?? Math.PI);
12397
12397
  let t = e.userData?.shape;
12398
12398
  n.shape = t === "square" || t === "rectangle" || t === "disk" || t === "ellipse" ? t : t === 1 ? "ellipse" : "rectangle";
12399
- let r = e.getWorldDirection(e.position.clone());
12399
+ let r = e.getWorldDirection(new vo()).negate();
12400
12400
  n.target = [
12401
12401
  e.position.x + r.x,
12402
12402
  e.position.y + r.y,
@@ -12768,7 +12768,7 @@ function lg(e, t, n) {
12768
12768
  }
12769
12769
  function ug(e, t, n, r) {
12770
12770
  if (e._sdf?.spilled && Ws.has(n)) {
12771
- e.ensureSceneResident().then(() => e.setMaterialProperty(t, n, r));
12771
+ e.ensureSceneResident().then(() => e.setMaterialProperty(t, n, r)).catch((t) => e._issues.warn(Gr.STORAGE_READ_FAILED, `reading the scene back for a material edit failed: ${t.message}`));
12772
12772
  return;
12773
12773
  }
12774
12774
  e.stages.pathTracer?.materialData.updateMaterialProperty(t, n, r), ["emissive", "emissiveIntensity"].includes(n) && e._sdf && e._uploadEmissivePayload(e._sdf.updateMaterialEmissive(t, n, r)), e.reset();
@@ -14231,7 +14231,7 @@ var $g = class extends ja {
14231
14231
  if (e) for (let n of t) this._addTrackedListener(e, n, (e) => this.dispatchEvent(e));
14232
14232
  }
14233
14233
  _createCamera() {
14234
- let e = new Ah(60, this.canvas.clientWidth / this.canvas.clientHeight || 1, .01, 1e3);
14234
+ let e = new Ah(60, this.canvas.clientWidth / this.canvas.clientHeight, .01, 1e3);
14235
14235
  return e.position.set(0, 0, 5), e;
14236
14236
  }
14237
14237
  _createExtraStages() {
@@ -1,3 +1,3 @@
1
1
  import { n as e, t } from "../ZipReader-D6LbMsfZ.js";
2
- import { n, t as r } from "../ArchiveImporter-CEv5EDgg.js";
2
+ import { n, t as r } from "../ArchiveImporter-Cv-MnDQa.js";
3
3
  export { r as ARCHIVE_ELEMENT_PROMPT_BYTES, n as ArchiveImporter, t as openZip, e as readZipDirectory };
@@ -1,3 +1,3 @@
1
1
  import { i as e, r as t, t as n } from "../ActiveColor-DakLCifA.js";
2
- import { A as r, C as i, D as a, E as o, F as s, I as c, M as l, N as u, O as d, P as f, S as p, T as m, _ as h, a as g, b as _, c as v, d as y, f as b, g as x, h as S, i as C, j as w, k as T, l as E, m as D, n as O, o as k, p as A, s as j, t as M, u as N, v as P, w as F, x as I, y as L } from "../ColorManagement-B6SgefNi.js";
2
+ import { A as r, C as i, D as a, E as o, F as s, I as c, M as l, N as u, O as d, P as f, S as p, T as m, _ as h, a as g, b as _, c as v, d as y, f as b, g as x, h as S, i as C, j as w, k as T, l as E, m as D, n as O, o as k, p as A, s as j, t as M, u as N, v as P, w as F, x as I, y as L } from "../ColorManagement-BSjTsrve.js";
3
3
  export { M as ColorManagement, b as DEFAULT_LUT_SIZE, A as DEFAULT_MAX_EV, D as DEFAULT_MIN_EV, n as DEFAULT_WORKING_SPACE, S as addAllOcioViews, x as addOcioView, p as applyMatrixRGBA8, L as bakeLut, h as buildCanvasView, P as buildOcioView, O as canvasColorSpaceFor, g as clearInputOverrides, i as convertColor, F as convertEncodedRGBA8, m as convertPixelsF32, w as displayCanvasFit, o as extractMatrix, l as findNativeLinearSpace, t as getActiveColorManagement, a as hasColorSpace, u as hdrViewFor, C as isColorManaged, d as isDataSpace, k as isDataTexture, f as isHdrDisplay, T as linearToSrgb, j as listFileRules, v as listInputOverrides, _ as makeCpuSampler, s as matchingView, I as measureBakeError, E as resolveInputSpace, c as sameToneMapping, e as setActiveColorManagement, N as setInputOverride, r as srgbToLinear, y as textureInputSpace };
@@ -1,3 +1,3 @@
1
1
  import { l as e, s as t } from "../FileIdentity-BXmPNvJP.js";
2
- import { a as n, c as r, i, l as a, n as o, o as s, r as c, s as l, t as u } from "../OpenStorage-CjlOYQyW.js";
2
+ import { a as n, c as r, i, l as a, n as o, o as s, r as c, s as l, t as u } from "../OpenStorage-DCvhWjxj.js";
3
3
  export { t as ENGINE_AREAS, c as EntryWriter, e as STORAGE_KIND, i as StorageArea, n as StorageEntry, s as StorageManager, r as acquireLock, u as acquireSharedStorage, a as heldLockNames, l as openInlineStorage, o as openStorage };
@@ -1,10 +1,10 @@
1
1
  import "./PackedRayBuffer-BhqeNEaL.js";
2
- import { D as e, N as t, a as n, c as r, r as i, s as a, t as o } from "./RayzeeRenderer-ClGfovbz.js";
2
+ import { D as e, N as t, a as n, c as r, r as i, s as a, t as o } from "./RayzeeRenderer-DcoDAmCU.js";
3
3
  import { i as s, n as c, r as l, t as u } from "./Logger-D7hic8LA.js";
4
4
  import { l as d, s as f } from "./TextureBuckets-CcOI4Bdg.js";
5
5
  import { f as p } from "./BufferLayout-ny3WneEc.js";
6
6
  import { i as m, n as h, r as g, t as _ } from "./EngineIssues-DHAU18xh.js";
7
- import { E as v, O as y, r as b, t as x, u as S } from "./ArchiveFormats-CWi6IbSp.js";
7
+ import { E as v, O as y, r as b, t as x, u as S } from "./ArchiveFormats-_1o7EfSy.js";
8
8
  import { n as C, t as w } from "./AssetConfig-C8BsprCp.js";
9
9
  import { d as T, p as E, t as D, u as O } from "./ViewTransforms-Bh7hSjSb.js";
10
10
  import { n as k, t as A } from "./EngineEvents-oQGofgRf.js";
package/dist/rayzee.es.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { t as e } from "./BidirectionalIntegrator-KWRQrMXX.js";
2
2
  import { Ft as t, Pt as n, Xt as r, en as i, fn as a, nt as o, rn as s, tn as c, wt as l } from "./PackedRayBuffer-BhqeNEaL.js";
3
- import { A as u, C as d, D as f, E as p, F as m, I as h, L as g, M as _, N as v, O as y, P as b, S as x, T as S, _ as ee, a as C, b as w, c as T, d as E, f as te, g as D, i as ne, j as O, k as re, l as ie, m as ae, n as oe, o as k, p as se, r as ce, s as le, t as A, u as ue, v as de, w as j, x as M, y as fe } from "./RayzeeRenderer-ClGfovbz.js";
3
+ import { A as u, C as d, D as f, E as p, F as m, I as h, L as g, M as _, N as v, O as y, P as b, S as x, T as S, _ as ee, a as C, b as w, c as T, d as E, f as te, g as D, i as ne, j as O, k as re, l as ie, m as ae, n as oe, o as k, p as se, r as ce, s as le, t as A, u as ue, v as de, w as j, x as M, y as fe } from "./RayzeeRenderer-DcoDAmCU.js";
4
4
  import { i as pe, n as me, r as N, t as he } from "./Logger-D7hic8LA.js";
5
5
  import { d as ge, f as _e, g as ve, i as ye, l as be, r as xe, u as Se, v as Ce } from "./TextureSampling-CQMmzhCp.js";
6
6
  import { c as we, d as Te, l as Ee, o as De, s as Oe, u as ke } from "./TextureBuckets-CcOI4Bdg.js";
7
7
  import { f as Ae, r as je } from "./BufferLayout-ny3WneEc.js";
8
8
  import { i as Me, n as Ne, r as Pe, t as Fe } from "./EngineIssues-DHAU18xh.js";
9
- import { E as Ie, F as Le, L as Re, O as ze, a as Be, b as Ve, d as He, f as Ue, h as We, i as Ge, r as Ke, t as qe, u as Je, x as Ye } from "./ArchiveFormats-CWi6IbSp.js";
9
+ import { E as Ie, F as Le, L as Re, O as ze, a as Be, b as Ve, d as He, f as Ue, h as We, i as Ge, r as Ke, t as qe, u as Je, x as Ye } from "./ArchiveFormats-_1o7EfSy.js";
10
10
  import { a as Xe, i as Ze, l as Qe, n as $e, r as et, s as tt } from "./FileIdentity-BXmPNvJP.js";
11
11
  import { r as nt } from "./WorkingMatrix-CDGicYGE.js";
12
12
  import { i as rt, r as it, t as at } from "./ActiveColor-DakLCifA.js";
@@ -15,10 +15,10 @@ import { a as ct, d as lt, g as ut, i as dt, l as ft, o as pt, p as mt, r as ht,
15
15
  import { n as yt, o as bt, t as P } from "./EngineEvents-oQGofgRf.js";
16
16
  import { i as xt, n as St, o as Ct, r as wt, t as Tt } from "./CameraRay-CdVb2LnS.js";
17
17
  import { t as Et } from "./ToneMapGPU-tJZo_-7S.js";
18
- import { n as Dt, t as Ot } from "./LocalExposure-CMO6fd8G.js";
18
+ import { n as Dt, t as Ot } from "./LocalExposure-hMqUG2UR.js";
19
19
  import { allFormats as kt } from "./addons/formats.es.js";
20
- import { A as At, C as jt, D as Mt, E as Nt, F as Pt, I as Ft, M as It, N as Lt, O as Rt, P as zt, S as Bt, T as Vt, _ as Ht, a as Ut, b as Wt, c as Gt, d as Kt, f as qt, g as Jt, h as Yt, i as Xt, j as Zt, k as Qt, l as $t, m as en, n as tn, o as nn, p as rn, s as an, t as on, u as sn, v as cn, w as ln, x as un, y as dn } from "./ColorManagement-B6SgefNi.js";
21
- import { c as fn, l as pn, n as mn, o as hn, t as gn } from "./OpenStorage-CjlOYQyW.js";
20
+ import { A as At, C as jt, D as Mt, E as Nt, F as Pt, I as Ft, M as It, N as Lt, O as Rt, P as zt, S as Bt, T as Vt, _ as Ht, a as Ut, b as Wt, c as Gt, d as Kt, f as qt, g as Jt, h as Yt, i as Xt, j as Zt, k as Qt, l as $t, m as en, n as tn, o as nn, p as rn, s as an, t as on, u as sn, v as cn, w as ln, x as un, y as dn } from "./ColorManagement-BSjTsrve.js";
21
+ import { c as fn, l as pn, n as mn, o as hn, t as gn } from "./OpenStorage-DCvhWjxj.js";
22
22
  import { n as _n, t as vn } from "./ZipReader-D6LbMsfZ.js";
23
23
  import { i as yn, n as bn, r as xn } from "./NeuralSuperRes-p0A3_wjO.js";
24
24
  import { i as Sn, n as Cn, r as wn } from "./NeuralRetouch-CYRGwe9E.js";
@@ -1477,7 +1477,7 @@ var ka = class extends Hn {
1477
1477
  constructor(e) {
1478
1478
  super();
1479
1479
  let t = e.clientWidth, n = e.clientHeight;
1480
- this.camera = new k(60, t / n || 1, .01, 1e3), this.camera.position.set(0, 0, 5), this.controls = new Kr(this.camera, e), this.controls.screenSpacePanning = !0, this.controls.zoomToCursor = !0, this.controls.saveState(), this._reportedOrthoHeight = null, this._reportOrthoHeight = this._reportOrthoHeight.bind(this), this.controls.addEventListener("change", this._reportOrthoHeight), this.walkControls = new Ga(this.camera, e, this.controls), this.interactionManager = null, this.cameras = [this.camera], this.currentCameraIndex = 0, this._userCameraCounter = 0, this.autoFocusMode = Ka.autoFocusMode, this.afScreenPoint = { ...Ka.afScreenPoint }, this.afSmoothingFactor = Ka.afSmoothingFactor, this._lastValidFocusDistance = null, this._smoothedFocusDistance = null, this._afPointDirty = !1, this._afSuspended = !1, this._afPick = null, this._defaultCameraState = null, this._onResize = null, this._onReset = null, this._getSettings = null, this._applySettings = null;
1480
+ this.camera = new k(60, t / n, .01, 1e3), this.camera.position.set(0, 0, 5), this.controls = new Kr(this.camera, e), this.controls.screenSpacePanning = !0, this.controls.zoomToCursor = !0, this.controls.saveState(), this._reportedOrthoHeight = null, this._reportOrthoHeight = this._reportOrthoHeight.bind(this), this.controls.addEventListener("change", this._reportOrthoHeight), this.walkControls = new Ga(this.camera, e, this.controls), this.interactionManager = null, this.cameras = [this.camera], this.currentCameraIndex = 0, this._userCameraCounter = 0, this.autoFocusMode = Ka.autoFocusMode, this.afScreenPoint = { ...Ka.afScreenPoint }, this.afSmoothingFactor = Ka.afSmoothingFactor, this._lastValidFocusDistance = null, this._smoothedFocusDistance = null, this._afPointDirty = !1, this._afSuspended = !1, this._afPick = null, this._defaultCameraState = null, this._onResize = null, this._onReset = null, this._getSettings = null, this._applySettings = null;
1481
1481
  }
1482
1482
  setCameras(e) {
1483
1483
  this.cameras = e, this._userCameraCounter = 0, this.camera.userData.clipStart = 0, this.resetAutoFocus();
@@ -2488,23 +2488,18 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
2488
2488
  }, this.config = {
2489
2489
  ...ko.DEFAULT_OPTIONS,
2490
2490
  ...t
2491
- }, this.enabled = this.config.enableOIDN, this.quality = this.config.oidnQuality, this.maxTileSize = this.config.tileSize, this._activeTileSize = 0, this.state = {
2491
+ }, this._enabled = this.config.enableOIDN, this.quality = this.config.oidnQuality, this.maxTileSize = this.config.tileSize, this._activeTileSize = 0, this.state = {
2492
2492
  isDenoising: !1,
2493
2493
  isLoading: !1,
2494
2494
  abortController: null
2495
- }, this._tilesWritten = 0, this._runId = 0, this._hasOutput = !1, this.lastDenoiseMs = 0, this.currentTZAUrl = null, this.unet = null, this._weights = /* @__PURE__ */ new Map(), this._pendingStart = !1, this._pendingStartContinuous = !1, this._reloadPending = !1, this._initialize().catch((e) => {
2496
- bo.error("init failed:", e), this.dispatchEvent({
2497
- type: "error",
2498
- error: e
2499
- });
2500
- });
2495
+ }, this._tilesWritten = 0, this._runId = 0, this._hasOutput = !1, this.lastDenoiseMs = 0, this.currentTZAUrl = null, this.unet = null, this._weights = /* @__PURE__ */ new Map(), this._pendingStart = !1, this._pendingStartContinuous = !1, this._reloadPending = !1, this._enabled && this._setupUNetDenoiser();
2501
2496
  }
2502
- async _initialize() {
2503
- try {
2504
- await this._setupUNetDenoiser();
2505
- } catch (e) {
2506
- throw Error(`Initialization failed: ${e.message}`);
2507
- }
2497
+ get enabled() {
2498
+ return this._enabled;
2499
+ }
2500
+ set enabled(e) {
2501
+ let t = !!e && !this._enabled;
2502
+ this._enabled = !!e, t && this._setupUNetDenoiser();
2508
2503
  }
2509
2504
  expectsCleanAux(e = this.quality) {
2510
2505
  let { QUALITY_MODELS: t } = ko;
@@ -2526,7 +2521,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
2526
2521
  return i <= r.width * r.height && i <= Co ? Math.max(n.width, n.height) : t;
2527
2522
  }
2528
2523
  _setupUNetDenoiser() {
2529
- return this.state.isLoading ? (this._reloadPending = !0, Promise.resolve()) : (this._loading = this._loadUNet(), this._loading);
2524
+ return this._enabled ? this.state.isLoading ? (this._reloadPending = !0, Promise.resolve()) : (this._loading = this._loadUNet(), this._loading) : Promise.resolve();
2530
2525
  }
2531
2526
  whenLoaded() {
2532
2527
  return this.state.isLoading ? this._loading : Promise.resolve();
@@ -5174,7 +5169,7 @@ var Qs = N("engine"), $s = class extends A {
5174
5169
  }), this.cameraManager.camera;
5175
5170
  }
5176
5171
  _initAssetPipeline() {
5177
- super._initAssetPipeline(), this.assetLoader.controls = this.cameraManager.controls, this.assetLoader.registerFormat(...kt), this.assetLoader.setArchiveImporterLoader(() => import("./ArchiveImporter-CEv5EDgg.js").then((e) => e.r).then((e) => new e.ArchiveImporter(this.assetLoader)), qe);
5172
+ super._initAssetPipeline(), this.assetLoader.controls = this.cameraManager.controls, this.assetLoader.registerFormat(...kt), this.assetLoader.setArchiveImporterLoader(() => import("./ArchiveImporter-Cv-MnDQa.js").then((e) => e.r).then((e) => new e.ArchiveImporter(this.assetLoader)), qe);
5178
5173
  let e = () => {
5179
5174
  this.needsReset = !0, this.stages.pathTracer?.enterInteractionMode(), this.wake();
5180
5175
  };
@@ -5320,7 +5315,7 @@ var Qs = N("engine"), $s = class extends A {
5320
5315
  this.stages.localExposure?.updateParameters(e);
5321
5316
  }
5322
5317
  async createPictureView(e) {
5323
- let { PictureView: t } = await import("./PictureView-6y4XsUf0.js");
5318
+ let { PictureView: t } = await import("./PictureView-DlQVw7W9.js");
5324
5319
  return new t({
5325
5320
  color: this.color,
5326
5321
  device: this.renderer.backend.device