rayzee 9.3.2 → 9.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rayzee.es.js CHANGED
@@ -1,6 +1,6 @@
1
- import { a as e, i as t, n, o as r, r as i } from "./NeuralSuperRes-PkgDLQcD.js";
2
- import { C as a, E as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, l as v, m as y, n as b, o as x, p as S, r as C, s as w, t as T, u as E, v as D, w as O, x as k, y as A } from "./ToneMapGPU-B6XIe3DU.js";
3
- import { i as ee, n as te, r as j } from "./NeuralRetouch-CYgkQY8Z.js";
1
+ import { a as e, i as t, n, o as r, r as i } from "./NeuralSuperRes-FVqRJKQV.js";
2
+ import { C as a, E as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, l as v, m as y, n as b, o as x, p as S, r as C, s as w, t as T, u as E, v as D, w as O, x as k, y as A } from "./ToneMapGPU-DKQM1pMd.js";
3
+ import { i as ee, n as te, r as j } from "./NeuralRetouch-vkdXXyK2.js";
4
4
  import { ContextNode as ne, ExternalTexture as re, LinearSRGBColorSpace as ie, MeshBasicNodeMaterial as ae, NodeMaterial as oe, QuadMesh as se, ReadbackBuffer as ce, RectAreaLightNode as le, RenderTarget as ue, SRGBColorSpace as de, StorageInstancedBufferAttribute as fe, StorageTexture as pe, TextureNode as me, WebGPUBackend as he, WebGPURenderer as ge } from "three/webgpu";
5
5
  import { Break as _e, Fn as M, If as N, Loop as ve, Return as ye, TWO_PI as be, abs as xe, acos as Se, array as Ce, asin as we, atan as Te, atomicAdd as Ee, atomicLoad as De, atomicStore as Oe, attributeArray as ke, bool as Ae, clamp as P, cos as je, cross as Me, cubeTexture as Ne, dot as F, exp as Pe, exp2 as Fe, float as I, floatBitsToUint as Ie, floor as Le, fract as Re, instanceIndex as ze, int as L, ivec2 as Be, ivec3 as Ve, length as He, lessThan as Ue, localId as R, log as We, log2 as Ge, mat3 as Ke, max as z, min as qe, mix as B, normalize as V, notEqual as Je, packHalf2x16 as Ye, packSnorm2x16 as Xe, packUnorm2x16 as Ze, pow as Qe, reflect as $e, refract as et, round as tt, sampler as nt, saturate as rt, screenCoordinate as it, select as H, sign as at, sin as ot, smoothstep as st, sqrt as U, step as ct, storage as lt, struct as ut, subgroupAdd as dt, subgroupBroadcast as ft, subgroupExclusiveAdd as pt, tan as mt, texture as ht, texture3DLoad as gt, textureLoad as W, textureSize as _t, textureStore as vt, uint as G, uintBitsToFloat as yt, uniform as K, uniformArray as bt, unpackHalf2x16 as q, unpackSnorm2x16 as xt, unpackUnorm2x16 as St, uv as Ct, uvec2 as wt, uvec4 as Tt, vec2 as J, vec3 as Y, vec4 as X, wgslFn as Et, workgroupArray as Dt, workgroupBarrier as Ot, workgroupId as kt } from "three/tsl";
6
6
  import { ACESFilmicToneMapping as At, AddEquation as jt, AnimationClip as Mt, AnimationMixer as Nt, BackSide as Pt, BooleanKeyframeTrack as Ft, Box2 as It, Box3 as Lt, BufferAttribute as Rt, BufferGeometry as zt, ByteType as Bt, CircleGeometry as Vt, ClampToEdgeWrapping as Ht, Color as Ut, Controls as Wt, CustomBlending as Gt, Data3DTexture as Kt, DataArrayTexture as qt, DataTexture as Jt, DataUtils as Yt, DirectionalLight as Xt, DirectionalLightHelper as Zt, DoubleSide as Qt, EquirectangularReflectionMapping as $t, EventDispatcher as en, Float32BufferAttribute as tn, FloatType as nn, FrontSide as rn, Group as an, HalfFloatType as on, InstancedBufferAttribute as sn, InstancedMesh as cn, IntType as ln, InterpolateSmooth as un, LinearFilter as Z, LinearSRGBColorSpace as dn, LoaderUtils as fn, LoadingManager as pn, LoopOnce as mn, LoopRepeat as hn, MaterialLoader as gn, MathUtils as _n, Matrix3 as vn, Matrix4 as yn, Mesh as bn, MeshBasicMaterial as xn, MeshPhysicalMaterial as Sn, MeshStandardMaterial as Cn, NearestFilter as wn, NoBlending as Tn, NoColorSpace as En, NoToneMapping as Dn, NumberKeyframeTrack as On, Object3D as kn, OneFactor as An, OrthographicCamera as jn, PerspectiveCamera as Mn, PointLight as Nn, PointLightHelper as Pn, Points as Fn, PointsMaterial as In, PropertyBinding as Ln, Quaternion as Rn, QuaternionKeyframeTrack as zn, REVISION as Bn, RGBAFormat as Vn, RGBFormat as Hn, RGFormat as Un, Raycaster as Wn, RectAreaLight as Gn, RedFormat as Kn, RedIntegerFormat as qn, RenderTarget as Jn, RepeatWrapping as Yn, SRGBColorSpace as Xn, Scene as Zn, ShortType as Qn, SphereGeometry as $n, SpotLight as er, SpotLightHelper as tr, Texture as nr, TextureLoader as rr, Timer as ir, Uint32BufferAttribute as ar, UnsignedByteType as or, UnsignedIntType as sr, UnsignedShortType as cr, Vector2 as lr, Vector3 as ur, Vector4 as dr, VectorKeyframeTrack as fr } from "three";
@@ -26863,7 +26863,15 @@ function Kg(e, t, n, r, i) {
26863
26863
  r[i] = c, r[i + 1] = l, r[i + 2] = u, r[i + 3] = d, r[i + 4] = f, r[i + 5] = p;
26864
26864
  }
26865
26865
  var qg = new Float32Array(12);
26866
- function Jg(e, t, n, r, i) {
26866
+ function Jg(e, t, n, r) {
26867
+ let i = Ig(e, t), a = Lg(e, t), o = Rg(e, t);
26868
+ if (a[o + 3] === Hg) {
26869
+ Kg(n, a[o], a[o + 1], r, 0);
26870
+ return;
26871
+ }
26872
+ for (let e = 0; e < 3; e++) r[e] = Math.min(i[o + e], i[o + 8 + e]), r[3 + e] = Math.max(i[o + 4 + e], i[o + 12 + e]);
26873
+ }
26874
+ function Yg(e, t, n, r, i) {
26867
26875
  let a = Ig(e, t), o = Lg(e, t), s = Rg(e, t), c = (t - i) * 6, l = o[s + 3];
26868
26876
  if (l === Hg) {
26869
26877
  Kg(n, o[s], o[s + 1], r, c);
@@ -26879,9 +26887,9 @@ function Jg(e, t, n, r, i) {
26879
26887
  dg(u) && (Kg(n, fg(u), pg(u), qg, 6), p = qg, m = 6), a[s] = d[f], a[s + 1] = d[f + 1], a[s + 2] = d[f + 2], a[s + 4] = d[f + 3], a[s + 5] = d[f + 4], a[s + 6] = d[f + 5], a[s + 8] = p[m], a[s + 9] = p[m + 1], a[s + 10] = p[m + 2], a[s + 12] = p[m + 3], a[s + 13] = p[m + 4], a[s + 14] = p[m + 5];
26880
26888
  for (let e = 0; e < 3; e++) r[c + e] = Math.min(d[f + e], p[m + e]), r[c + 3 + e] = Math.max(d[f + 3 + e], p[m + 3 + e]);
26881
26889
  }
26882
- var Yg = class {
26890
+ var Xg = class {
26883
26891
  constructor() {
26884
- this._bounds = null, this._boundsNodeCount = 0;
26892
+ this._bounds = null, this._boundsNodeCount = 0, this._tlasBounds = null, this._rootBox = null;
26885
26893
  }
26886
26894
  updateTrianglePositions(e, t, n) {
26887
26895
  let r = n.length, i = zg(e);
@@ -26896,19 +26904,29 @@ var Yg = class {
26896
26904
  let i = zg(t);
26897
26905
  r > this._boundsNodeCount && (this._bounds = new Float32Array(r * 6), this._boundsNodeCount = r);
26898
26906
  let a = Fg(e);
26899
- for (let e = n + r - 1; e >= n; e--) Jg(a, e, i, this._bounds, n);
26907
+ for (let e = n + r - 1; e >= n; e--) Yg(a, e, i, this._bounds, n);
26908
+ }
26909
+ refitPartial(e, t, n, r) {
26910
+ for (let r = 0; r < n.length; r += 2) this.refitRange(e, t, n[r], n[r + 1]);
26911
+ let i = zg(t), a = Fg(e);
26912
+ (!this._tlasBounds || this._tlasBounds.length < r * 6) && (this._tlasBounds = new Float32Array(r * 6));
26913
+ let o = this._tlasBounds, s = this._rootBox ||= new Float32Array(6);
26914
+ for (let e = r - 1; e >= 0; e--) {
26915
+ let t = Lg(a, e), n = Rg(a, e);
26916
+ t[n + 3] === Ug ? (Jg(a, t[n], i, s), Gg(Ig(a, e), n, s, 0, o, e * 6)) : Yg(a, e, i, o, 0);
26917
+ }
26900
26918
  }
26901
26919
  refit(e, t, n) {
26902
26920
  let r = zg(t);
26903
26921
  n !== this._boundsNodeCount && (this._bounds = new Float32Array(n * 6), this._boundsNodeCount = n);
26904
26922
  let i = Fg(e);
26905
- for (let e = n - 1; e >= 0; e--) Jg(i, e, r, this._bounds, 0);
26923
+ for (let e = n - 1; e >= 0; e--) Yg(i, e, r, this._bounds, 0);
26906
26924
  }
26907
- }, Xg = "var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}function b(e){e&&e in r&&(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e])}const x=1073741824,S=(e,t)=>~(e<<4|t)>>>0;function C(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]===1073741824&&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]>=x||(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]>=x)&&(l[s+3]=w(t,t[o+3],r,i),l[s+7]=w(t,t[o+7],r,i))}return c}function w(e,t,n,r){let i=t*16;return n(t)?S(e[i],e[i+1]):r[t]}const T=y(`bvh`),E=1073741824,D=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),O=1073741824;function k(e,t){if(e>=O)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${O}`);return e}const A={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},j=A.FLOATS_PER_TRIANGLE,M=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var N=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}},P=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,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=M(this.triangles),n=A.POSITION_A_OFFSET,r=A.POSITION_B_OFFSET,i=A.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*j,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/(j*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?C(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(j*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){T.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){T.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*j);for(let e=0;e<s;e++){let t=this.indices[e]*j,n=e*j;m.set(p.subarray(t,t+j),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return T.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new N;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 N;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)}k(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=D(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]=E}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)}k(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=D(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=E}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;k(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=D(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]<E&&(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 F=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?I(t):n===`assemble`?L(t):R(t)};function I(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u,treeletOptimization:d}=e;try{let e=new P;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let p=performance.now(),m=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-m,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let h=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,f);e.splitStats.sahBuildTime=performance.now()-h,e.applySAOrdering(g);let v=performance.now(),{flatData:y,frontierMap:b,nodeCount:x}=e.flattenBVHWithFrontier(g),S=performance.now()-v,C=performance.now()-p;F.debug(`phase 1 ${_.ms(C)} (init ${_.ms(e.splitStats.initTime)} · morton ${_.ms(e.splitStats.mortonSortTime)} · SAH ${_.ms(e.splitStats.sahBuildTime)} · flatten ${_.ms(S)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:y,topNodeCount:x,frontierTasks:e.frontierTasks,frontierMap:b,splitStats:e.splitStats},[y.buffer])}catch(e){F.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function L(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 P().assembleParallelBVH(t,n,r,i),d=l?C(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;F.debug(`phase 3 assemble + reorder ${_.ms(m)} (${_.mb(d.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:d,originalToBvh:p,triangleCount:c},[d.buffer,p.buffer])}catch(e){F.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function R(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,treeletOptimization:o,reinsertionOptimization:s,sharedReorderBuffer:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f,foldLeaves:p}=e,m=new P;l!==void 0&&(m.maxLeafSize=l),u!==void 0&&(m.numBins=u),d!==void 0&&(m.maxBins=d),f!==void 0&&(m.minBins=f);try{o&&m.setTreeletConfig(o),s&&m.setReinsertionConfig(s);let e=a?e=>{self.postMessage({progress:e})}:null,l=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),u=c?new Uint32Array(c):null,d=m.buildSync(l,i,e,u),f=performance.now(),h=m.flattenBVH(d),g=p?C(h):h,v=performance.now()-f;F.debug(`flatten ${_.ms(v)} (${_.mb(g.byteLength)})`);let y=m.originalToBvhMap||null;if(c){let e=[g.buffer];y&&e.push(y.buffer),self.postMessage({bvhData:g,originalToBvh:y,triangleCount:l.length/20,treeletStats:m.splitStats},e)}else{let e=m.reorderedTriangleData,t=e.byteLength/80,n=[g.buffer,e.buffer];y&&n.push(y.buffer),self.postMessage({bvhData:g,triangles:e,originalToBvh:y,triangleCount:t,treeletStats:m.splitStats},n)}}catch(e){F.error(`build failed:`,e),self.postMessage({error:e.message})}}", Zg = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Xg], { type: "text/javascript;charset=utf-8" });
26908
- function Qg(e) {
26925
+ }, Zg = "var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}function b(e){e&&e in r&&(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e])}const x=1073741824,S=(e,t)=>~(e<<4|t)>>>0;function C(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]===1073741824&&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]>=x||(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]>=x)&&(l[s+3]=w(t,t[o+3],r,i),l[s+7]=w(t,t[o+7],r,i))}return c}function w(e,t,n,r){let i=t*16;return n(t)?S(e[i],e[i+1]):r[t]}const T=y(`bvh`),E=1073741824,D=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),O=1073741824;function k(e,t){if(e>=O)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${O}`);return e}const A={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},j=A.FLOATS_PER_TRIANGLE,M=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length);var N=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}},P=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,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=M(this.triangles),n=A.POSITION_A_OFFSET,r=A.POSITION_B_OFFSET,i=A.POSITION_C_OFFSET;for(let a=0;a<e;a++){let e=a*j,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/(j*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?C(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(j*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){T.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){T.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*j);for(let e=0;e<s;e++){let t=this.indices[e]*j,n=e*j;m.set(p.subarray(t,t+j),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return T.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new N;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 N;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)}k(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=D(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]=E}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)}k(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=D(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=E}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;k(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=D(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]<E&&(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 F=y(`bvh`);self.onmessage=function(e){let t=e.data,n=t.type;b(t.logLevel),n===`buildPhase1`?I(t):n===`assemble`?L(t):R(t)};function I(e){let{sharedTriangleData:t,sharedCentroids:n,sharedBMin:r,sharedBMax:i,sharedIndices:a,sharedMortonCodes:o,triangleCount:s,depth:c,parallelDepth:l,reportProgress:u,treeletOptimization:d}=e;try{let e=new P;d&&e.setTreeletConfig(d);let f=u?e=>{self.postMessage({type:`progress`,progress:e})}:null;e.triangles=new Uint32Array(t),e.centroids=new Float32Array(n),e.bMin=new Float32Array(r),e.bMax=new Float32Array(i),e.indices=new Uint32Array(a),e.mortonCodes=new Uint32Array(o),e.totalTriangles=s,e.totalNodes=0,e.processedTriangles=0,e.lastProgressUpdate=performance.now(),e.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let p=performance.now(),m=performance.now();e.initializeTriangleArrays(),e.splitStats.initTime=performance.now()-m,e.sortTrianglesByMortonCode(),e.frontierTasks=[];let h=performance.now(),g=e.buildNodeRecursiveToDepth(0,s,c,l,f);e.splitStats.sahBuildTime=performance.now()-h,e.applySAOrdering(g);let v=performance.now(),{flatData:y,frontierMap:b,nodeCount:x}=e.flattenBVHWithFrontier(g),S=performance.now()-v,C=performance.now()-p;F.debug(`phase 1 ${_.ms(C)} (init ${_.ms(e.splitStats.initTime)} · morton ${_.ms(e.splitStats.mortonSortTime)} · SAH ${_.ms(e.splitStats.sahBuildTime)} · flatten ${_.ms(S)}) · ${e.frontierTasks.length} frontier tasks`),self.postMessage({type:`phase1Result`,topFlatData:y,topNodeCount:x,frontierTasks:e.frontierTasks,frontierMap:b,splitStats:e.splitStats},[y.buffer])}catch(e){F.error(`phase 1 failed:`,e),self.postMessage({type:`error`,error:e.message})}}function L(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 P().assembleParallelBVH(t,n,r,i),d=l?C(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;F.debug(`phase 3 assemble + reorder ${_.ms(m)} (${_.mb(d.byteLength)} BVH)`),self.postMessage({type:`assembleResult`,bvhData:d,originalToBvh:p,triangleCount:c},[d.buffer,p.buffer])}catch(e){F.error(`assembly failed:`,e),self.postMessage({type:`error`,error:e.message})}}function R(e){let{triangleData:t,triangleByteOffset:n,triangleByteLength:r,depth:i,reportProgress:a,treeletOptimization:o,reinsertionOptimization:s,sharedReorderBuffer:c,maxLeafSize:l,numBins:u,maxBins:d,minBins:f,foldLeaves:p}=e,m=new P;l!==void 0&&(m.maxLeafSize=l),u!==void 0&&(m.numBins=u),d!==void 0&&(m.maxBins=d),f!==void 0&&(m.minBins=f);try{o&&m.setTreeletConfig(o),s&&m.setReinsertionConfig(s);let e=a?e=>{self.postMessage({progress:e})}:null,l=n===void 0?new Uint32Array(t):new Uint32Array(t,n,r/4),u=c?new Uint32Array(c):null,d=m.buildSync(l,i,e,u),f=performance.now(),h=m.flattenBVH(d),g=p?C(h):h,v=performance.now()-f;F.debug(`flatten ${_.ms(v)} (${_.mb(g.byteLength)})`);let y=m.originalToBvhMap||null;if(c){let e=[g.buffer];y&&e.push(y.buffer),self.postMessage({bvhData:g,originalToBvh:y,triangleCount:l.length/20,treeletStats:m.splitStats},e)}else{let e=m.reorderedTriangleData,t=e.byteLength/80,n=[g.buffer,e.buffer];y&&n.push(y.buffer),self.postMessage({bvhData:g,triangles:e,originalToBvh:y,triangleCount:t,treeletStats:m.splitStats},n)}}catch(e){F.error(`build failed:`,e),self.postMessage({error:e.message})}}", Qg = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Zg], { type: "text/javascript;charset=utf-8" });
26926
+ function $g(e) {
26909
26927
  let t;
26910
26928
  try {
26911
- if (t = Zg && (self.URL || self.webkitURL).createObjectURL(Zg), !t) throw "";
26929
+ if (t = Qg && (self.URL || self.webkitURL).createObjectURL(Qg), !t) throw "";
26912
26930
  let n = new Worker(t, {
26913
26931
  type: "module",
26914
26932
  name: e?.name
@@ -26917,7 +26935,7 @@ function Qg(e) {
26917
26935
  (self.URL || self.webkitURL).revokeObjectURL(t);
26918
26936
  }), n;
26919
26937
  } catch {
26920
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(Xg), {
26938
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(Zg), {
26921
26939
  type: "module",
26922
26940
  name: e?.name
26923
26941
  });
@@ -26925,11 +26943,11 @@ function Qg(e) {
26925
26943
  }
26926
26944
  //#endregion
26927
26945
  //#region src/Processor/Workers/BVHSubtreeWorker.js?worker&inline
26928
- var $g = "var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}const b=1073741824,x=(e,t)=>~(e<<4|t)>>>0;function S(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]===1073741824&&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]>=b||(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]>=b)&&(l[s+3]=C(t,t[o+3],r,i),l[s+7]=C(t,t[o+7],r,i))}return c}function C(e,t,n,r){let i=t*16;return n(t)?x(e[i],e[i+1]):r[t]}const w=y(`bvh`),T=1073741824,E=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),D=1073741824;function O(e,t){if(e>=D)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${D}`);return e}const k={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},A=k.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,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=j(this.triangles),n=k.POSITION_A_OFFSET,r=k.POSITION_B_OFFSET,i=k.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?S(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(A*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){w.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){w.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*A);for(let e=0;e<s;e++){let t=this.indices[e]*A,n=e*A;m.set(p.subarray(t,t+A),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return w.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new 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)}O(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=E(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]=T}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)}O(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=E(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=T}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;O(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=E(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]<T&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:r,sharedTriangleData:i,sharedCentroids:a,sharedBMin:o,sharedBMax:s,sharedIndices:c,triangleCount:l,maxLeafSize:u,numBins:d,maxBins:f,minBins:p,treeletConfig:m,reinsertionConfig:h,reportProgress:g}=t.data;for(let t=0;t<r.length;t++){let _=r[t];try{let t=new N;t.maxLeafSize=u,t.numBins=d,t.maxBins=f,t.minBins=p,t.triangles=new Float32Array(i),t.centroids=new Float32Array(a),t.bMin=new Float32Array(o),t.bMax=new Float32Array(s),t.indices=new Uint32Array(c),t.totalTriangles=l,t.totalNodes=0,t.processedTriangles=0,t.lastProgressUpdate=performance.now(),t.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let r=g?e=>{self.postMessage({type:`progress`,taskId:_.taskId,progress:e})}:null,v=performance.now(),y=t.buildNodeRecursive(_.start,_.end,_.depth,r,_.preMinX,_.preMinY,_.preMinZ,_.preMaxX,_.preMaxY,_.preMaxZ);if(m&&m.enabled&&_.end-_.start>1e3){let n=_.end-_.start>5e4,r=n?3:m.size||5,i=n?10:20,a=new e(t.traversalCost,t.intersectionCost);a.setTreeletSize(r),a.setMinImprovement(m.minImprovement||.02),a.setMaxTreelets(i);let o=m.passes||1;for(let e=0;e<o;e++)try{a.optimizeBVH(y,null)}catch(t){console.error(`[BVHSubtreeWorker] Treelet pass ${e+1} error:`,t);break}}if(h&&h.enabled&&_.end-_.start>1e3){let e=new n(t.traversalCost,t.intersectionCost);h.batchSizeRatio&&e.setBatchSizeRatio(h.batchSizeRatio),h.maxIterations&&e.setMaxIterations(h.maxIterations);try{e.optimizeBVH(y,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(y);let b=t.flattenBVH(y),x=b.length/16,S=performance.now()-v;console.log(`[BVHSubtreeWorker] Task ${_.taskId}: ${(_.end-_.start).toLocaleString()} triangles, ${x} nodes, ${Math.round(S)}ms`),self.postMessage({type:`subtreeResult`,taskId:_.taskId,flatData:b,nodeCount:x},[b.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${_.taskId} error:`,e),self.postMessage({type:`error`,taskId:_.taskId,error:e.message})}}};", e_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", $g], { type: "text/javascript;charset=utf-8" });
26929
- function t_(e) {
26946
+ var e_ = "var e=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.maxTreeletLeaves=7,this.minImprovement=.02,this.topologyCache=new Map;for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.set(e,this.generateTopologies(e));this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0}}generateTopologies(e){if(e===1)return[0];if(e===2)return[[0,1]];let t=[];for(let n=1;n<e;n++){let r=this.generateTopologies(n),i=this.generateTopologies(e-n);for(let e of r)for(let r of i)t.push([e,this.offsetTopology(r,n)])}return t}offsetTopology(e,t){return typeof e==`number`?e+t:[this.offsetTopology(e[0],t),this.offsetTopology(e[1],t)]}optimizeBVH(e){let t=performance.now();this.stats={treeletsProcessed:0,treeletsImproved:0,totalSAHImprovement:0,averageSAHImprovement:0,optimizationTime:0};let n=this.identifyTreeletRoots(e);for(let e=0;e<n.length;e++){if(performance.now()-t>3e4){console.warn(`TreeletOptimizer: timeout after ${e}/${n.length} treelets`);break}this.optimizeTreelet(n[e])}return this.stats.optimizationTime=performance.now()-t,this.stats.averageSAHImprovement=this.stats.treeletsProcessed>0?this.stats.totalSAHImprovement/this.stats.treeletsProcessed:0,e}identifyTreeletRoots(e){let t=[],n=new Set,r=[{node:e,visited:!1}];for(;r.length>0;){let e=r[r.length-1];if(e.visited){r.pop();let i=e.node;if(i.triangleCount>0||n.has(i))continue;let a=this.countLeaves(i);a>=3&&a<=this.maxTreeletLeaves&&(t.push(i),this.markSubtree(i,n))}else{e.visited=!0;let t=e.node;if(t.triangleCount>0)continue;t.rightChild&&r.push({node:t.rightChild,visited:!1}),t.leftChild&&r.push({node:t.leftChild,visited:!1})}}return t}countLeaves(e){return e?e.triangleCount>0?1:this.countLeaves(e.leftChild)+this.countLeaves(e.rightChild):0}markSubtree(e,t){e&&(t.add(e),!(e.triangleCount>0)&&(this.markSubtree(e.leftChild,t),this.markSubtree(e.rightChild,t)))}optimizeTreelet(e){let t=[];this.extractLeaves(e,t);let n=t.length;if(n<3||n>this.maxTreeletLeaves)return;this.stats.treeletsProcessed++;let r=this.evaluateSubtreeSAH(e),i=this.topologyCache.get(n);if(!i||i.length===0)return;let a=r,o=null,s=null;if(n<=5){let e=this.generatePermutations(n);for(let n of i)for(let r of e){let e=this.evaluateTopology(n,t,r);e<a&&(a=e,o=n,s=r)}}else{let e=Array.from({length:n},(e,t)=>t);for(let n of i){let r=this.evaluateTopology(n,t,e);r<a&&(a=r,o=n,s=e);let i=this.greedySwapOptimize(n,t,e,r);i.cost<a&&(a=i.cost,o=n,s=i.perm)}}let c=(r-a)/r;o&&c>this.minImprovement&&(this.reconstructTreelet(e,o,t,s),this.stats.treeletsImproved++,this.stats.totalSAHImprovement+=c)}extractLeaves(e,t){if(e){if(e.triangleCount>0){t.push({minX:e.minX,minY:e.minY,minZ:e.minZ,maxX:e.maxX,maxY:e.maxY,maxZ:e.maxZ,triangleOffset:e.triangleOffset,triangleCount:e.triangleCount});return}this.extractLeaves(e.leftChild,t),this.extractLeaves(e.rightChild,t)}}evaluateSubtreeSAH(e){if(!e)return 0;if(e.triangleCount>0)return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*e.triangleCount*this.intersectionCost;let t=this.evaluateSubtreeSAH(e.leftChild),n=this.evaluateSubtreeSAH(e.rightChild);return this.surfaceAreaFlat(e.minX,e.minY,e.minZ,e.maxX,e.maxY,e.maxZ)*this.traversalCost+t+n}evaluateTopology(e,t,n){return this.evalTopoRecursive(e,t,n).cost}evalTopoRecursive(e,t,n){if(typeof e==`number`){let r=t[n[e]];return{cost:this.surfaceAreaFlat(r.minX,r.minY,r.minZ,r.maxX,r.maxY,r.maxZ)*r.triangleCount*this.intersectionCost,minX:r.minX,minY:r.minY,minZ:r.minZ,maxX:r.maxX,maxY:r.maxY,maxZ:r.maxZ}}let r=this.evalTopoRecursive(e[0],t,n),i=this.evalTopoRecursive(e[1],t,n),a=Math.min(r.minX,i.minX),o=Math.min(r.minY,i.minY),s=Math.min(r.minZ,i.minZ),c=Math.max(r.maxX,i.maxX),l=Math.max(r.maxY,i.maxY),u=Math.max(r.maxZ,i.maxZ);return{cost:this.surfaceAreaFlat(a,o,s,c,l,u)*this.traversalCost+r.cost+i.cost,minX:a,minY:o,minZ:s,maxX:c,maxY:l,maxZ:u}}surfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}generatePermutations(e){let t=[],n=Array.from({length:e},(e,t)=>t),r=i=>{if(i===e){t.push([...n]);return}for(let t=i;t<e;t++)[n[i],n[t]]=[n[t],n[i]],r(i+1),[n[i],n[t]]=[n[t],n[i]]};return r(0),t}greedySwapOptimize(e,t,n,r){let i=[...n],a=r,o=!0;for(;o;){o=!1;for(let n=0;n<i.length-1;n++)for(let r=n+1;r<i.length;r++){[i[n],i[r]]=[i[r],i[n]];let s=this.evaluateTopology(e,t,i);s<a?(a=s,o=!0):[i[n],i[r]]=[i[r],i[n]]}}return{perm:i,cost:a}}reconstructTreelet(e,t,n,r){let i=this.buildSubtree(t,n,r);e.minX=i.minX,e.minY=i.minY,e.minZ=i.minZ,e.maxX=i.maxX,e.maxY=i.maxY,e.maxZ=i.maxZ,e.leftChild=i.leftChild,e.rightChild=i.rightChild,e.triangleOffset=i.triangleOffset,e.triangleCount=i.triangleCount}buildSubtree(e,n,r){if(typeof e==`number`){let i=n[r[e]],a=new t;return a.minX=i.minX,a.minY=i.minY,a.minZ=i.minZ,a.maxX=i.maxX,a.maxY=i.maxY,a.maxZ=i.maxZ,a.triangleOffset=i.triangleOffset,a.triangleCount=i.triangleCount,a}let i=this.buildSubtree(e[0],n,r),a=this.buildSubtree(e[1],n,r),o=new t;return o.leftChild=i,o.rightChild=a,o.minX=Math.min(i.minX,a.minX),o.minY=Math.min(i.minY,a.minY),o.minZ=Math.min(i.minZ,a.minZ),o.maxX=Math.max(i.maxX,a.maxX),o.maxY=Math.max(i.maxY,a.maxY),o.maxZ=Math.max(i.maxZ,a.maxZ),o}setTreeletSize(e){this.maxTreeletLeaves=Math.max(3,Math.min(7,e));for(let e=3;e<=this.maxTreeletLeaves;e++)this.topologyCache.has(e)||this.topologyCache.set(e,this.generateTopologies(e))}setMinImprovement(e){this.minImprovement=Math.max(.001,e)}getStatistics(){return{...this.stats}}},t=class{constructor(){this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0,this.leftChild=null,this.rightChild=null,this.triangleOffset=0,this.triangleCount=0}},n=class{constructor(e,t){this.traversalCost=e,this.intersectionCost=t,this.batchSizeRatio=.02,this.maxIterations=2,this.timeBudgetMs=15e3,this.stats={reinsertionsApplied:0,iterations:0,timeMs:0}}setBatchSizeRatio(e){this.batchSizeRatio=Math.max(.005,Math.min(.1,e))}setMaxIterations(e){this.maxIterations=Math.max(1,Math.min(5,e))}getStatistics(){return{...this.stats}}surfaceArea(e){let t=e.maxX-e.minX,n=e.maxY-e.minY,r=e.maxZ-e.minZ;return t*n+n*r+r*t}buildParentMap(e){let t=new Map;t.set(e,{parent:null,isLeft:!1});let n=[e];for(;n.length>0;){let e=n.pop();e.triangleCount>0||(e.leftChild&&(t.set(e.leftChild,{parent:e,isLeft:!0}),n.push(e.leftChild)),e.rightChild&&(t.set(e.rightChild,{parent:e,isLeft:!1}),n.push(e.rightChild)))}return t}findCandidates(e,t,n){let r=[],i=[e];for(;i.length>0;){let a=i.pop();if(a!==e&&n.get(a).parent!==e){let e=this.surfaceArea(a);r.length<t?(r.push({node:a,cost:e}),r.length===t&&this._heapify(r)):e>r[0].cost&&(r[0]={node:a,cost:e},this._siftDown(r,0))}a.triangleCount===0&&(a.leftChild&&i.push(a.leftChild),a.rightChild&&i.push(a.rightChild))}return r}_heapify(e){for(let t=(e.length>>1)-1;t>=0;t--)this._siftDown(e,t)}_siftDown(e,t){let n=e.length;for(;;){let r=t,i=2*t+1,a=2*t+2;if(i<n&&e[i].cost<e[r].cost&&(r=i),a<n&&e[a].cost<e[r].cost&&(r=a),r===t)break;let o=e[t];e[t]=e[r],e[r]=o,t=r}}findReinsertion(e,t,n){let r=n.get(e),i=r.parent;if(!i)return null;let a=r.isLeft?i.rightChild:i.leftChild,o=this.surfaceArea(e),s=this.surfaceArea(i),c=null,l=0,u=s,d=a.minX,f=a.minY,p=a.minZ,m=a.maxX,h=a.maxY,g=a.maxZ,_=a,v=i,y=[];do{for(y.length=0,y.push(u,_);y.length>0;){let t=y.pop(),n=y.pop();if(n-o<=l)continue;let r=Math.min(t.minX,e.minX),i=Math.min(t.minY,e.minY),a=Math.min(t.minZ,e.minZ),s=Math.max(t.maxX,e.maxX),u=Math.max(t.maxY,e.maxY),d=Math.max(t.maxZ,e.maxZ),f=s-r,p=u-i,m=d-a,h=n-(f*p+p*m+m*f);if(h>l&&(c=t,l=h),t.triangleCount===0&&t.leftChild&&t.rightChild){let e=h+this.surfaceArea(t);y.push(e,t.leftChild),y.push(e,t.rightChild)}}let t=n.get(v);if(!t||t.parent===null)break;if(v!==i){d=Math.min(d,_.minX),f=Math.min(f,_.minY),p=Math.min(p,_.minZ),m=Math.max(m,_.maxX),h=Math.max(h,_.maxY),g=Math.max(g,_.maxZ);let e=m-d,t=h-f,n=g-p,r=e*t+t*n+n*e;u+=this.surfaceArea(v)-r}let r=t.parent;_=t.isLeft?r.rightChild:r.leftChild,v=r}while(n.get(v).parent!==null);return c===a||c===i?null:c?{from:e,to:c,areaDiff:l}:null}getConflicts(e,t,n){let r=n.get(e);return[t,e,r.isLeft?r.parent.rightChild:r.parent.leftChild,n.get(t).parent,r.parent]}reinsertNode(e,t,n){let r=n.get(e),i=r.parent,a=r.isLeft?i.rightChild:i.leftChild,o=n.get(i),s=o.parent,c=n.get(t),l=c.parent;o.isLeft?s.leftChild=a:s.rightChild=a,i.leftChild=e,i.rightChild=t,i.triangleOffset=0,i.triangleCount=0,i.minX=Math.min(e.minX,t.minX),i.minY=Math.min(e.minY,t.minY),i.minZ=Math.min(e.minZ,t.minZ),i.maxX=Math.max(e.maxX,t.maxX),i.maxY=Math.max(e.maxY,t.maxY),i.maxZ=Math.max(e.maxZ,t.maxZ),c.isLeft?l.leftChild=i:l.rightChild=i,n.set(a,{parent:s,isLeft:o.isLeft}),n.set(i,{parent:l,isLeft:c.isLeft}),n.set(e,{parent:i,isLeft:!0}),n.set(t,{parent:i,isLeft:!1}),this.refitFrom(s,n),this.refitFrom(l,n)}refitFrom(e,t){let n=e;for(;n;){if(n.triangleCount===0&&n.leftChild&&n.rightChild){let e=n.leftChild,t=n.rightChild;n.minX=Math.min(e.minX,t.minX),n.minY=Math.min(e.minY,t.minY),n.minZ=Math.min(e.minZ,t.minZ),n.maxX=Math.max(e.maxX,t.maxX),n.maxY=Math.max(e.maxY,t.maxY),n.maxZ=Math.max(e.maxZ,t.maxZ)}let e=t.get(n);n=e?e.parent:null}}optimizeBVH(e,t){let n=performance.now();this.stats={reinsertionsApplied:0,iterations:0,timeMs:0};for(let r=0;r<this.maxIterations&&!(performance.now()-n>this.timeBudgetMs);r++){let i=this.buildParentMap(e),a=i.size,o=Math.max(1,Math.floor(a*this.batchSizeRatio));t&&t(`Reinsertion iter ${r+1}/${this.maxIterations}: selecting ${o} candidates`);let s=this.findCandidates(e,o,i),c=[];for(let t=0;t<s.length&&!(performance.now()-n>this.timeBudgetMs);t++){let n=this.findReinsertion(s[t].node,e,i);n&&n.areaDiff>0&&c.push(n)}c.sort((e,t)=>t.areaDiff-e.areaDiff);let l=new Set,u=0;for(let e of c){let t=this.getConflicts(e.from,e.to,i);if(!t.some(e=>l.has(e))){for(let e of t)l.add(e);this.reinsertNode(e.from,e.to,i),u++}}if(this.stats.reinsertionsApplied+=u,this.stats.iterations=r+1,t&&t(`Reinsertion iter ${r+1}: applied ${u} reinsertions`),u===0)break}return this.stats.timeMs=performance.now()-n,this.stats}};const r={silent:0,error:1,warn:2,info:3,debug:4},i=`info`,a=`rayzeeLogLevel`,o=`rayzeeLogNamespaces`,s=`color:#7c8494`,c=`color:inherit`;let l=null,u=null;function d(e){try{return globalThis.localStorage?.getItem(e)??null}catch{return null}}function f(e,t){try{t===null?globalThis.localStorage?.removeItem(e):globalThis.localStorage?.setItem(e,t)}catch{}}function p(){if(l!==null)return l;let e=globalThis.__RAYZEE_LOG_LEVEL__;return e!==void 0&&e in r?(l=r[e],l):(l=r[d(a)]??r[i],l)}function m(){if(u!==null)return u;let e=globalThis.__RAYZEE_LOG_NS__??d(o);return u=e?String(e).split(`,`).map(e=>e.trim()).filter(Boolean):[],u}function h(e,t){if(t<r.debug)return!0;let n=m();return n.length===0||n.some(t=>e===t||e.startsWith(`${t}:`))}function g(e,t,n){if(e>p()||!h(t,e))return;let i=e===r.error?console.error:e===r.warn?console.warn:console.log,a=`[${t}]`;typeof n[0]==`string`?i(`%c${a}%c ${n[0]}`,s,c,...n.slice(1)):i(`%c${a}`,s,...n)}const _={n:e=>Number(e).toLocaleString(`en-US`),ms:e=>e<10?`${Number(e).toFixed(1)} ms`:`${Math.round(e)} ms`,mb:e=>{let t=e/(1024*1024);return t<10?`${t.toFixed(1)} MB`:`${Math.round(t)} MB`},px:(e,t)=>`${e}×${t}`,count:(e,t,n=`${t}s`)=>`${_.n(e)} ${Number(e)===1?t:n}`,list:e=>e.filter(Boolean).join(` · `)},v={levels:r,setLevel(e){return e in r?(globalThis.__RAYZEE_LOG_LEVEL__=e,l=r[e],f(a,e===i?null:e),e):(console.warn(`[log] unknown level '${e}' — expected one of ${Object.keys(r).join(`, `)}`),this.getLevel())},getLevel(){let e=p();return Object.keys(r).find(t=>r[t]===e)},isEnabled(e){return(r[e]??r.debug)<=p()},only(...e){let t=e.flat().filter(Boolean);return u=t,globalThis.__RAYZEE_LOG_NS__=t.join(`,`),f(o,t.length?t.join(`,`):null),t.length&&this.setLevel(`debug`),t},refresh(){return l=null,u=null,this.getLevel()}};function y(e){return{namespace:e,error:(...t)=>g(r.error,e,t),warn:(...t)=>g(r.warn,e,t),info:(...t)=>g(r.info,e,t),debug:(...t)=>g(r.debug,e,t),isEnabled:e=>v.isEnabled(e),summary(t,n=[]){let i=n.filter(Boolean);if(i.length===0||!console.groupCollapsed){g(r.info,e,[t]),i.forEach(t=>g(r.debug,e,[t]));return}r.info>p()||((p()>=r.debug&&console.group?console.group:console.groupCollapsed)(`%c[${e}]%c ${t}`,s,c),i.forEach(e=>console.log(e)),console.groupEnd())}}}const b=1073741824,x=(e,t)=>~(e<<4|t)>>>0;function S(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]===1073741824&&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]>=b||(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]>=b)&&(l[s+3]=C(t,t[o+3],r,i),l[s+7]=C(t,t[o+7],r,i))}return c}function C(e,t,n,r){let i=t*16;return n(t)?x(e[i],e[i+1]):r[t]}const w=y(`bvh`),T=1073741824,E=e=>new Uint32Array(e.buffer,e.byteOffset,e.length),D=1073741824;function O(e,t){if(e>=D)throw RangeError(`${t} is ${e}, at or past the BVH index limit of ${D}`);return e}const k={FLOATS_PER_TRIANGLE:20,POSITION_A_OFFSET:0,POSITION_B_OFFSET:4,POSITION_C_OFFSET:8},A=k.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,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0},this.enableTreeletOptimization=!1,this.treeletSize=5,this.treeletOptimizationPasses=1,this.treeletMinImprovement=.02,this.treeletComplexityThreshold=5e4,this.enableReinsertionOptimization=!0,this.reinsertionBatchSizeRatio=.02,this.reinsertionMaxIterations=2,this.initializeBinArrays(),this._partResult={mid:0,lMinX:0,lMinY:0,lMinZ:0,lMaxX:0,lMaxY:0,lMaxZ:0,rMinX:0,rMinY:0,rMinZ:0,rMaxX:0,rMaxY:0,rMaxZ:0},this.centroids=null,this.bMin=null,this.bMax=null,this.indices=null,this.mortonCodes=null,this.triangles=null,this.reorderedTriangleData=null}initializeBinArrays(){let e=this.maxBins;this.binBoundsMin=new Float32Array(e*3),this.binBoundsMax=new Float32Array(e*3),this.binCounts=new Uint32Array(e),this.leftPrefixMin=new Float32Array(e*3),this.leftPrefixMax=new Float32Array(e*3),this.leftPrefixCount=new Uint32Array(e),this.rightPrefixMin=new Float32Array(e*3),this.rightPrefixMax=new Float32Array(e*3),this.rightPrefixCount=new Uint32Array(e)}getOptimalBinCount(e){return e<=16?this.minBins:e<=64?16:e<=256?32:e<=1024?48:this.maxBins}setAdaptiveBinConfig(e){e.minBins!==void 0&&(this.minBins=Math.max(4,e.minBins)),e.maxBins!==void 0&&(this.maxBins=Math.min(128,e.maxBins)),e.baseBins!==void 0&&(this.numBins=e.baseBins),e.maxBins!==void 0&&this.initializeBinArrays()}setMortonConfig(e){e.enabled!==void 0&&(this.useMortonCodes=e.enabled),e.bits!==void 0&&(this.mortonBits=Math.max(6,Math.min(10,e.bits))),e.threshold!==void 0&&(this.mortonClusterThreshold=Math.max(16,e.threshold))}setFallbackConfig(e){e.objectMedian!==void 0&&(this.enableObjectMedianFallback=e.objectMedian),e.spatialMedian!==void 0&&(this.enableSpatialMedianFallback=e.spatialMedian)}setTreeletConfig(e){e.enabled!==void 0&&(this.enableTreeletOptimization=e.enabled),e.size!==void 0&&(this.treeletSize=Math.max(3,Math.min(12,e.size))),e.passes!==void 0&&(this.treeletOptimizationPasses=Math.max(1,Math.min(3,e.passes))),e.minImprovement!==void 0&&(this.treeletMinImprovement=Math.max(.001,e.minImprovement)),e.complexityThreshold!==void 0&&(this.treeletComplexityThreshold=e.complexityThreshold)}disableTreeletOptimization(){this.enableTreeletOptimization=!1}setReinsertionConfig(e){e.enabled!==void 0&&(this.enableReinsertionOptimization=e.enabled),e.batchSizeRatio!==void 0&&(this.reinsertionBatchSizeRatio=Math.max(.005,Math.min(.1,e.batchSizeRatio))),e.maxIterations!==void 0&&(this.reinsertionMaxIterations=Math.max(1,Math.min(5,e.maxIterations)))}initializeTriangleArrays(){let e=this.totalTriangles,t=j(this.triangles),n=k.POSITION_A_OFFSET,r=k.POSITION_B_OFFSET,i=k.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?S(i):i,bvhRoot:!0,reorderedTriangles:this.reorderedTriangleData||null,originalToBvh:this.originalToBvhMap||null}}buildSync(t,r=30,i=null,a=null){let o=performance.now();this.totalNodes=0,this.processedTriangles=0,this.triangles=t,this.totalTriangles=t.byteLength/(A*4),this.lastProgressUpdate=performance.now(),this.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,reinsertionOptimizationTime:0,reinsertionsApplied:0,reinsertionIterations:0,saOrderTime:0,initTime:0,sahBuildTime:0,reorderTime:0};let s=this.totalTriangles,c=performance.now();this.centroids=new Float32Array(s*3),this.bMin=new Float32Array(s*3),this.bMax=new Float32Array(s*3),this.indices=new Uint32Array(s),this.mortonCodes=new Uint32Array(s),this.initializeTriangleArrays(),this.splitStats.initTime=performance.now()-c,this.sortTrianglesByMortonCode();let l=performance.now(),u=this.buildNodeRecursive(0,s,r,i);if(this.splitStats.sahBuildTime=performance.now()-l,this.enableTreeletOptimization&&this.totalTriangles>1e3){let t=this.totalTriangles>this.treeletComplexityThreshold?3:this.treeletSize,n=new e(this.traversalCost,this.intersectionCost);n.setTreeletSize(t),n.setMinImprovement(this.treeletMinImprovement);let r=performance.now();for(let e=0;e<this.treeletOptimizationPasses;e++){let t=i?t=>{i(`Treelet optimization pass ${e+1}/${this.treeletOptimizationPasses}: ${t}`)}:null;try{n.optimizeBVH(u,t)}catch(t){w.error(`treelet optimizer failed in pass ${e+1}:`,t);break}let a=n.getStatistics(),o=performance.now()-r;if(a.treeletsImproved===0&&e>0||o>15e3)break}let a=performance.now()-r;this.splitStats.treeletOptimizationTime=a;let o=n.getStatistics();this.splitStats.treeletsProcessed=o.treeletsProcessed,this.splitStats.treeletsImproved=o.treeletsImproved,this.splitStats.averageSAHImprovement=o.averageSAHImprovement}if(this.enableReinsertionOptimization&&this.totalTriangles>1e3){let e=new n(this.traversalCost,this.intersectionCost);e.setBatchSizeRatio(this.reinsertionBatchSizeRatio),e.setMaxIterations(this.reinsertionMaxIterations);let t=i?e=>{i(e)}:null;try{e.optimizeBVH(u,t)}catch(e){w.error(`reinsertion optimizer failed:`,e)}let r=e.getStatistics();this.splitStats.reinsertionOptimizationTime=r.timeMs,this.splitStats.reinsertionsApplied=r.reinsertionsApplied,this.splitStats.reinsertionIterations=r.iterations}let d=performance.now();this.applySAOrdering(u),this.splitStats.saOrderTime=performance.now()-d;let f=performance.now(),p=this.triangles,m=a||new p.constructor(s*A);for(let e=0;e<s;e++){let t=this.indices[e]*A,n=e*A;m.set(p.subarray(t,t+A),n)}this.reorderedTriangleData=m;let h=new Uint32Array(s);for(let e=0;e<s;e++)h[this.indices[e]]=e;this.originalToBvhMap=h,this.splitStats.reorderTime=performance.now()-f,this.splitStats.totalBuildTime=performance.now()-o;let g=this.splitStats.totalBuildTime,v=this.splitStats;return w.debug(`${_.n(s)} tris → ${_.n(this.totalNodes)} nodes in ${_.ms(g)} | SAH ${v.sahSplits} objMed ${v.objectMedianSplits} spatMed ${v.spatialMedianSplits} failed ${v.failedSplits}`+(v.treeletsProcessed?` | treelets ${v.treeletsImproved}/${v.treeletsProcessed} improved`:``)+(v.reinsertionsApplied?` | reinsertions ${v.reinsertionsApplied}`:``)),i&&i(100),this.centroids=null,this.bMin=null,this.bMax=null,this.mortonCodes=null,u}updateProgress(e,t){if(!t)return;this.processedTriangles+=e;let n=performance.now();n-this.lastProgressUpdate<this.progressUpdateInterval||(this.lastProgressUpdate=n,t(Math.min(Math.floor(this.processedTriangles/this.totalTriangles*100),99)))}buildNodeRecursiveToDepth(e,t,n,r,i,a,o,s,c,l,u){let d=new 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)}O(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=E(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]=T}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)}O(t.length,`BLAS node count`);let r=new Float32Array(t.length*16),i=[],a=E(r);for(let e=0;e<t.length;e++){let n=t[e],o=e*16;if(n.leftChild){let e=n.leftChild,t=n.rightChild;r[o]=e.minX,r[o+1]=e.minY,r[o+2]=e.minZ,a[o+3]=e._flatIndex,r[o+4]=e.maxX,r[o+5]=e.maxY,r[o+6]=e.maxZ,a[o+7]=t._flatIndex,r[o+8]=t.minX,r[o+9]=t.minY,r[o+10]=t.minZ,r[o+12]=t.maxX,r[o+13]=t.maxY,r[o+14]=t.maxZ}else if(n.isFrontier){let t=n.frontierTaskId;a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+2]=t,a[o+3]=1073741826,i.push({taskId:t,flatIndex:e})}else a[o]=n.triangleOffset,a[o+1]=n.triangleCount,a[o+3]=T}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;O(a,`assembled BLAS node count`);let o=new Float32Array(a*16),s=E(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]<T&&(s[t+3]+=l,s[t+7]+=l)}let u=c.get(t.taskId);if(u!==void 0){let e=u*16,t=a;for(let n=0;n<16;n++)o[e+n]=o[t+n]}l+=r}return o}computeSurfaceAreaFlat(e,t,n,r,i,a){let o=r-e,s=i-t,c=a-n;return 2*(o*s+s*c+c*o)}};self.onmessage=function(t){let{tasks:r,sharedTriangleData:i,sharedCentroids:a,sharedBMin:o,sharedBMax:s,sharedIndices:c,triangleCount:l,maxLeafSize:u,numBins:d,maxBins:f,minBins:p,treeletConfig:m,reinsertionConfig:h,reportProgress:g}=t.data;for(let t=0;t<r.length;t++){let _=r[t];try{let t=new N;t.maxLeafSize=u,t.numBins=d,t.maxBins=f,t.minBins=p,t.triangles=new Float32Array(i),t.centroids=new Float32Array(a),t.bMin=new Float32Array(o),t.bMax=new Float32Array(s),t.indices=new Uint32Array(c),t.totalTriangles=l,t.totalNodes=0,t.processedTriangles=0,t.lastProgressUpdate=performance.now(),t.splitStats={sahSplits:0,objectMedianSplits:0,spatialMedianSplits:0,failedSplits:0,avgBinsUsed:0,totalSplitAttempts:0,mortonSortTime:0,totalBuildTime:0,treeletOptimizationTime:0,treeletsProcessed:0,treeletsImproved:0,averageSAHImprovement:0,initTime:0,sahBuildTime:0,reorderTime:0};let r=g?e=>{self.postMessage({type:`progress`,taskId:_.taskId,progress:e})}:null,v=performance.now(),y=t.buildNodeRecursive(_.start,_.end,_.depth,r,_.preMinX,_.preMinY,_.preMinZ,_.preMaxX,_.preMaxY,_.preMaxZ);if(m&&m.enabled&&_.end-_.start>1e3){let n=_.end-_.start>5e4,r=n?3:m.size||5,i=n?10:20,a=new e(t.traversalCost,t.intersectionCost);a.setTreeletSize(r),a.setMinImprovement(m.minImprovement||.02),a.setMaxTreelets(i);let o=m.passes||1;for(let e=0;e<o;e++)try{a.optimizeBVH(y,null)}catch(t){console.error(`[BVHSubtreeWorker] Treelet pass ${e+1} error:`,t);break}}if(h&&h.enabled&&_.end-_.start>1e3){let e=new n(t.traversalCost,t.intersectionCost);h.batchSizeRatio&&e.setBatchSizeRatio(h.batchSizeRatio),h.maxIterations&&e.setMaxIterations(h.maxIterations);try{e.optimizeBVH(y,null)}catch(e){console.error(`[BVHSubtreeWorker] Reinsertion error:`,e)}}t.applySAOrdering(y);let b=t.flattenBVH(y),x=b.length/16,S=performance.now()-v;console.log(`[BVHSubtreeWorker] Task ${_.taskId}: ${(_.end-_.start).toLocaleString()} triangles, ${x} nodes, ${Math.round(S)}ms`),self.postMessage({type:`subtreeResult`,taskId:_.taskId,flatData:b,nodeCount:x},[b.buffer])}catch(e){console.error(`[BVHSubtreeWorker] Task ${_.taskId} error:`,e),self.postMessage({type:`error`,taskId:_.taskId,error:e.message})}}};", t_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", e_], { type: "text/javascript;charset=utf-8" });
26947
+ function n_(e) {
26930
26948
  let t;
26931
26949
  try {
26932
- if (t = e_ && (self.URL || self.webkitURL).createObjectURL(e_), !t) throw "";
26950
+ if (t = t_ && (self.URL || self.webkitURL).createObjectURL(t_), !t) throw "";
26933
26951
  let n = new Worker(t, {
26934
26952
  type: "module",
26935
26953
  name: e?.name
@@ -26938,7 +26956,7 @@ function t_(e) {
26938
26956
  (self.URL || self.webkitURL).revokeObjectURL(t);
26939
26957
  }), n;
26940
26958
  } catch {
26941
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent($g), {
26959
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(e_), {
26942
26960
  type: "module",
26943
26961
  name: e?.name
26944
26962
  });
@@ -26946,25 +26964,25 @@ function t_(e) {
26946
26964
  }
26947
26965
  //#endregion
26948
26966
  //#region src/Processor/ParallelBVHBuilder.js
26949
- Tg(() => Ls(Qg));
26950
- var n_ = a("bvh"), r_ = 20, i_ = 5e4, a_ = 8;
26951
- function o_(e, t, n, r) {
26952
- let i = e.byteLength / (r_ * 4), a = Math.min(Fs(), a_), o = Math.ceil(Math.log2(a * 2.5 + 1));
26953
- return n_.debug(`parallel build ${O.n(i)} triangles · ${a} workers · parallelDepth ${o}`), new Promise((s, c) => {
26967
+ Tg(() => Ls($g));
26968
+ var r_ = a("bvh"), i_ = 20, a_ = 5e4, o_ = 8;
26969
+ function s_(e, t, n, r) {
26970
+ let i = e.byteLength / (i_ * 4), a = Math.min(Fs(), o_), o = Math.ceil(Math.log2(a * 2.5 + 1));
26971
+ return r_.debug(`parallel build ${O.n(i)} triangles · ${a} workers · parallelDepth ${o}`), new Promise((s, c) => {
26954
26972
  (async () => {
26955
26973
  let l = e.buffer instanceof SharedArrayBuffer && e.byteOffset === 0 && e.byteLength === e.buffer.byteLength, u = l ? e.buffer : new SharedArrayBuffer(e.byteLength);
26956
26974
  l || new Uint32Array(u).set(e), e = null;
26957
- let d = new SharedArrayBuffer(i * 3 * 4), f = new SharedArrayBuffer(i * 3 * 4), p = new SharedArrayBuffer(i * 3 * 4), m = new SharedArrayBuffer(i * 4), h = new SharedArrayBuffer(i * 4), g = Ls(Qg), _ = null, v = [g], y = { id: null }, b = !1, x = () => {
26975
+ let d = new SharedArrayBuffer(i * 3 * 4), f = new SharedArrayBuffer(i * 3 * 4), p = new SharedArrayBuffer(i * 3 * 4), m = new SharedArrayBuffer(i * 4), h = new SharedArrayBuffer(i * 4), g = Ls($g), _ = null, v = [g], y = { id: null }, b = !1, x = () => {
26958
26976
  y.id &&= (clearTimeout(y.id), null);
26959
26977
  for (let e of v) try {
26960
26978
  e.terminate();
26961
26979
  } catch {}
26962
26980
  }, S = (e) => {
26963
26981
  if (!b) {
26964
- b = !0, n_.warn(`parallel build failed (${e}), falling back to single worker`), x();
26982
+ b = !0, r_.warn(`parallel build failed (${e}), falling back to single worker`), x();
26965
26983
  try {
26966
26984
  let e = new ArrayBuffer(u.byteLength);
26967
- new Uint32Array(e).set(new Uint32Array(u)), s(c_(new Uint32Array(e), t, n, r));
26985
+ new Uint32Array(e).set(new Uint32Array(u)), s(l_(new Uint32Array(e), t, n, r));
26968
26986
  } catch (e) {
26969
26987
  c(e);
26970
26988
  }
@@ -26983,7 +27001,7 @@ function o_(e, t, n, r) {
26983
27001
  return;
26984
27002
  }
26985
27003
  if (t.type === "phase1Result") {
26986
- _ = t.splitStats, s_(t, a, u, d, f, p, m, null, i, n, g, v, x, S, s, y, r).catch((e) => S(e.message));
27004
+ _ = t.splitStats, c_(t, a, u, d, f, p, m, null, i, n, g, v, x, S, s, y, r).catch((e) => S(e.message));
26987
27005
  return;
26988
27006
  }
26989
27007
  if (t.type === "assembleResult") {
@@ -27012,14 +27030,14 @@ function o_(e, t, n, r) {
27012
27030
  treeletOptimization: r.treeletOptimization
27013
27031
  });
27014
27032
  })().catch((e) => {
27015
- n_.warn("parallel build setup failed:", e), c(e);
27033
+ r_.warn("parallel build setup failed:", e), c(e);
27016
27034
  });
27017
27035
  });
27018
27036
  }
27019
- async function s_(e, t, n, r, i, a, o, s, c, l, u, d, f, p, m, h, g) {
27037
+ async function c_(e, t, n, r, i, a, o, s, c, l, u, d, f, p, m, h, g) {
27020
27038
  let { topFlatData: _, topNodeCount: v, frontierTasks: y, frontierMap: b } = e;
27021
27039
  if (!y || y.length === 0) {
27022
- n_.debug("no frontier tasks, assembling with top-level tree only"), u.postMessage({
27040
+ r_.debug("no frontier tasks, assembling with top-level tree only"), u.postMessage({
27023
27041
  type: "assemble",
27024
27042
  topFlatData: _,
27025
27043
  topNodeCount: v,
@@ -27033,7 +27051,7 @@ async function s_(e, t, n, r, i, a, o, s, c, l, u, d, f, p, m, h, g) {
27033
27051
  }, [_.buffer]);
27034
27052
  return;
27035
27053
  }
27036
- n_.debug(`phase 2 distributing ${y.length} tasks across ${t} workers`);
27054
+ r_.debug(`phase 2 distributing ${y.length} tasks across ${t} workers`);
27037
27055
  let x = [...y].sort((e, t) => t.end - t.start - (e.end - e.start)), S = Array.from({ length: Math.min(t, x.length) }, () => []), C = Array(S.length).fill(0);
27038
27056
  for (let e of x) {
27039
27057
  let t = 0;
@@ -27065,7 +27083,7 @@ async function s_(e, t, n, r, i, a, o, s, c, l, u, d, f, p, m, h, g) {
27065
27083
  for (let e = 0; e < A; e++) {
27066
27084
  let t = S[e];
27067
27085
  if (t.length === 0) continue;
27068
- let s = Ls(t_);
27086
+ let s = Ls(n_);
27069
27087
  d.push(s), s.onerror = (e) => {
27070
27088
  p(`subtree worker error: ${e.message}`);
27071
27089
  }, s.onmessage = (e) => {
@@ -27115,10 +27133,10 @@ async function s_(e, t, n, r, i, a, o, s, c, l, u, d, f, p, m, h, g) {
27115
27133
  });
27116
27134
  }
27117
27135
  }
27118
- function c_(e, t, n, r) {
27136
+ function l_(e, t, n, r) {
27119
27137
  return new Promise((i, a) => {
27120
27138
  (async () => {
27121
- let o = Ls(Qg), s = e.byteLength / (r_ * 4), c = typeof SharedArrayBuffer < "u" ? new SharedArrayBuffer(s * r_ * 4) : null;
27139
+ let o = Ls($g), s = e.byteLength / (i_ * 4), c = typeof SharedArrayBuffer < "u" ? new SharedArrayBuffer(s * i_ * 4) : null;
27122
27140
  o.onmessage = (e) => {
27123
27141
  let { bvhData: t, triangles: r, originalToBvh: s, error: l, progress: u, treeletStats: d } = e.data;
27124
27142
  if (l) {
@@ -27153,16 +27171,16 @@ function c_(e, t, n, r) {
27153
27171
  foldLeaves: r.foldLeaves
27154
27172
  }, [l]);
27155
27173
  })().catch((e) => {
27156
- n_.warn("single worker fallback failed:", e), a(e);
27174
+ r_.warn("single worker fallback failed:", e), a(e);
27157
27175
  });
27158
27176
  });
27159
27177
  }
27160
- function l_(e) {
27161
- return Is() && typeof SharedArrayBuffer < "u" && e >= i_;
27178
+ function u_(e) {
27179
+ return Is() && typeof SharedArrayBuffer < "u" && e >= a_;
27162
27180
  }
27163
27181
  //#endregion
27164
27182
  //#region src/Processor/InstanceTable.js
27165
- var u_ = Float64Array.from([
27183
+ var d_ = Float64Array.from([
27166
27184
  1,
27167
27185
  0,
27168
27186
  0,
@@ -27180,27 +27198,27 @@ var u_ = Float64Array.from([
27180
27198
  0,
27181
27199
  1
27182
27200
  ]);
27183
- function d_(e, t) {
27201
+ function f_(e, t) {
27184
27202
  return e[t] * (e[t + 5] * e[t + 10] - e[t + 6] * e[t + 9]) - e[t + 4] * (e[t + 1] * e[t + 10] - e[t + 2] * e[t + 9]) + e[t + 8] * (e[t + 1] * e[t + 6] - e[t + 2] * e[t + 5]);
27185
27203
  }
27186
- function f_(e, t, n) {
27187
- let r = d_(e, t);
27188
- if (!Number.isFinite(r) || Math.abs(r) < 1e-20) return n.set(u_), n;
27204
+ function p_(e, t, n) {
27205
+ let r = f_(e, t);
27206
+ if (!Number.isFinite(r) || Math.abs(r) < 1e-20) return n.set(d_), n;
27189
27207
  let i = 1 / r;
27190
27208
  return n[0] = (e[t + 5] * e[t + 10] - e[t + 6] * e[t + 9]) * i, n[1] = (e[t + 2] * e[t + 9] - e[t + 1] * e[t + 10]) * i, n[2] = (e[t + 1] * e[t + 6] - e[t + 2] * e[t + 5]) * i, n[3] = 0, n[4] = (e[t + 6] * e[t + 8] - e[t + 4] * e[t + 10]) * i, n[5] = (e[t] * e[t + 10] - e[t + 2] * e[t + 8]) * i, n[6] = (e[t + 2] * e[t + 4] - e[t] * e[t + 6]) * i, n[7] = 0, n[8] = (e[t + 4] * e[t + 9] - e[t + 5] * e[t + 8]) * i, n[9] = (e[t + 1] * e[t + 8] - e[t] * e[t + 9]) * i, n[10] = (e[t] * e[t + 5] - e[t + 1] * e[t + 4]) * i, n[11] = 0, n[12] = -(n[0] * e[t + 12] + n[4] * e[t + 13] + n[8] * e[t + 14]), n[13] = -(n[1] * e[t + 12] + n[5] * e[t + 13] + n[9] * e[t + 14]), n[14] = -(n[2] * e[t + 12] + n[6] * e[t + 13] + n[10] * e[t + 14]), n[15] = 1, n;
27191
27209
  }
27192
- function p_(e, t, n, r) {
27210
+ function m_(e, t, n, r) {
27193
27211
  for (let i = 0; i < 4; i++) {
27194
27212
  let a = n + i * 4, o = t[a], s = t[a + 1], c = t[a + 2], l = t[a + 3];
27195
27213
  for (let t = 0; t < 4; t++) r[i * 4 + t] = e[t] * o + e[4 + t] * s + e[8 + t] * c + e[12 + t] * l;
27196
27214
  }
27197
27215
  return r;
27198
27216
  }
27199
- function m_(e) {
27200
- for (let t = 0; t < 16; t++) if (e[t] !== u_[t]) return !1;
27217
+ function h_(e) {
27218
+ for (let t = 0; t < 16; t++) if (e[t] !== d_[t]) return !1;
27201
27219
  return !0;
27202
27220
  }
27203
- function h_(e, t, n, r, i, a) {
27221
+ function g_(e, t, n, r, i, a) {
27204
27222
  let o = Infinity, s = Infinity, c = Infinity, l = -Infinity, u = -Infinity, d = -Infinity;
27205
27223
  for (let i = 0; i < 8; i++) {
27206
27224
  let a = e[t + (i & 1 ? 3 : 0)], f = e[t + (i & 2 ? 4 : 1)], p = e[t + (i & 4 ? 5 : 2)], m = n[r] * a + n[r + 4] * f + n[r + 8] * p + n[r + 12], h = n[r + 1] * a + n[r + 5] * f + n[r + 9] * p + n[r + 13], g = n[r + 2] * a + n[r + 6] * f + n[r + 10] * p + n[r + 14];
@@ -27208,11 +27226,11 @@ function h_(e, t, n, r, i, a) {
27208
27226
  }
27209
27227
  i[a] = o, i[a + 1] = s, i[a + 2] = c, i[a + 3] = l, i[a + 4] = u, i[a + 5] = d;
27210
27228
  }
27211
- function g_(e, t) {
27212
- for (let n = 0; n < 16; n++) if (e[t + n] !== u_[n]) return !1;
27229
+ function __(e, t) {
27230
+ for (let n = 0; n < 16; n++) if (e[t + n] !== d_[n]) return !1;
27213
27231
  return !0;
27214
27232
  }
27215
- var __ = class e {
27233
+ var v_ = class e {
27216
27234
  constructor() {
27217
27235
  this.count = 0, this.templateCount = 0, this.totalBLASNodes = 0, this.tlasNodeCount = 0, this.allocate(0);
27218
27236
  }
@@ -27223,11 +27241,11 @@ var __ = class e {
27223
27241
  this.isSet[e] = 1, this.sourceMesh[e] = t;
27224
27242
  let i = e * 16;
27225
27243
  if (!n) {
27226
- this.world.set(u_, i), this.flipWinding[e] = 0;
27244
+ this.world.set(d_, i), this.flipWinding[e] = 0;
27227
27245
  return;
27228
27246
  }
27229
27247
  if (n !== this.world) for (let e = 0; e < 16; e++) this.world[i + e] = n[r + e];
27230
- this.flipWinding[e] = +(d_(this.world, i) < 0);
27248
+ this.flipWinding[e] = +(f_(this.world, i) < 0);
27231
27249
  }
27232
27250
  setEntry({ meshIndex: e, blasNodeCount: t, triOffset: n, triCount: r, originalToBvhMap: i, bvhData: a, matrixWorld: o = null, matrixOffset: s = 0, expandedStart: c = null, sourceMesh: l = null }) {
27233
27251
  let u = l ?? e;
@@ -27293,14 +27311,14 @@ var __ = class e {
27293
27311
  return this.world.subarray(e * 16, e * 16 + 16);
27294
27312
  }
27295
27313
  matrixInverseOf(e) {
27296
- return f_(this.world, e * 16, new Float64Array(16));
27314
+ return p_(this.world, e * 16, new Float64Array(16));
27297
27315
  }
27298
27316
  writeWorldAABB(e, t, n) {
27299
27317
  if (!this.isSet[e]) {
27300
27318
  for (let e = 0; e < 6; e++) t[n + e] = 0;
27301
27319
  return;
27302
27320
  }
27303
- h_(this.tplObjectAABB, this.sourceMesh[e] * 6, this.world, e * 16, t, n);
27321
+ g_(this.tplObjectAABB, this.sourceMesh[e] * 6, this.world, e * 16, t, n);
27304
27322
  }
27305
27323
  writeWorldAABBs(e) {
27306
27324
  let t = this.tplObjectAABB, n = this.world, r = this.sourceMesh, i = this.isSet;
@@ -27310,7 +27328,7 @@ var __ = class e {
27310
27328
  e[o] = 0, e[o + 1] = 0, e[o + 2] = 0, e[o + 3] = 0, e[o + 4] = 0, e[o + 5] = 0;
27311
27329
  continue;
27312
27330
  }
27313
- h_(t, r[a] * 6, n, a * 16, e, o);
27331
+ g_(t, r[a] * 6, n, a * 16, e, o);
27314
27332
  }
27315
27333
  }
27316
27334
  entryAt(e) {
@@ -27358,13 +27376,13 @@ var __ = class e {
27358
27376
  }
27359
27377
  static rootAABB(e, t, n, r, i, a) {
27360
27378
  if (!e || Gi(e)[3] === Ui.TRIANGLE_LEAF) {
27361
- v_(t, n, r, i, a);
27379
+ y_(t, n, r, i, a);
27362
27380
  return;
27363
27381
  }
27364
27382
  i[a] = Math.min(e[0], e[8]), i[a + 1] = Math.min(e[1], e[9]), i[a + 2] = Math.min(e[2], e[10]), i[a + 3] = Math.max(e[4], e[12]), i[a + 4] = Math.max(e[5], e[13]), i[a + 5] = Math.max(e[6], e[14]);
27365
27383
  }
27366
27384
  _computeAABBFromTriangles(e, t, n, r) {
27367
- v_(t, this.tplTriOffset[e], this.tplTriCount[e], n, r);
27385
+ y_(t, this.tplTriOffset[e], this.tplTriCount[e], n, r);
27368
27386
  }
27369
27387
  assignOffsets(e) {
27370
27388
  this.tlasNodeCount = e;
@@ -27388,7 +27406,7 @@ var __ = class e {
27388
27406
  this.allocate(0), this.totalBLASNodes = 0, this.tlasNodeCount = 0;
27389
27407
  }
27390
27408
  };
27391
- function v_(e, t, n, r, i) {
27409
+ function y_(e, t, n, r, i) {
27392
27410
  let a = Mi.FLOATS_PER_TRIANGLE, o = e && e.chunks ? e.viewAs(Float32Array) : null, s = o ? null : e instanceof Float32Array ? e : new Float32Array(e.buffer, e.byteOffset, e.length), c = Infinity, l = Infinity, u = Infinity, d = -Infinity, f = -Infinity, p = -Infinity;
27393
27411
  for (let e = 0; e < n; e++) {
27394
27412
  let n = t + e, r = o ? o.chunkFor(n) : s, i = o ? o.baseOf(n) : n * a;
@@ -27401,9 +27419,9 @@ function v_(e, t, n, r, i) {
27401
27419
  }
27402
27420
  //#endregion
27403
27421
  //#region src/Processor/TLASBuilder.js
27404
- var y_ = 16, b_ = 32, x_ = (e) => e < b_ ? e : b_, S_ = 8, C_ = 64, w_ = new Float64Array(16), T_ = class e {
27422
+ var b_ = 16, x_ = 32, S_ = (e) => e < x_ ? e : x_, C_ = 8, w_ = 64, T_ = new Float64Array(16), E_ = class e {
27405
27423
  constructor() {
27406
- this._flatBuffer = null, this._flatBufferCapacity = 0, this._binCounts = new Int32Array(b_ * 3), this._binBounds = new Float64Array(b_ * 6 * 3), this._binSuffix = new Float64Array(b_), this._binSuffixCount = new Int32Array(b_), this._order = null, this._stackI = null, this._stackB = null, this._stackFrames = 0, this._sortScratch = [], this._suffix = null, this._bounds = new Float64Array(12), this._extent = new Float64Array(3), this._cMin = new Float64Array(3);
27424
+ this._flatBuffer = null, this._flatBufferCapacity = 0, this._binCounts = new Int32Array(x_ * 3), this._binBounds = new Float64Array(x_ * 6 * 3), this._binSuffix = new Float64Array(x_), this._binSuffixCount = new Int32Array(x_), this._order = null, this._stackI = null, this._stackB = null, this._stackFrames = 0, this._sortScratch = [], this._suffix = null, this._bounds = new Float64Array(12), this._extent = new Float64Array(3), this._cMin = new Float64Array(3);
27407
27425
  }
27408
27426
  static nodeCountFor(e) {
27409
27427
  return e > 0 ? e * 2 - 1 : 0;
@@ -27424,22 +27442,22 @@ var y_ = 16, b_ = 32, x_ = (e) => e < b_ ? e : b_, S_ = 8, C_ = 64, w_ = new Flo
27424
27442
  nodeCount: 0
27425
27443
  };
27426
27444
  Ki(r, "TLAS node count");
27427
- let i = r * y_;
27445
+ let i = r * b_;
27428
27446
  i > this._flatBufferCapacity && (this._flatBuffer = new Float32Array(i), this._flatBufferCapacity = i);
27429
27447
  let a = this._flatBuffer, o = Gi(a);
27430
27448
  (!this._order || this._order.length < n) && (this._order = new Int32Array(n));
27431
27449
  let s = this._order;
27432
27450
  for (let e = 0; e < n; e++) s[e] = e;
27433
- this._ensureStack(C_);
27451
+ this._ensureStack(w_);
27434
27452
  let c = 0, l = 0, u = 0, d = n, f = this._bounds;
27435
27453
  this._rangeBounds(t, s, u, d, f, 0);
27436
27454
  let p = f[0], m = f[1], h = f[2], g = f[3], _ = f[4], v = f[5];
27437
27455
  for (;;) {
27438
27456
  if (d - u === 1) {
27439
- let e = l * y_;
27457
+ let e = l * b_;
27440
27458
  o[e] = 0, o[e + 1] = s[u], a[e + 2] = 0, o[e + 3] = Ui.BLAS_POINTER_LEAF;
27441
27459
  } else {
27442
- let e = this._partition(t, s, u, d, p, m, h, g, _, v), n = e - u, r = l + 1, i = r + (n * 2 - 1), y = l * y_;
27460
+ let e = this._partition(t, s, u, d, p, m, h, g, _, v), n = e - u, r = l + 1, i = r + (n * 2 - 1), y = l * b_;
27443
27461
  a[y] = f[0], a[y + 1] = f[1], a[y + 2] = f[2], o[y + 3] = r, a[y + 4] = f[3], a[y + 5] = f[4], a[y + 6] = f[5], o[y + 7] = i, a[y + 8] = f[6], a[y + 9] = f[7], a[y + 10] = f[8], a[y + 11] = 0, a[y + 12] = f[9], a[y + 13] = f[10], a[y + 14] = f[11], a[y + 15] = 0;
27444
27462
  let b = n <= d - e, x = b ? 0 : 6, S = b ? 6 : 0;
27445
27463
  c = this._push(c, b ? i : r, b ? e : u, b ? d : e, f, S), l = b ? r : i, b ? d = e : u = e, p = f[x], m = f[x + 1], h = f[x + 2], g = f[x + 3], _ = f[x + 4], v = f[x + 5];
@@ -27470,20 +27488,20 @@ var y_ = 16, b_ = 32, x_ = (e) => e < b_ ? e : b_, S_ = 8, C_ = 64, w_ = new Flo
27470
27488
  static fillLeaves(t, n, r) {
27471
27489
  let i = r.world, a = r.sourceMesh, o = r.tplBlasOffset, s = r.visible, c = r.tlasLeafIndex, l = Gi(t);
27472
27490
  for (let r = 0; r < n; r++) {
27473
- let n = r * y_;
27491
+ let n = r * b_;
27474
27492
  if (l[n + 3] !== Ui.BLAS_POINTER_LEAF) continue;
27475
27493
  let u = l[n + 1] & Hi;
27476
27494
  l[n] = o[a[u]], t[n + 2] = +!!s[u], e.writeLeafMatrix(t, l, n, i, u), c[u] = r;
27477
27495
  }
27478
27496
  }
27479
27497
  static writeLeafMatrix(e, t, n, r, i) {
27480
- let a = w_;
27481
- f_(r, i * 16, a), e[n + 4] = a[0], e[n + 5] = a[4], e[n + 6] = a[8], e[n + 7] = a[12], e[n + 8] = a[1], e[n + 9] = a[5], e[n + 10] = a[9], e[n + 11] = a[13], e[n + 12] = a[2], e[n + 13] = a[6], e[n + 14] = a[10], e[n + 15] = a[14], t[n + 1] = (i | (g_(r, i * 16) ? Vi : 0)) >>> 0;
27498
+ let a = T_;
27499
+ p_(r, i * 16, a), e[n + 4] = a[0], e[n + 5] = a[4], e[n + 6] = a[8], e[n + 7] = a[12], e[n + 8] = a[1], e[n + 9] = a[5], e[n + 10] = a[9], e[n + 11] = a[13], e[n + 12] = a[2], e[n + 13] = a[6], e[n + 14] = a[10], e[n + 15] = a[14], t[n + 1] = (i | (__(r, i * 16) ? Vi : 0)) >>> 0;
27482
27500
  }
27483
27501
  _partition(e, t, n, r, i, a, o, s, c, l) {
27484
27502
  let u = r - n, d = 0;
27485
27503
  if (u === 2) d = n + 1;
27486
- else if (u <= S_) d = n + (u >> 1), this._insertionSortRange(e, t, n, r, this._widestCentroidAxis(e, t, n, r));
27504
+ else if (u <= C_) d = n + (u >> 1), this._insertionSortRange(e, t, n, r, this._widestCentroidAxis(e, t, n, r));
27487
27505
  else {
27488
27506
  if (d = this._binnedSplit(e, t, n, r, i, a, o, s, c, l), d > n && d < r) return d;
27489
27507
  if (d = this._sweepSplit(e, t, n, r, i, a, o, s, c, l), !(d > n && d < r)) {
@@ -27506,7 +27524,7 @@ var y_ = 16, b_ = 32, x_ = (e) => e < b_ ? e : b_, S_ = 8, C_ = 64, w_ = new Flo
27506
27524
  _[0] = m - d, _[1] = h - f, _[2] = g - p, v[0] = d, v[1] = f, v[2] = p;
27507
27525
  let y = Infinity, b = -1, x = -1, S = this._binCounts, C = this._binBounds, w = _[0] > 1e-12, T = _[1] > 1e-12, E = _[2] > 1e-12;
27508
27526
  if (!w && !T && !E) return n;
27509
- let D = x_(r - n), O = w ? D / _[0] : 0, k = T ? D / _[1] : 0, A = E ? D / _[2] : 0;
27527
+ let D = S_(r - n), O = w ? D / _[0] : 0, k = T ? D / _[1] : 0, A = E ? D / _[2] : 0;
27510
27528
  S.fill(0, 0, D * 3);
27511
27529
  for (let e = 0; e < D * 3; e++) {
27512
27530
  let t = e * 6;
@@ -27618,8 +27636,8 @@ var y_ = 16, b_ = 32, x_ = (e) => e < b_ ? e : b_, S_ = 8, C_ = 64, w_ = new Flo
27618
27636
  let o = r - e, s = i - t, c = a - n;
27619
27637
  return 2 * (o * s + s * c + c * o);
27620
27638
  }
27621
- }, E_ = Mi.FLOATS_PER_TRIANGLE * 4, D_ = 64, O_ = .9, k_ = 64, A_ = 4, j_ = 7040 * 1024 * 1024, M_ = 9216 * 1024 * 1024;
27622
- function N_(e) {
27639
+ }, D_ = Mi.FLOATS_PER_TRIANGLE * 4, O_ = 64, k_ = .9, A_ = 64, j_ = 4, M_ = 7040 * 1024 * 1024, N_ = 9216 * 1024 * 1024;
27640
+ function P_(e) {
27623
27641
  if (e > 0) return {
27624
27642
  gb: e,
27625
27643
  assumed: !1
@@ -27633,19 +27651,19 @@ function N_(e) {
27633
27651
  assumed: !0
27634
27652
  };
27635
27653
  }
27636
- var P_ = 1.15, F_ = 12 * 1024 * 1024 * 1024;
27637
- function I_({ triangles: e, placements: t, geometryBytes: n = 0 }) {
27654
+ var F_ = 1.15, I_ = 12 * 1024 * 1024 * 1024;
27655
+ function L_({ triangles: e, placements: t, geometryBytes: n = 0 }) {
27638
27656
  let r = {
27639
- triangles: e * E_,
27640
- bvh: Math.ceil(e * O_) * D_,
27657
+ triangles: e * D_,
27658
+ bvh: Math.ceil(e * k_) * O_,
27641
27659
  geometry: n,
27642
- placements: t * k_,
27643
- orderMaps: e * A_
27660
+ placements: t * A_,
27661
+ orderMaps: e * j_
27644
27662
  };
27645
27663
  return r.total = r.triangles + r.bvh + r.geometry + r.placements + r.orderMaps, r;
27646
27664
  }
27647
- function L_(e, { chunkBytes: t = qa, shared: n = !1, allocate: r = null } = {}) {
27648
- let i = Math.min(e, F_), a = r ?? (n ? (e) => new SharedArrayBuffer(e) : (e) => new ArrayBuffer(e)), o = [], s = 0;
27665
+ function R_(e, { chunkBytes: t = qa, shared: n = !1, allocate: r = null } = {}) {
27666
+ let i = Math.min(e, I_), a = r ?? (n ? (e) => new SharedArrayBuffer(e) : (e) => new ArrayBuffer(e)), o = [], s = 0;
27649
27667
  try {
27650
27668
  for (; s < i;) {
27651
27669
  let e = Math.min(t, i - s);
@@ -27660,7 +27678,7 @@ function L_(e, { chunkBytes: t = qa, shared: n = !1, allocate: r = null } = {})
27660
27678
  capped: e > i
27661
27679
  };
27662
27680
  }
27663
- var R_ = class {
27681
+ var z_ = class {
27664
27682
  constructor() {
27665
27683
  this.reset();
27666
27684
  }
@@ -27705,11 +27723,11 @@ var R_ = class {
27705
27723
  samples: this.samples.slice()
27706
27724
  };
27707
27725
  }
27708
- }, z_ = "let e,t;const n={MAX_BYTES_PER_TEXTURE:256*1024*1024,MAX_TEXTURE_DIMENSION:8192,CHUNK_SIZE:8,ADAPTIVE_CHUNK_SIZE:!0,MEMORY_SAFETY_FACTOR:.8};self.onmessage=async function(t){let{textures:n,maxTextureSize:a,method:o=`direct-transfer`}=t.data;try{e||r(a);let t=await i(n,a,o);self.postMessage(t,[t.data])}catch(e){console.error(`Worker processing failed:`,e),self.postMessage({error:e.message})}};function r(r){let i=Math.min(r,n.MAX_TEXTURE_DIMENSION);e=new OffscreenCanvas(i,i),t=e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0})}async function i(e,t,r){let i=h(e,t),o=i.maxWidth*i.maxHeight*e.length*4;if(o>n.MAX_BYTES_PER_TEXTURE)return console.log(`Large texture array detected (${(o/1024/1024).toFixed(2)}MB), using chunked processing`),await a(e,t,r);switch(r){case`direct-transfer`:return await d(e,t);case`offscreen-optimized`:return await p(e,t);case`imageBitmap-batch`:return await m(e,t);default:return await d(e,t)}}async function a(e,t,n){let{maxWidth:r,maxHeight:i}=h(e,t),a=e.length,c=o(r,i,a),l=Math.ceil(a/c);console.log(`Processing ${a} textures in ${l} chunks of up to ${c} textures each`),console.log(`Texture dimensions: ${r}x${i}, Est. memory per chunk: ${(r*i*c*4/1024/1024).toFixed(2)}MB`);let u;try{u=new Uint8Array(r*i*a*4)}catch{return console.warn(`Failed to allocate full texture array, reducing dimensions`),await f(e,g(e,t),n)}let d=r*i*c*4,p;try{p=new Uint8Array(d)}catch{return console.warn(`Failed to allocate chunk buffer, reducing dimensions`),await f(e,g(e,t),n)}for(let t=0;t<l;t++){let n=t*c,o=Math.min(n+c,a),l=o-n,d=await s(e.slice(n,o),r,i,p.subarray(0,r*i*l*4)),f=n*r*i*4,m=l*r*i*4;u.set(new Uint8Array(d.data.slice(0,m)),f),t%2==1&&await new Promise(e=>setTimeout(e,0))}return{data:u.buffer,width:r,height:i,depth:a}}function o(e,t,r){if(!n.ADAPTIVE_CHUNK_SIZE)return Math.min(n.CHUNK_SIZE,r);let i=e*t*4/(1024*1024),a;return a=i<=1?16:i<=4?8:i<=16?4:2,Math.min(a,r,n.CHUNK_SIZE*2)}async function s(n,r,i,a){(e.width!==r||e.height!==i)&&(e.width=r,e.height=i);let o=r*i*4;t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await c(t,a,e*o,r,i)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=e*o;a.fill(0,n,n+o)}}return{data:a.buffer,width:r,height:i,depth:n.length}}async function c(e,n,r,i,a){let o;if(e.isDirect&&e.bitmap)o=e.bitmap;else if(e.isImageData&&e.data){let t=new ImageData(new Uint8ClampedArray(e.data),e.width,e.height);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else if(e.isBlob){let t=new Blob([e.data]);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else throw Error(`Unknown texture data format`);t.clearRect(0,0,i,a),t.drawImage(o,0,0,i,a);let s=t.getImageData(0,0,i,a);n.set(s.data,r),(e.isImageData||e.isBlob)&&o.close()}async function l(e,t,n){let r;try{r=new Uint8Array(t*n*e.length*4)}catch(r){console.warn(`Failed to allocate texture array in processTextureChunk, reducing dimensions`);let i=Math.max(1,Math.floor(t/2)),a=Math.max(1,Math.floor(n/2));if(i===t&&a===n)throw r;return await l(e,i,a)}return await s(e,t,n,r)}async function u(e,t,n,r,i){await c(e,n,r*i*4*t,r,i)}async function d(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`direct-transfer`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await u(t,e,c,i,o)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function f(e,t,n){let{maxWidth:r,maxHeight:i}=t;return console.log(`Using reduced dimensions: ${r}x${i}`),await l(e,r,i,n)}async function p(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`offscreen-optimized`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let r=n[e];try{let n;if(r.isBlob){let e=new Blob([r.data]);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(r.data),r.width,r.height);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}t.clearRect(0,0,i,o),t.drawImage(n,0,0);let a=t.getImageData(0,0,i,o),s=i*o*4*e;c.set(a.data,s),n.close()}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function m(n,r){let{maxWidth:i,maxHeight:s}=h(n,r),c=n.length,l;try{l=new Uint8Array(i*s*c*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`imageBitmap-batch`)}let u=Math.min(o(i,s,n.length),n.length);for(let r=0;r<n.length;r+=u){let a=Math.min(r+u,n.length),o=[];for(let e=r;e<a;e++){let t=n[e],r;if(t.isBlob){let e=new Blob([t.data]);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(t.data),t.width,t.height);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}o.push(r.then(t=>({bitmap:t,index:e})))}let c=await Promise.all(o);e.width=i,e.height=s,t.imageSmoothingEnabled=!1;for(let{bitmap:e,index:n}of c){t.clearRect(0,0,i,s),t.drawImage(e,0,0);let r=t.getImageData(0,0,i,s),a=i*s*4*n;l.set(r.data,a),e.close()}}return{data:l.buffer,width:i,height:s,depth:c}}function h(e,t){let r=0,i=0;for(let t of e)r=Math.max(r,t.width||0),i=Math.max(i,t.height||0);let a=Math.min(t,n.MAX_TEXTURE_DIMENSION),o=Math.max(r,i);if(o>a){let e=a/o;r=Math.round(r*e),i=Math.round(i*e)}return r=Math.min(a,Math.max(4,Math.ceil(Math.max(1,r)/64)*64)),{maxWidth:r,maxHeight:Math.max(1,i)}}function g(e,t){let n=h(e,t);return{maxWidth:Math.max(64,Math.ceil(n.maxWidth/128)*64),maxHeight:Math.max(1,Math.floor(n.maxHeight/2))}}", B_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", z_], { type: "text/javascript;charset=utf-8" });
27709
- function V_(e) {
27726
+ }, B_ = "let e,t;const n={MAX_BYTES_PER_TEXTURE:256*1024*1024,MAX_TEXTURE_DIMENSION:8192,CHUNK_SIZE:8,ADAPTIVE_CHUNK_SIZE:!0,MEMORY_SAFETY_FACTOR:.8};self.onmessage=async function(t){let{textures:n,maxTextureSize:a,method:o=`direct-transfer`}=t.data;try{e||r(a);let t=await i(n,a,o);self.postMessage(t,[t.data])}catch(e){console.error(`Worker processing failed:`,e),self.postMessage({error:e.message})}};function r(r){let i=Math.min(r,n.MAX_TEXTURE_DIMENSION);e=new OffscreenCanvas(i,i),t=e.getContext(`2d`,{willReadFrequently:!0,alpha:!0,desynchronized:!0})}async function i(e,t,r){let i=h(e,t),o=i.maxWidth*i.maxHeight*e.length*4;if(o>n.MAX_BYTES_PER_TEXTURE)return console.log(`Large texture array detected (${(o/1024/1024).toFixed(2)}MB), using chunked processing`),await a(e,t,r);switch(r){case`direct-transfer`:return await d(e,t);case`offscreen-optimized`:return await p(e,t);case`imageBitmap-batch`:return await m(e,t);default:return await d(e,t)}}async function a(e,t,n){let{maxWidth:r,maxHeight:i}=h(e,t),a=e.length,c=o(r,i,a),l=Math.ceil(a/c);console.log(`Processing ${a} textures in ${l} chunks of up to ${c} textures each`),console.log(`Texture dimensions: ${r}x${i}, Est. memory per chunk: ${(r*i*c*4/1024/1024).toFixed(2)}MB`);let u;try{u=new Uint8Array(r*i*a*4)}catch{return console.warn(`Failed to allocate full texture array, reducing dimensions`),await f(e,g(e,t),n)}let d=r*i*c*4,p;try{p=new Uint8Array(d)}catch{return console.warn(`Failed to allocate chunk buffer, reducing dimensions`),await f(e,g(e,t),n)}for(let t=0;t<l;t++){let n=t*c,o=Math.min(n+c,a),l=o-n,d=await s(e.slice(n,o),r,i,p.subarray(0,r*i*l*4)),f=n*r*i*4,m=l*r*i*4;u.set(new Uint8Array(d.data.slice(0,m)),f),t%2==1&&await new Promise(e=>setTimeout(e,0))}return{data:u.buffer,width:r,height:i,depth:a}}function o(e,t,r){if(!n.ADAPTIVE_CHUNK_SIZE)return Math.min(n.CHUNK_SIZE,r);let i=e*t*4/(1024*1024),a;return a=i<=1?16:i<=4?8:i<=16?4:2,Math.min(a,r,n.CHUNK_SIZE*2)}async function s(n,r,i,a){(e.width!==r||e.height!==i)&&(e.width=r,e.height=i);let o=r*i*4;t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await c(t,a,e*o,r,i)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=e*o;a.fill(0,n,n+o)}}return{data:a.buffer,width:r,height:i,depth:n.length}}async function c(e,n,r,i,a){let o;if(e.isDirect&&e.bitmap)o=e.bitmap;else if(e.isImageData&&e.data){let t=new ImageData(new Uint8ClampedArray(e.data),e.width,e.height);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else if(e.isBlob){let t=new Blob([e.data]);o=await createImageBitmap(t,{resizeWidth:i,resizeHeight:a,resizeQuality:`high`})}else throw Error(`Unknown texture data format`);t.clearRect(0,0,i,a),t.drawImage(o,0,0,i,a);let s=t.getImageData(0,0,i,a);n.set(s.data,r),(e.isImageData||e.isBlob)&&o.close()}async function l(e,t,n){let r;try{r=new Uint8Array(t*n*e.length*4)}catch(r){console.warn(`Failed to allocate texture array in processTextureChunk, reducing dimensions`);let i=Math.max(1,Math.floor(t/2)),a=Math.max(1,Math.floor(n/2));if(i===t&&a===n)throw r;return await l(e,i,a)}return await s(e,t,n,r)}async function u(e,t,n,r,i){await c(e,n,r*i*4*t,r,i)}async function d(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`direct-transfer`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let t=n[e];try{await u(t,e,c,i,o)}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function f(e,t,n){let{maxWidth:r,maxHeight:i}=t;return console.log(`Using reduced dimensions: ${r}x${i}`),await l(e,r,i,n)}async function p(n,r){let{maxWidth:i,maxHeight:o}=h(n,r);(e.width!==i||e.height!==o)&&(e.width=i,e.height=o);let s=n.length,c;try{c=new Uint8Array(i*o*s*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`offscreen-optimized`)}t.imageSmoothingEnabled=!0,t.imageSmoothingQuality=`high`;for(let e=0;e<n.length;e++){let r=n[e];try{let n;if(r.isBlob){let e=new Blob([r.data]);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(r.data),r.width,r.height);n=await createImageBitmap(e,{resizeWidth:i,resizeHeight:o,resizeQuality:`high`})}t.clearRect(0,0,i,o),t.drawImage(n,0,0);let a=t.getImageData(0,0,i,o),s=i*o*4*e;c.set(a.data,s),n.close()}catch(t){console.warn(`Failed to process texture ${e}:`,t);let n=i*o*4*e;c.fill(0,n,n+i*o*4)}}return{data:c.buffer,width:i,height:o,depth:s}}async function m(n,r){let{maxWidth:i,maxHeight:s}=h(n,r),c=n.length,l;try{l=new Uint8Array(i*s*c*4)}catch(e){return console.error(`Failed to allocate texture array:`,e),await a(n,r,`imageBitmap-batch`)}let u=Math.min(o(i,s,n.length),n.length);for(let r=0;r<n.length;r+=u){let a=Math.min(r+u,n.length),o=[];for(let e=r;e<a;e++){let t=n[e],r;if(t.isBlob){let e=new Blob([t.data]);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}else{let e=new ImageData(new Uint8ClampedArray(t.data),t.width,t.height);r=createImageBitmap(e,{resizeWidth:i,resizeHeight:s,resizeQuality:`high`})}o.push(r.then(t=>({bitmap:t,index:e})))}let c=await Promise.all(o);e.width=i,e.height=s,t.imageSmoothingEnabled=!1;for(let{bitmap:e,index:n}of c){t.clearRect(0,0,i,s),t.drawImage(e,0,0);let r=t.getImageData(0,0,i,s),a=i*s*4*n;l.set(r.data,a),e.close()}}return{data:l.buffer,width:i,height:s,depth:c}}function h(e,t){let r=0,i=0;for(let t of e)r=Math.max(r,t.width||0),i=Math.max(i,t.height||0);let a=Math.min(t,n.MAX_TEXTURE_DIMENSION),o=Math.max(r,i);if(o>a){let e=a/o;r=Math.round(r*e),i=Math.round(i*e)}return r=Math.min(a,Math.max(4,Math.ceil(Math.max(1,r)/64)*64)),{maxWidth:r,maxHeight:Math.max(1,i)}}function g(e,t){let n=h(e,t);return{maxWidth:Math.max(64,Math.ceil(n.maxWidth/128)*64),maxHeight:Math.max(1,Math.floor(n.maxHeight/2))}}", V_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", B_], { type: "text/javascript;charset=utf-8" });
27727
+ function H_(e) {
27710
27728
  let t;
27711
27729
  try {
27712
- if (t = B_ && (self.URL || self.webkitURL).createObjectURL(B_), !t) throw "";
27730
+ if (t = V_ && (self.URL || self.webkitURL).createObjectURL(V_), !t) throw "";
27713
27731
  let n = new Worker(t, {
27714
27732
  type: "module",
27715
27733
  name: e?.name
@@ -27718,7 +27736,7 @@ function V_(e) {
27718
27736
  (self.URL || self.webkitURL).revokeObjectURL(t);
27719
27737
  }), n;
27720
27738
  } catch {
27721
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(z_), {
27739
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(B_), {
27722
27740
  type: "module",
27723
27741
  name: e?.name
27724
27742
  });
@@ -27726,11 +27744,11 @@ function V_(e) {
27726
27744
  }
27727
27745
  //#endregion
27728
27746
  //#region src/Processor/Workers/PackWorker.js?worker&inline
27729
- var H_ = "function e({data:e,width:t,height:n,flipY:r},i,a,o,s){let c=o*4;if(t===o&&n===s){if(!r){i.set(e.subarray(0,s*c),a);return}for(let t=0;t<s;t++)i.set(e.subarray(t*c,(t+1)*c),a+(s-1-t)*c);return}let l=new Int32Array(o),u=new Int32Array(o),d=new Float64Array(o);for(let e=0;e<o;e++){let n=Math.min(Math.max((e+.5)*t/o-.5,0),t-1),r=Math.floor(n);l[e]=r*4,u[e]=Math.min(r+1,t-1)*4,d[e]=n-r}if(s<=n){for(let f=0;f<s;f++){let p=Math.min(Math.max((f+.5)*n/s-.5,0),n-1),m=Math.floor(p),h=Math.min(m+1,n-1),g=p-m,_=m*t*4,v=h*t*4,y=a+(r?s-1-f:f)*c;for(let t=0;t<o;t++,y+=4){let n=_+l[t],r=_+u[t],a=v+l[t],o=v+u[t],s=d[t];for(let t=0;t<4;t++){let c=e[n+t]+(e[r+t]-e[n+t])*s,l=e[a+t]+(e[o+t]-e[a+t])*s;i[y+t]=Math.round(c+(l-c)*g)}}}return}let f=[{row:-1,data:new Float64Array(c)},{row:-1,data:new Float64Array(c)}],p=(n,r)=>{for(let e of f)if(e.row===n)return e.data;let i=f[0].row===r?f[1]:f[0],a=n*t*4,s=i.data;for(let t=0,n=0;t<o;t++,n+=4){let r=a+l[t],i=a+u[t],o=d[t];s[n]=e[r]+(e[i]-e[r])*o,s[n+1]=e[r+1]+(e[i+1]-e[r+1])*o,s[n+2]=e[r+2]+(e[i+2]-e[r+2])*o,s[n+3]=e[r+3]+(e[i+3]-e[r+3])*o}return i.row=n,s};for(let e=0;e<s;e++){let t=Math.min(Math.max((e+.5)*n/s-.5,0),n-1),o=Math.floor(t),l=Math.min(o+1,n-1),u=t-o,d=p(o,l),f=l===o?d:p(l,o),m=a+(r?s-1-e:e)*c;for(let e=0;e<c;e++)i[m+e]=Math.round(d[e]+(f[e]-d[e])*u)}}self.onmessage=function(t){let{layers:n,width:r,height:i}=t.data;try{let t=r*i*4,a=new Uint8Array(t*n.length);n.forEach((n,o)=>e(n,a,o*t,r,i)),self.postMessage({data:a},[a.buffer])}catch(e){self.postMessage({error:e.message})}};", U_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", H_], { type: "text/javascript;charset=utf-8" });
27730
- function W_(e) {
27747
+ var U_ = "function e({data:e,width:t,height:n,flipY:r},i,a,o,s){let c=o*4;if(t===o&&n===s){if(!r){i.set(e.subarray(0,s*c),a);return}for(let t=0;t<s;t++)i.set(e.subarray(t*c,(t+1)*c),a+(s-1-t)*c);return}let l=new Int32Array(o),u=new Int32Array(o),d=new Float64Array(o);for(let e=0;e<o;e++){let n=Math.min(Math.max((e+.5)*t/o-.5,0),t-1),r=Math.floor(n);l[e]=r*4,u[e]=Math.min(r+1,t-1)*4,d[e]=n-r}if(s<=n){for(let f=0;f<s;f++){let p=Math.min(Math.max((f+.5)*n/s-.5,0),n-1),m=Math.floor(p),h=Math.min(m+1,n-1),g=p-m,_=m*t*4,v=h*t*4,y=a+(r?s-1-f:f)*c;for(let t=0;t<o;t++,y+=4){let n=_+l[t],r=_+u[t],a=v+l[t],o=v+u[t],s=d[t];for(let t=0;t<4;t++){let c=e[n+t]+(e[r+t]-e[n+t])*s,l=e[a+t]+(e[o+t]-e[a+t])*s;i[y+t]=Math.round(c+(l-c)*g)}}}return}let f=[{row:-1,data:new Float64Array(c)},{row:-1,data:new Float64Array(c)}],p=(n,r)=>{for(let e of f)if(e.row===n)return e.data;let i=f[0].row===r?f[1]:f[0],a=n*t*4,s=i.data;for(let t=0,n=0;t<o;t++,n+=4){let r=a+l[t],i=a+u[t],o=d[t];s[n]=e[r]+(e[i]-e[r])*o,s[n+1]=e[r+1]+(e[i+1]-e[r+1])*o,s[n+2]=e[r+2]+(e[i+2]-e[r+2])*o,s[n+3]=e[r+3]+(e[i+3]-e[r+3])*o}return i.row=n,s};for(let e=0;e<s;e++){let t=Math.min(Math.max((e+.5)*n/s-.5,0),n-1),o=Math.floor(t),l=Math.min(o+1,n-1),u=t-o,d=p(o,l),f=l===o?d:p(l,o),m=a+(r?s-1-e:e)*c;for(let e=0;e<c;e++)i[m+e]=Math.round(d[e]+(f[e]-d[e])*u)}}self.onmessage=function(t){let{layers:n,width:r,height:i}=t.data;try{let t=r*i*4,a=new Uint8Array(t*n.length);n.forEach((n,o)=>e(n,a,o*t,r,i)),self.postMessage({data:a},[a.buffer])}catch(e){self.postMessage({error:e.message})}};", W_ = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", U_], { type: "text/javascript;charset=utf-8" });
27748
+ function G_(e) {
27731
27749
  let t;
27732
27750
  try {
27733
- if (t = U_ && (self.URL || self.webkitURL).createObjectURL(U_), !t) throw "";
27751
+ if (t = W_ && (self.URL || self.webkitURL).createObjectURL(W_), !t) throw "";
27734
27752
  let n = new Worker(t, {
27735
27753
  type: "module",
27736
27754
  name: e?.name
@@ -27739,7 +27757,7 @@ function W_(e) {
27739
27757
  (self.URL || self.webkitURL).revokeObjectURL(t);
27740
27758
  }), n;
27741
27759
  } catch {
27742
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(H_), {
27760
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(U_), {
27743
27761
  type: "module",
27744
27762
  name: e?.name
27745
27763
  });
@@ -27747,7 +27765,7 @@ function W_(e) {
27747
27765
  }
27748
27766
  //#endregion
27749
27767
  //#region src/Processor/ResampleRGBA8.js
27750
- function G_({ data: e, width: t, height: n, flipY: r }, i, a, o, s) {
27768
+ function K_({ data: e, width: t, height: n, flipY: r }, i, a, o, s) {
27751
27769
  let c = o * 4;
27752
27770
  if (t === o && n === s) {
27753
27771
  if (!r) {
@@ -27797,16 +27815,15 @@ function G_({ data: e, width: t, height: n, flipY: r }, i, a, o, s) {
27797
27815
  }
27798
27816
  //#endregion
27799
27817
  //#region src/Processor/ToneMapCPU.js
27800
- var K_ = (e) => (t, n, r, i, a) => e(t > 0 ? t : 0, n > 0 ? n : 0, r > 0 ? r : 0, i, a), q_ = /* @__PURE__ */ new Map();
27801
- function J_() {
27802
- q_.clear();
27803
- for (let e of u.values()) q_.set(e.id, K_(e.cpu));
27818
+ var q_ = (e) => (t, n, r, i, a) => e(t > 0 ? t : 0, n > 0 ? n : 0, r > 0 ? r : 0, i, a), J_ = /* @__PURE__ */ new Map();
27819
+ function Y_() {
27820
+ J_.clear();
27821
+ for (let e of u.values()) J_.set(e.id, q_(e.cpu));
27804
27822
  }
27805
- J_(), S(J_);
27806
- function Y_(e) {
27823
+ Y_(), S(Y_);
27824
+ function X_(e) {
27807
27825
  return E(e)?.outputEncoded === !0;
27808
27826
  }
27809
- var X_ = 1 / 2.2;
27810
27827
  function Z_(e) {
27811
27828
  return e <= .0031308 ? 12.92 * e : 1.055 * e ** (1 / 2.4) - .055;
27812
27829
  }
@@ -27821,7 +27838,7 @@ function nv(e, t) {
27821
27838
  e[0] = n + (e[0] - n) * t, e[1] = n + (e[1] - n) * t, e[2] = n + (e[2] - n) * t;
27822
27839
  }
27823
27840
  function rv(e, { exposure: t, toneMapping: n, saturation: r = 1, preserveAlpha: i = !1 }) {
27824
- let a = q_.get(n) ?? q_.get(Dn), o = Q_(t, n), s = Y_(n), c = new Uint8ClampedArray(e.length), l = [
27841
+ let a = J_.get(n) ?? J_.get(Dn), o = Q_(t, n), s = X_(n), c = new Uint8ClampedArray(e.length), l = [
27825
27842
  0,
27826
27843
  0,
27827
27844
  0
@@ -28132,7 +28149,7 @@ var uv = class {
28132
28149
  async processWithWorkerDirect(e) {
28133
28150
  for (; this.activeWorkers >= this.maxConcurrentWorkers;) await new Promise((e) => setTimeout(e, 10));
28134
28151
  this.activeWorkers++;
28135
- let t = new V_();
28152
+ let t = new H_();
28136
28153
  try {
28137
28154
  let n = await this.prepareTexturesForWorkerDirect(e), r = await new Promise((e, r) => {
28138
28155
  t.onmessage = (t) => {
@@ -28220,7 +28237,7 @@ var uv = class {
28220
28237
  }), { maxWidth: n, maxHeight: r } = this.calculateOptimalDimensions(t.map((e) => ({ image: e }))), i = n * r * 4, a = Is() && i * t.length >= av ? await this._packInWorker(t, n, r) : null;
28221
28238
  if (a) return this.createDataArrayTextureFromBuffer(a, n, r, t.length);
28222
28239
  let o = this.bufferPool.getBuffer(i * t.length, Uint8Array);
28223
- return t.forEach((e, t) => G_(e, o, t * i, n, r)), this.createDataArrayTextureFromBuffer(o, n, r, t.length);
28240
+ return t.forEach((e, t) => K_(e, o, t * i, n, r)), this.createDataArrayTextureFromBuffer(o, n, r, t.length);
28224
28241
  }
28225
28242
  async _packInWorker(e, t, n) {
28226
28243
  let r = await sv(), i = null;
@@ -28233,7 +28250,7 @@ var uv = class {
28233
28250
  data: t
28234
28251
  };
28235
28252
  });
28236
- return i = Ls(W_), await new Promise((e, o) => {
28253
+ return i = Ls(G_), await new Promise((e, o) => {
28237
28254
  i.onmessage = (t) => t.data.error ? o(Error(t.data.error)) : e(t.data.data), i.onerror = (e) => o(e.error ?? Error(e.message ?? "texture pack worker failed")), i.postMessage({
28238
28255
  layers: a,
28239
28256
  width: t,
@@ -29095,13 +29112,13 @@ function Vv(e, t, n, r) {
29095
29112
  }
29096
29113
  //#endregion
29097
29114
  //#region src/version.js
29098
- var Hv = "9.3.2", Uv = 1e4, Wv = 15e5;
29115
+ var Hv = "9.3.3", Uv = 1e4, Wv = 15e5;
29099
29116
  function Gv(e, t, n = Uv) {
29100
29117
  return e >= n && t / Wv < e / 3;
29101
29118
  }
29102
29119
  //#endregion
29103
29120
  //#region src/Processor/Workers/BVHRefitWorker.js?worker&inline
29104
- var Kv = "const e=e=>e>=2147483648,t=e=>~e>>>0>>>4,n=e=>~e&15,r={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},i=r.FLOATS_PER_TRIANGLE,a=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),o=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),s=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):o(e)}},c=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,l=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,u=(e,t)=>e.chunked?e.chunked.baseOf(t):t*p,d=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):a(e),u:t?e:o(e)}};function f(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}const p=16;function m(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=1e-12*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>z&&(z=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=z}function h(e,t,n,a,o){let s=r.POSITION_A_OFFSET,c=r.POSITION_B_OFFSET,l=r.POSITION_C_OFFSET,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0;for(let r=0;r<n;r++){let n=t+r,a=e.chunked?e.f.chunkFor(n):e.f,o=e.chunked?e.chunked.baseOf(n):n*i;u=Math.min(u,a[o+s],a[o+c],a[o+l]),d=Math.min(d,a[o+s+1],a[o+c+1],a[o+l+1]),f=Math.min(f,a[o+s+2],a[o+c+2],a[o+l+2]),p=Math.max(p,a[o+s],a[o+c],a[o+l]),m=Math.max(m,a[o+s+1],a[o+c+1],a[o+l+1]),h=Math.max(h,a[o+s+2],a[o+c+2],a[o+l+2])}a[o]=u,a[o+1]=d,a[o+2]=f,a[o+3]=p,a[o+4]=m,a[o+5]=h}const g=new Float32Array(12);function _(r,i,a,o,s){let d=c(r,i),f=l(r,i),p=u(r,i),_=(i-s)*6,v=f[p+3];if(v===1073741824){h(a,f[p],f[p+1],o,_);return}if(v===1073741825){m(d,p,o,(f[p]-s)*6,o,_);return}let y=f[p+7],b=o,x=(v-s)*6;e(v)&&(h(a,t(v),n(v),g,0),b=g,x=0);let S=o,C=(y-s)*6;e(y)&&(h(a,t(y),n(y),g,6),S=g,C=6),d[p]=b[x],d[p+1]=b[x+1],d[p+2]=b[x+2],d[p+4]=b[x+3],d[p+5]=b[x+4],d[p+6]=b[x+5],d[p+8]=S[C],d[p+9]=S[C+1],d[p+10]=S[C+2],d[p+12]=S[C+3],d[p+13]=S[C+4],d[p+14]=S[C+5];for(let e=0;e<3;e++)o[_+e]=Math.min(b[x+e],S[C+e]),o[_+3+e]=Math.max(b[x+3+e],S[C+3+e])}var v=class{constructor(){this._bounds=null,this._boundsNodeCount=0}updateTrianglePositions(e,t,n){let a=n.length,o=d(e);for(let e=0;e<a;e++){let a=n[e],s=o.chunked?o.f.chunkFor(e):o.f,c=o.chunked?o.u.chunkFor(e):o.u,l=o.chunked?o.chunked.baseOf(e):e*i,u=a*9,d=t[u],p=t[u+1],m=t[u+2],h=t[u+3],g=t[u+4],_=t[u+5],v=t[u+6],y=t[u+7],b=t[u+8];s[l+r.POSITION_A_OFFSET]=d,s[l+r.POSITION_A_OFFSET+1]=p,s[l+r.POSITION_A_OFFSET+2]=m,s[l+r.POSITION_B_OFFSET]=h,s[l+r.POSITION_B_OFFSET+1]=g,s[l+r.POSITION_B_OFFSET+2]=_,s[l+r.POSITION_C_OFFSET]=v,s[l+r.POSITION_C_OFFSET+1]=y,s[l+r.POSITION_C_OFFSET+2]=b;let x=h-d,S=g-p,C=_-m,w=v-d,T=y-p,E=b-m,D=f(S*E-C*T,C*w-x*E,x*T-S*w);c[l+r.NORMAL_A_PACKED_OFFSET]=D,c[l+r.NORMAL_B_PACKED_OFFSET]=D,c[l+r.NORMAL_C_PACKED_OFFSET]=D}}refitRange(e,t,n,r){let i=d(t);r>this._boundsNodeCount&&(this._bounds=new Float32Array(r*6),this._boundsNodeCount=r);let a=s(e);for(let e=n+r-1;e>=n;e--)_(a,e,i,this._bounds,n)}refit(e,t,n){let r=d(t);n!==this._boundsNodeCount&&(this._bounds=new Float32Array(n*6),this._boundsNodeCount=n);let i=s(e);for(let e=n-1;e>=0;e--)_(i,e,r,this._bounds,0)}};const y=64*1024*1024;function b(e,t,n){return n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t)}var x=class e{constructor(e,t,n,r=y,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push(b(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push(b(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=y,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=b(this.LaneType,n,this.shared);for(let t of this._liveViews())t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)!this.chunks[e]&&!this._spilled?.has(e)&&this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0,n=this.chunks[t];if(n)return n;if(this._spilled?.has(t))throw Error(`ChunkedRecords: chunk ${t} is on disk — await ensureResident() before touching record ${e}`);return this._materialize(t)}async spill(e,{keep:t=()=>!1}={}){if(this._owner)throw Error(`ChunkedRecords: spill the storage, not a view of it`);this._store=e,this._spilled??=new Set;let n=0;for(let r=0;r<this.chunks.length;r++){let i=this.chunks[r];if(!(!i||t(r))){await e.write(r,i),this.chunks[r]=null;for(let e of this._liveViews())e.chunks[r]=null;this._spilled.add(r),n+=i.byteLength}}return n}async spillChunk(e,t){let n=this.chunks[e];if(!n)return 0;this._store=t,this._spilled??=new Set,await t.write(e,n),this.chunks[e]=null;for(let t of this._liveViews())t.chunks[e]=null;return this._spilled.add(e),n.byteLength}async ensureResident(e=0,t=this.recordCount){if(!this._spilled?.size||t<=0)return;let n=e/this.recordsPerChunk|0,r=(e+t-1)/this.recordsPerChunk|0;for(let e=n;e<=r;e++){if(!this._spilled.has(e))continue;let t=Math.min(this.recordsPerChunk,this.recordCount-e*this.recordsPerChunk)*this.lanesPerRecord,n=await this._store.read(e,t*this.LaneType.BYTES_PER_ELEMENT),r=b(this.LaneType,t,this.shared);new Uint8Array(r.buffer,r.byteOffset,r.byteLength).set(new Uint8Array(n)),this.chunks[e]=r;for(let t of this._liveViews())t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);this._spilled.delete(e)}}_liveViews(){return this._weakViews&&=this._weakViews.filter(e=>e.deref()),[...this._views??[],...(this._weakViews??[]).map(e=>e.deref())]}isResident(e=0,t=this.recordCount){if(!this._spilled?.size||t<=0)return!0;let n=e/this.recordsPerChunk|0,r=(e+t-1)/this.recordsPerChunk|0;for(let e=n;e<=r;e++)if(this._spilled.has(e))return!1;return!0}get spilledChunks(){return this._spilled?.size??0}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}grow(e){if(e<=this.recordCount)return;let t=this.chunks.length-1,n=(e,t)=>Math.min(this.recordsPerChunk,t-e*this.recordsPerChunk)*this.lanesPerRecord,r=this.chunks[t];this.recordCount=e;for(let t of this._liveViews())t.recordCount=e;if(this.chunks.length*this.recordsPerChunk<e){this.chunks.length=Math.ceil(e/this.recordsPerChunk);for(let e of this._liveViews())e.chunks.length=this.chunks.length}if(r&&r.length<n(t,e)){let i=b(this.LaneType,n(t,e),this.shared);i.set(r),this.chunks[t]=i;for(let e of this._liveViews())e.chunks[t]=new e.LaneType(i.buffer,i.byteOffset,i.byteLength/e.LaneType.BYTES_PER_ELEMENT)}else if(!r&&this._spilled?.has(t))throw Error(`ChunkedRecords: cannot grow past chunk ${t}, which is on disk`)}release(e,t){let n=this.recordsPerChunk,r=Math.ceil(e/n),i=Math.floor((e+t)/n),a=0;for(let e=r;e<i;e++){let t=this.chunks[e];if(t){a+=t.byteLength,this.chunks[e]=void 0;for(let t of this._liveViews())t.chunks[e]=void 0}}return a}trimInPlace(e){let t=Math.max(1,Math.ceil(e/this.recordsPerChunk)),n=Math.max(0,(e-(t-1)*this.recordsPerChunk)*this.lanesPerRecord),r=[this,...this._liveViews()];for(let i of r){i.chunks.length=t;let r=i.chunks[t-1];r&&r.length>n&&(i.chunks[t-1]=r.subarray(0,n)),i.recordCount=e}if(this._spilled)for(let e of this._spilled)e>=t&&this._spilled.delete(e);return this}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,r._owner=this,this._views?this._views.push(r):(this._weakViews??=[]).push(new WeakRef(r)),r._spilled=this._spilled??=new Set,r}};const S=new v;let C=null,w=null,T=0;self.onmessage=function(e){let{type:t}=e.data;if(t===`init`){C=x.adopt(e.data.sharedBvhBufs.map(e=>new Float32Array(e)),e.data.bvhRecordCount,16,e.data.bvhRecordsPerChunk),w=x.adopt(e.data.sharedTriBufs.map(e=>new Uint32Array(e)),e.data.triRecordCount,e.data.triLanesPerRecord,e.data.triRecordsPerChunk),T=C.recordCount;return}if(t===`refit`)try{let e=performance.now();S.refit(C,w,T),self.postMessage({type:`refitComplete`,refitTimeMs:performance.now()-e})}catch(e){console.error(`[BVHRefitWorker] Refit error:`,e),self.postMessage({type:`error`,error:e.message})}};", qv = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Kv], { type: "text/javascript;charset=utf-8" });
29121
+ var Kv = "const e=e=>e>=2147483648,t=e=>~e>>>0>>>4,n=e=>~e&15,r={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},i=r.FLOATS_PER_TRIANGLE,a=e=>e instanceof Float32Array?e:new Float32Array(e.buffer,e.byteOffset,e.length),o=e=>e instanceof Uint32Array?e:new Uint32Array(e.buffer,e.byteOffset,e.length),s=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:e,idx:t?e.viewAs(Uint32Array):o(e)}},c=(e,t)=>e.chunked?e.f.chunkFor(t):e.f,l=(e,t)=>e.chunked?e.idx.chunkFor(t):e.idx,u=(e,t)=>e.chunked?e.chunked.baseOf(t):t*p,d=e=>{let t=e&&e.chunks?e:null;return{chunked:t,f:t?t.viewAs(Float32Array):a(e),u:t?e:o(e)}};function f(e,t,n){let r=Math.sqrt(e*e+t*t+n*n);r>0?(e/=r,t/=r,n/=r):(e=0,t=0,n=1);let i=Math.abs(e)+Math.abs(t)+Math.abs(n),a=e/i,o=t/i;if(n<0){let e=a,t=o;a=(1-Math.abs(t))*(e>=0?1:-1),o=(1-Math.abs(e))*(t>=0?1:-1)}let s=Math.round(Math.min(1,Math.max(-1,a))*32767)&65535;return((Math.round(Math.min(1,Math.max(-1,o))*32767)&65535)<<16|s)>>>0}const p=16,m=1073741824,h=1073741825;function g(e,t,n,r,i,a){let o=e[t+4],s=e[t+5],c=e[t+6],l=e[t+7],u=e[t+8],d=e[t+9],f=e[t+10],p=e[t+11],m=e[t+12],h=e[t+13],g=e[t+14],_=e[t+15],v=d*g-f*h,y=f*m-u*g,b=u*h-d*m,x=o*v+s*y+c*b,S=o===1&&d===1&&g===1&&s===0&&c===0&&u===0&&f===0&&m===0&&h===0&&l===0&&p===0&&_===0,C=(Math.abs(o)+Math.abs(s)+Math.abs(c))*(Math.abs(u)+Math.abs(d)+Math.abs(f))*(Math.abs(m)+Math.abs(h)+Math.abs(g));if(S||!Number.isFinite(x)||Math.abs(x)<=1e-12*C){for(let e=0;e<6;e++)i[a+e]=n[r+e];return}let w=1/x,T=v*w,E=y*w,D=b*w,O=(c*h-s*g)*w,k=(o*g-c*m)*w,A=(s*m-o*h)*w,j=(s*f-c*d)*w,M=(c*u-o*f)*w,N=(o*d-s*u)*w,P=1/0,F=1/0,I=1/0,L=-1/0,R=-1/0,z=-1/0;for(let e=0;e<8;e++){let t=(e&1?n[r+3]:n[r])-l,i=(e&2?n[r+4]:n[r+1])-p,a=(e&4?n[r+5]:n[r+2])-_,o=T*t+O*i+j*a,s=E*t+k*i+M*a,c=D*t+A*i+N*a;o<P&&(P=o),o>L&&(L=o),s<F&&(F=s),s>R&&(R=s),c<I&&(I=c),c>z&&(z=c)}i[a]=P,i[a+1]=F,i[a+2]=I,i[a+3]=L,i[a+4]=R,i[a+5]=z}function _(e,t,n,a,o){let s=r.POSITION_A_OFFSET,c=r.POSITION_B_OFFSET,l=r.POSITION_C_OFFSET,u=1/0,d=1/0,f=1/0,p=-1/0,m=-1/0,h=-1/0;for(let r=0;r<n;r++){let n=t+r,a=e.chunked?e.f.chunkFor(n):e.f,o=e.chunked?e.chunked.baseOf(n):n*i;u=Math.min(u,a[o+s],a[o+c],a[o+l]),d=Math.min(d,a[o+s+1],a[o+c+1],a[o+l+1]),f=Math.min(f,a[o+s+2],a[o+c+2],a[o+l+2]),p=Math.max(p,a[o+s],a[o+c],a[o+l]),m=Math.max(m,a[o+s+1],a[o+c+1],a[o+l+1]),h=Math.max(h,a[o+s+2],a[o+c+2],a[o+l+2])}a[o]=u,a[o+1]=d,a[o+2]=f,a[o+3]=p,a[o+4]=m,a[o+5]=h}const v=new Float32Array(12);function y(e,t,n,r){let i=c(e,t),a=l(e,t),o=u(e,t);if(a[o+3]===m){_(n,a[o],a[o+1],r,0);return}for(let e=0;e<3;e++)r[e]=Math.min(i[o+e],i[o+8+e]),r[3+e]=Math.max(i[o+4+e],i[o+12+e])}function b(r,i,a,o,s){let d=c(r,i),f=l(r,i),p=u(r,i),y=(i-s)*6,b=f[p+3];if(b===m){_(a,f[p],f[p+1],o,y);return}if(b===h){g(d,p,o,(f[p]-s)*6,o,y);return}let x=f[p+7],S=o,C=(b-s)*6;e(b)&&(_(a,t(b),n(b),v,0),S=v,C=0);let w=o,T=(x-s)*6;e(x)&&(_(a,t(x),n(x),v,6),w=v,T=6),d[p]=S[C],d[p+1]=S[C+1],d[p+2]=S[C+2],d[p+4]=S[C+3],d[p+5]=S[C+4],d[p+6]=S[C+5],d[p+8]=w[T],d[p+9]=w[T+1],d[p+10]=w[T+2],d[p+12]=w[T+3],d[p+13]=w[T+4],d[p+14]=w[T+5];for(let e=0;e<3;e++)o[y+e]=Math.min(S[C+e],w[T+e]),o[y+3+e]=Math.max(S[C+3+e],w[T+3+e])}var x=class{constructor(){this._bounds=null,this._boundsNodeCount=0,this._tlasBounds=null,this._rootBox=null}updateTrianglePositions(e,t,n){let a=n.length,o=d(e);for(let e=0;e<a;e++){let a=n[e],s=o.chunked?o.f.chunkFor(e):o.f,c=o.chunked?o.u.chunkFor(e):o.u,l=o.chunked?o.chunked.baseOf(e):e*i,u=a*9,d=t[u],p=t[u+1],m=t[u+2],h=t[u+3],g=t[u+4],_=t[u+5],v=t[u+6],y=t[u+7],b=t[u+8];s[l+r.POSITION_A_OFFSET]=d,s[l+r.POSITION_A_OFFSET+1]=p,s[l+r.POSITION_A_OFFSET+2]=m,s[l+r.POSITION_B_OFFSET]=h,s[l+r.POSITION_B_OFFSET+1]=g,s[l+r.POSITION_B_OFFSET+2]=_,s[l+r.POSITION_C_OFFSET]=v,s[l+r.POSITION_C_OFFSET+1]=y,s[l+r.POSITION_C_OFFSET+2]=b;let x=h-d,S=g-p,C=_-m,w=v-d,T=y-p,E=b-m,D=f(S*E-C*T,C*w-x*E,x*T-S*w);c[l+r.NORMAL_A_PACKED_OFFSET]=D,c[l+r.NORMAL_B_PACKED_OFFSET]=D,c[l+r.NORMAL_C_PACKED_OFFSET]=D}}refitRange(e,t,n,r){let i=d(t);r>this._boundsNodeCount&&(this._bounds=new Float32Array(r*6),this._boundsNodeCount=r);let a=s(e);for(let e=n+r-1;e>=n;e--)b(a,e,i,this._bounds,n)}refitPartial(e,t,n,r){for(let r=0;r<n.length;r+=2)this.refitRange(e,t,n[r],n[r+1]);let i=d(t),a=s(e);(!this._tlasBounds||this._tlasBounds.length<r*6)&&(this._tlasBounds=new Float32Array(r*6));let o=this._tlasBounds,f=this._rootBox||=new Float32Array(6);for(let e=r-1;e>=0;e--){let t=l(a,e),n=u(a,e);t[n+3]===h?(y(a,t[n],i,f),g(c(a,e),n,f,0,o,e*6)):b(a,e,i,o,0)}}refit(e,t,n){let r=d(t);n!==this._boundsNodeCount&&(this._bounds=new Float32Array(n*6),this._boundsNodeCount=n);let i=s(e);for(let e=n-1;e>=0;e--)b(i,e,r,this._bounds,0)}};const S=64*1024*1024;function C(e,t,n){return n?new e(new SharedArrayBuffer(t*e.BYTES_PER_ELEMENT)):new e(t)}var w=class e{constructor(e,t,n,r=S,i=!1){let a=t*n.BYTES_PER_ELEMENT,o=Math.max(1,Math.floor(r/a));this.recordCount=e,this.lanesPerRecord=t,this.LaneType=n,this.recordsPerChunk=e<=o?Math.max(e,1):o,this.shared=i,this.chunks=[];let s=e;for(;s>0;){let e=Math.min(s,this.recordsPerChunk);this.chunks.push(C(n,e*t,i)),s-=e}this.chunks.length===0&&this.chunks.push(C(n,0,i))}static adopt(t,n,r,i){let a=Object.create(e.prototype);return a.recordCount=n,a.lanesPerRecord=r,a.LaneType=t[0]?.constructor??null,a.recordsPerChunk=i,a.chunks=t,a.shared=typeof SharedArrayBuffer<`u`&&t[0]?.buffer instanceof SharedArrayBuffer,a}static lazy(t,n,r,i=S,a=!1){let o=Math.max(1,Math.floor(i/(n*r.BYTES_PER_ELEMENT))),s=Object.create(e.prototype);return s.recordCount=t,s.lanesPerRecord=n,s.LaneType=r,s.recordsPerChunk=t<=o?Math.max(t,1):o,s.shared=a,s.chunks=Array(Math.max(1,Math.ceil(t/s.recordsPerChunk))),s._views=[],s}_materialize(e){if(this._owner)return this._owner._materialize(e),this.chunks[e];let t=e*this.recordsPerChunk,n=Math.min(this.recordsPerChunk,this.recordCount-t)*this.lanesPerRecord,r=this.chunks[e]=C(this.LaneType,n,this.shared);for(let t of this._liveViews())t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);return r}materializeAll(){for(let e=0;e<this.chunks.length;e++)!this.chunks[e]&&!this._spilled?.has(e)&&this._materialize(e);return this}get chunkCount(){return this.chunks.length}get single(){return this.chunks.length===1?this.chunks[0]:null}get byteLength(){let e=0;for(let t of this.chunks)t&&(e+=t.byteLength);return e}chunkFor(e){let t=e/this.recordsPerChunk|0,n=this.chunks[t];if(n)return n;if(this._spilled?.has(t))throw Error(`ChunkedRecords: chunk ${t} is on disk — await ensureResident() before touching record ${e}`);return this._materialize(t)}async spill(e,{keep:t=()=>!1}={}){if(this._owner)throw Error(`ChunkedRecords: spill the storage, not a view of it`);this._store=e,this._spilled??=new Set;let n=0;for(let r=0;r<this.chunks.length;r++){let i=this.chunks[r];if(!(!i||t(r))){await e.write(r,i),this.chunks[r]=null;for(let e of this._liveViews())e.chunks[r]=null;this._spilled.add(r),n+=i.byteLength}}return n}async spillChunk(e,t){let n=this.chunks[e];if(!n)return 0;this._store=t,this._spilled??=new Set,await t.write(e,n),this.chunks[e]=null;for(let t of this._liveViews())t.chunks[e]=null;return this._spilled.add(e),n.byteLength}async ensureResident(e=0,t=this.recordCount){if(!this._spilled?.size||t<=0)return;let n=e/this.recordsPerChunk|0,r=(e+t-1)/this.recordsPerChunk|0;for(let e=n;e<=r;e++){if(!this._spilled.has(e))continue;let t=Math.min(this.recordsPerChunk,this.recordCount-e*this.recordsPerChunk)*this.lanesPerRecord,n=await this._store.read(e,t*this.LaneType.BYTES_PER_ELEMENT),r=C(this.LaneType,t,this.shared);new Uint8Array(r.buffer,r.byteOffset,r.byteLength).set(new Uint8Array(n)),this.chunks[e]=r;for(let t of this._liveViews())t.chunks[e]=new t.LaneType(r.buffer,r.byteOffset,r.byteLength/t.LaneType.BYTES_PER_ELEMENT);this._spilled.delete(e)}}_liveViews(){return this._weakViews&&=this._weakViews.filter(e=>e.deref()),[...this._views??[],...(this._weakViews??[]).map(e=>e.deref())]}isResident(e=0,t=this.recordCount){if(!this._spilled?.size||t<=0)return!0;let n=e/this.recordsPerChunk|0,r=(e+t-1)/this.recordsPerChunk|0;for(let e=n;e<=r;e++)if(this._spilled.has(e))return!1;return!0}get spilledChunks(){return this._spilled?.size??0}baseOf(e){return e%this.recordsPerChunk*this.lanesPerRecord}isContiguous(e,t){return t<=0?!0:(e/this.recordsPerChunk|0)==((e+t-1)/this.recordsPerChunk|0)}slice(e,t){let n=this.baseOf(e),r=t*this.lanesPerRecord;if(this.isContiguous(e,t))return this.chunkFor(e).subarray(n,n+r);let i=new this.LaneType(r);return this.readRecords(e,t,i),i}readRecords(e,t,n){let r=0;for(;r<t;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,t-r);n.set(a.subarray(o,o+c*this.lanesPerRecord),r*this.lanesPerRecord),r+=c}return n}setRecords(e,t){let n=t.length/this.lanesPerRecord,r=0;for(;r<n;){let i=e+r,a=this.chunkFor(i),o=this.baseOf(i),s=this.recordsPerChunk-i%this.recordsPerChunk,c=Math.min(s,n-r);a.set(t.subarray(r*this.lanesPerRecord,(r+c)*this.lanesPerRecord),o),r+=c}}copyOf(e,t){return this.readRecords(e,t,new this.LaneType(t*this.lanesPerRecord))}trimTo(t){let n=Math.max(1,Math.ceil(t/this.recordsPerChunk)),r=this.chunks.slice(0,n),i=(t-(n-1)*this.recordsPerChunk)*this.lanesPerRecord,a=r[n-1];return a.length>i&&(r[n-1]=a.subarray(0,Math.max(0,i))),e.adopt(r,t,this.lanesPerRecord,this.recordsPerChunk)}grow(e){if(e<=this.recordCount)return;let t=this.chunks.length-1,n=(e,t)=>Math.min(this.recordsPerChunk,t-e*this.recordsPerChunk)*this.lanesPerRecord,r=this.chunks[t];this.recordCount=e;for(let t of this._liveViews())t.recordCount=e;if(this.chunks.length*this.recordsPerChunk<e){this.chunks.length=Math.ceil(e/this.recordsPerChunk);for(let e of this._liveViews())e.chunks.length=this.chunks.length}if(r&&r.length<n(t,e)){let i=C(this.LaneType,n(t,e),this.shared);i.set(r),this.chunks[t]=i;for(let e of this._liveViews())e.chunks[t]=new e.LaneType(i.buffer,i.byteOffset,i.byteLength/e.LaneType.BYTES_PER_ELEMENT)}else if(!r&&this._spilled?.has(t))throw Error(`ChunkedRecords: cannot grow past chunk ${t}, which is on disk`)}release(e,t){let n=this.recordsPerChunk,r=Math.ceil(e/n),i=Math.floor((e+t)/n),a=0;for(let e=r;e<i;e++){let t=this.chunks[e];if(t){a+=t.byteLength,this.chunks[e]=void 0;for(let t of this._liveViews())t.chunks[e]=void 0}}return a}trimInPlace(e){let t=Math.max(1,Math.ceil(e/this.recordsPerChunk)),n=Math.max(0,(e-(t-1)*this.recordsPerChunk)*this.lanesPerRecord),r=[this,...this._liveViews()];for(let i of r){i.chunks.length=t;let r=i.chunks[t-1];r&&r.length>n&&(i.chunks[t-1]=r.subarray(0,n)),i.recordCount=e}if(this._spilled)for(let e of this._spilled)e>=t&&this._spilled.delete(e);return this}viewAs(t){let n=e=>new t(e.buffer,e.byteOffset,e.byteLength/t.BYTES_PER_ELEMENT),r=e.adopt(this.chunks.map(e=>e?n(e):void 0),this.recordCount,this.lanesPerRecord,this.recordsPerChunk);return r.LaneType=t,r._owner=this,this._views?this._views.push(r):(this._weakViews??=[]).push(new WeakRef(r)),r._spilled=this._spilled??=new Set,r}};const T=new x;let E=null,D=null,O=0;self.onmessage=function(e){let{type:t}=e.data;if(t===`init`){E=w.adopt(e.data.sharedBvhBufs.map(e=>new Float32Array(e)),e.data.bvhRecordCount,16,e.data.bvhRecordsPerChunk),D=w.adopt(e.data.sharedTriBufs.map(e=>new Uint32Array(e)),e.data.triRecordCount,e.data.triLanesPerRecord,e.data.triRecordsPerChunk),O=E.recordCount;return}if(t===`refit`)try{let t=performance.now(),{blasRanges:n,tlasNodeCount:r}=e.data;n?T.refitPartial(E,D,n,r):T.refit(E,D,O),self.postMessage({type:`refitComplete`,refitTimeMs:performance.now()-t})}catch(e){console.error(`[BVHRefitWorker] Refit error:`,e),self.postMessage({type:`error`,error:e.message})}};", qv = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Kv], { type: "text/javascript;charset=utf-8" });
29105
29122
  function Jv(e) {
29106
29123
  let t;
29107
29124
  try {
@@ -29166,7 +29183,7 @@ var dy = class {
29166
29183
  maxTextureSize: qi.DEFAULT_MAX_TEXTURE_SIZE,
29167
29184
  enableTextureCache: !0,
29168
29185
  maxConcurrentTextureTasks: Math.min(Fs(), 6),
29169
- maxSceneBytes: M_,
29186
+ maxSceneBytes: N_,
29170
29187
  enableTreeletOptimization: !1,
29171
29188
  treeletSize: 7,
29172
29189
  treeletOptimizationPasses: 1,
@@ -29175,7 +29192,7 @@ var dy = class {
29175
29192
  sceneCache: !0,
29176
29193
  sceneCacheMinBuildMs: Uv,
29177
29194
  ...e
29178
- }, this.triangleData = null, this.triangleFloats = null, this.triangleCount = 0, this.materials = [], this.maps = [], this.normalMaps = [], this.bumpMaps = [], this.roughnessMaps = [], this.metalnessMaps = [], this.emissiveMaps = [], this.displacementMaps = [], this.anisotropyMaps = [], this.transmissionMaps = [], this.clearcoatMaps = [], this.clearcoatRoughnessMaps = [], this.sheenColorMaps = [], this.sheenRoughnessMaps = [], this.iridescenceMaps = [], this.iridescenceThicknessMaps = [], this.specularIntensityMaps = [], this.specularColorMaps = [], this.directionalLights = [], this.cameras = [], this.spheres = [], this.bvhRoot = null, this.bvh = null, this.bvhData = null, this.bvhIndexChunks = null, this.bvhIndex = null, this.materialData = null, this.instanceTable = null, this._refitWorker = null, this._refitSharedBuffers = null, this._rebuildGeneration = 0, this._pendingRebuilds = /* @__PURE__ */ new Map(), this.srgbBucketTextures = null, this.linearBucketTextures = null, this.emissiveTriangleData = null, this.emissiveTriangleCount = 0, this.lightBVHNodeData = null, this.lightBVHNodeCount = 0, this.emissiveBitTrailMap = null, this._initProcessors(), this.isProcessing = !1, this.processingStage = null, this.memory = new R_(), this.memoryPreflight = null, this.performanceMetrics = {
29195
+ }, this.triangleData = null, this.triangleFloats = null, this.triangleCount = 0, this.materials = [], this.maps = [], this.normalMaps = [], this.bumpMaps = [], this.roughnessMaps = [], this.metalnessMaps = [], this.emissiveMaps = [], this.displacementMaps = [], this.anisotropyMaps = [], this.transmissionMaps = [], this.clearcoatMaps = [], this.clearcoatRoughnessMaps = [], this.sheenColorMaps = [], this.sheenRoughnessMaps = [], this.iridescenceMaps = [], this.iridescenceThicknessMaps = [], this.specularIntensityMaps = [], this.specularColorMaps = [], this.directionalLights = [], this.cameras = [], this.spheres = [], this.bvhRoot = null, this.bvh = null, this.bvhData = null, this.bvhIndexChunks = null, this.bvhIndex = null, this.materialData = null, this.instanceTable = null, this._refitWorker = null, this._refitSharedBuffers = null, this._rebuildGeneration = 0, this._pendingRebuilds = /* @__PURE__ */ new Map(), this.srgbBucketTextures = null, this.linearBucketTextures = null, this.emissiveTriangleData = null, this.emissiveTriangleCount = 0, this.lightBVHNodeData = null, this.lightBVHNodeCount = 0, this.emissiveBitTrailMap = null, this._initProcessors(), this.isProcessing = !1, this.processingStage = null, this.memory = new z_(), this.memoryPreflight = null, this.performanceMetrics = {
29179
29196
  textureCreationTime: 0,
29180
29197
  geometryExtractionTime: 0,
29181
29198
  bvhBuildTime: 0,
@@ -29199,13 +29216,13 @@ var dy = class {
29199
29216
  }), this.textureCreator = new pv({
29200
29217
  maxTextureSize: this.config.maxTextureSize,
29201
29218
  issues: this.config.issues
29202
- }), this.emissiveTriangleBuilder = new xv(), this.tlasBuilder = new T_(), this._tlasWorker = null, this._tlasWorkerFailed = !1;
29219
+ }), this.emissiveTriangleBuilder = new xv(), this.tlasBuilder = new E_(), this._tlasWorker = null, this._tlasWorkerFailed = !1;
29203
29220
  }
29204
29221
  _log(e, t) {
29205
29222
  t === void 0 ? ay.debug(e) : ay.debug(e, t);
29206
29223
  }
29207
29224
  _preflightMemory(e) {
29208
- let t = this.config.maxSceneBytes ?? 9663676416, n = this.geometryExtractor.surveyScene(e), r = I_(n);
29225
+ let t = this.config.maxSceneBytes ?? 9663676416, n = this.geometryExtractor.surveyScene(e), r = L_(n);
29209
29226
  if (this._progressive && (r.total -= r.bvh), this._streaming) {
29210
29227
  let t = ry + uy(e) * (Mi.FLOATS_PER_TRIANGLE * 4 + 44);
29211
29228
  r.total -= Math.max(0, r.triangles - t);
@@ -29213,9 +29230,9 @@ var dy = class {
29213
29230
  let i = {
29214
29231
  ...n,
29215
29232
  estimate: r,
29216
- safeBytes: j_,
29233
+ safeBytes: M_,
29217
29234
  maxBytes: t,
29218
- fits: r.total <= j_
29235
+ fits: r.total <= M_
29219
29236
  };
29220
29237
  if (this.memoryPreflight = i, r.total < 1610612736) return i;
29221
29238
  if (ay.debug(O.list([
@@ -29230,16 +29247,16 @@ var dy = class {
29230
29247
  maxBytes: t
29231
29248
  }), Error(e);
29232
29249
  }
29233
- return i.fits || this.config.issues?.warn(Ua.SCENE_MEMORY_BUDGET, `Scene needs about ${O.mb(r.total)} of CPU memory, above the ${O.mb(j_)} a fresh browser session can usually place. It may still load, but a long-running session will probably fail during BVH assembly; restarting the browser recovers the address space.`, {
29250
+ return i.fits || this.config.issues?.warn(Ua.SCENE_MEMORY_BUDGET, `Scene needs about ${O.mb(r.total)} of CPU memory, above the ${O.mb(M_)} a fresh browser session can usually place. It may still load, but a long-running session will probably fail during BVH assembly; restarting the browser recovers the address space.`, {
29234
29251
  ...n,
29235
29252
  estimate: r,
29236
- safeBytes: j_
29253
+ safeBytes: M_
29237
29254
  }), i;
29238
29255
  }
29239
29256
  _checkAssemblyHeadroom(e) {
29240
29257
  let t = e * 64;
29241
29258
  if (t < 1610612736) return !0;
29242
- let n = L_(Math.ceil(t * P_), { shared: Ja });
29259
+ let n = R_(Math.ceil(t * F_), { shared: Ja });
29243
29260
  return this.memoryPreflight && (this.memoryPreflight.assemblyProbed = n.placed), n.exhausted && this.config.issues?.warn(Ua.SCENE_MEMORY_BUDGET, `BVH assembly needs ${O.mb(t)} but only ${O.mb(n.placed)} could be allocated. Restarting the browser usually recovers the address space.`, {
29244
29261
  totalNodes: e,
29245
29262
  need: t,
@@ -29378,7 +29395,7 @@ var dy = class {
29378
29395
  for (let t of e) t();
29379
29396
  }, v = null, y = (e, t, n) => {
29380
29397
  let r = n.bvhData, i = new Float32Array(6);
29381
- __.rootAABB(oy(r)[0], v, t.start, t.count, i, 0), p.set(e, {
29398
+ v_.rootAABB(oy(r)[0], v, t.start, t.count, i, 0), p.set(e, {
29382
29399
  result: n,
29383
29400
  aabb: i
29384
29401
  });
@@ -29442,7 +29459,7 @@ var dy = class {
29442
29459
  let t = this.meshTriangleRanges;
29443
29460
  if (!t || t.length === 0) throw Error("No mesh triangle ranges available for TLAS/BLAS build");
29444
29461
  let n = this.instanceCount > 0, r = n ? this.instanceCount : t.length, i = this.instanceSource, a = n ? this.instanceMatrices : null, o = (e) => n ? i[e] : e;
29445
- this.instanceTable = new __(), this.instanceTable.allocate(r, t.length, a, n ? i : null), this.instanceTable.tplBakeInverse = this.bakeInverse;
29462
+ this.instanceTable = new v_(), this.instanceTable.allocate(r, t.length, a, n ? i : null), this.instanceTable.tplBakeInverse = this.bakeInverse;
29446
29463
  let s = this._streamed;
29447
29464
  this._streamed = null;
29448
29465
  let c = [], l = [], u = [], d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
@@ -29476,7 +29493,7 @@ var dy = class {
29476
29493
  t: o(e),
29477
29494
  triOffset: t.start,
29478
29495
  triCount: t.count
29479
- })).sort((e, t) => e.t - t.t), v = s ? null : await this._restoreBLASes(_, T_.nodeCountFor(r), p), y = s ? s.state : !v && this._progressive && this.triangles.chunks.length > 1 ? await this._beginProgressiveSpill(_) : null, b = y && !s ? (e, t, n) => this._onBLASBuilt(y, o(e), t, n) : null;
29496
+ })).sort((e, t) => e.t - t.t), v = s ? null : await this._restoreBLASes(_, E_.nodeCountFor(r), p), y = s ? s.state : !v && this._progressive && this.triangles.chunks.length > 1 ? await this._beginProgressiveSpill(_) : null, b = y && !s ? (e, t, n) => this._onBLASBuilt(y, o(e), t, n) : null;
29480
29497
  if (s) for (let [e, t] of s.templates) this.instanceTable.tplObjectAABB.set(t.aabb, e * 6);
29481
29498
  v && (c.length = 0, l.length = 0, Jr({
29482
29499
  status: "Restored stored BVHs",
@@ -29529,7 +29546,7 @@ var dy = class {
29529
29546
  progress: 72
29530
29547
  }), this._sampleMemory("BLASes built"), this.memory.mark("tlas");
29531
29548
  let E = performance.now(), D = this.instanceTable;
29532
- this.instanceTable.computeAABBs(this.triangles, { owners: !y }), this.instanceTable.assignOffsets(T_.nodeCountFor(D.count));
29549
+ this.instanceTable.computeAABBs(this.triangles, { owners: !y }), this.instanceTable.assignOffsets(E_.nodeCountFor(D.count));
29533
29550
  let k = this.instanceTable.totalNodeCount, A = await this._buildTLAS(D);
29534
29551
  this.performanceMetrics.tlasBuildTime = performance.now() - E, this.memory.mark("assemble");
29535
29552
  let ee = performance.now();
@@ -29601,13 +29618,13 @@ var dy = class {
29601
29618
  };
29602
29619
  }
29603
29620
  _isLargeMesh(e) {
29604
- return e.count >= $v && l_(e.count);
29621
+ return e.count >= $v && u_(e.count);
29605
29622
  }
29606
29623
  async _buildLargeBLAS(e, t) {
29607
29624
  if (e.count > ey) return this._buildSplitBLAS(e, t);
29608
29625
  let n = new Uint32Array(new SharedArrayBuffer(e.count * this.triangles.lanesPerRecord * 4));
29609
29626
  this.triangles.readRecords(e.start, e.count, n), this.triangles.release(e.start, e.count);
29610
- let r = await o_(n, this.config.bvhDepth, null, t);
29627
+ let r = await s_(n, this.config.bvhDepth, null, t);
29611
29628
  return r.reorderedTriangles ? (this.triangles.setRecords(e.start, r.reorderedTriangles), delete r.reorderedTriangles) : r.order && (this._writeInOrder(e.start, r.triangles, r.order), delete r.order, delete r.triangles), r;
29612
29629
  }
29613
29630
  async _buildSplitBLAS(e, t) {
@@ -29621,7 +29638,7 @@ var dy = class {
29621
29638
  }));
29622
29639
  let s = [], c = {};
29623
29640
  for (let { m: e, range: t, result: r } of await o.close()) {
29624
- r.aabb = new Float32Array(6), __.rootAABB(r.bvhData, n, t.start, t.count, r.aabb, 0), s[e] = r;
29641
+ r.aabb = new Float32Array(6), v_.rootAABB(r.bvhData, n, t.start, t.count, r.aabb, 0), s[e] = r;
29625
29642
  for (let [e, t] of Object.entries(r.splitStats ?? {})) typeof t == "number" && (c[e] = (c[e] ?? 0) + t);
29626
29643
  }
29627
29644
  return {
@@ -29915,7 +29932,7 @@ var dy = class {
29915
29932
  }
29916
29933
  u++, t?.(u), g(e);
29917
29934
  }, v = () => {
29918
- let e = Ls(Qg);
29935
+ let e = Ls($g);
29919
29936
  return e.onmessage = (t) => _(e, t), e.onerror = (e) => m(e), o.push(e), e;
29920
29937
  };
29921
29938
  return {
@@ -30158,7 +30175,7 @@ var dy = class {
30158
30175
  };
30159
30176
  }
30160
30177
  async refitBVH(e, t) {
30161
- if (this._geometryVersion = (this._geometryVersion ?? 0) + 1, !this.bvh || !this.triangles || !this.instanceTable) throw Error("No BVH data available for refit. Run buildBVH() first.");
30178
+ if (this._geometryVersion = (this._geometryVersion ?? 0) + 1, this._tlasLeafBoxesOf = null, !this.bvh || !this.triangles || !this.instanceTable) throw Error("No BVH data available for refit. Run buildBVH() first.");
30162
30179
  let n = this._meshSource(e, "position"), r = this._meshSource(t, "normal");
30163
30180
  if (!n) throw Error("SceneProcessor.refitBVH: positions are required.");
30164
30181
  if (this._refitWorker ||= Ls(Jv), !this._refitSharedBuffers) {
@@ -30178,29 +30195,40 @@ var dy = class {
30178
30195
  triRecordsPerChunk: this.triangles.recordsPerChunk
30179
30196
  });
30180
30197
  }
30181
- let i = this.instanceTable, a = Mi.FLOATS_PER_TRIANGLE, o = [];
30198
+ let i = this.instanceTable, a = Mi.FLOATS_PER_TRIANGLE, o = [], s = [], c = 0;
30182
30199
  for (let e = 0; e < i.count; e++) {
30183
30200
  if (!i.isSet[e] || !i.isOwner(e)) continue;
30201
+ c++;
30184
30202
  let t = n(e);
30185
30203
  if (!t) continue;
30186
- if (this._updateMeshTrianglePositions(e, t), r) {
30204
+ if (this._updateMeshTrianglePositions(e, t), s.push(i.blasOffsetOf(e), i.blasNodeCountOf(e)), r) {
30187
30205
  let t = r(e);
30188
30206
  t && this._patchMeshSmoothNormals(e, t);
30189
30207
  }
30190
- let s = i.triOffsetOf(e) * a, c = i.triCountOf(e) * a, l = o.at(-1);
30191
- l && l.offset + l.count === s ? l.count += c : o.push({
30192
- offset: s,
30193
- count: c
30208
+ let l = i.triOffsetOf(e) * a, u = i.triCountOf(e) * a, d = o.at(-1);
30209
+ d && d.offset + d.count === l ? d.count += u : o.push({
30210
+ offset: l,
30211
+ count: u
30194
30212
  });
30195
30213
  }
30214
+ let l = i.tlasNodeCount, u = l > 0 && s.length / 2 < c, d = u ? [this.computeTLASDirtyRange()] : null;
30215
+ for (let e = 0; u && e < s.length; e += 2) d.push({
30216
+ offset: s[e] * 16,
30217
+ count: s[e + 1] * 16
30218
+ });
30196
30219
  return new Promise((e, t) => {
30197
30220
  this._refitWorker.onmessage = (n) => {
30198
30221
  let r = n.data;
30199
30222
  r.type === "refitComplete" ? e({
30200
30223
  refitTimeMs: r.refitTimeMs,
30201
- triRanges: o
30224
+ triRanges: o,
30225
+ bvhRanges: d
30202
30226
  }) : r.type === "error" && t(Error(r.error));
30203
- }, this._refitWorker.postMessage({ type: "refit" });
30227
+ }, this._refitWorker.postMessage({
30228
+ type: "refit",
30229
+ blasRanges: u ? s : null,
30230
+ tlasNodeCount: l
30231
+ });
30204
30232
  });
30205
30233
  }
30206
30234
  _patchSmoothNormals(e) {
@@ -30219,7 +30247,7 @@ var dy = class {
30219
30247
  let r = this._meshSource(t, "position"), i = this._meshSource(n, "normal");
30220
30248
  if (!r) throw Error("SceneProcessor.refitBLASes: positions are required.");
30221
30249
  let a = performance.now();
30222
- this._blasRefitter ||= new Yg();
30250
+ this._blasRefitter ||= new Xg();
30223
30251
  let o = this.instanceTable;
30224
30252
  for (let t of e) {
30225
30253
  let e = this._placementOf(t);
@@ -30245,20 +30273,22 @@ var dy = class {
30245
30273
  }
30246
30274
  updateMeshTransforms(e) {
30247
30275
  if (!this.instanceTable || !this.bvh) throw Error("No TLAS/BLAS data available. Run buildBVH() first.");
30248
- let t = performance.now(), n = this.instanceTable, r = this._transformScratch ??= new Float32Array(16), i = 0;
30276
+ let t = performance.now(), n = this.instanceTable, r = this._transformScratch ??= new Float32Array(16);
30277
+ this._movedPlacements?.length !== n.count && (this._movedPlacements = new Uint8Array(n.count));
30278
+ let i = this._movedPlacements, a = 0;
30249
30279
  for (let t of e) {
30250
- let e = this.meshes?.[t], a = n.placementRunOf(t);
30251
- if (!e || !a) continue;
30280
+ let e = this.meshes?.[t], o = n.placementRunOf(t);
30281
+ if (!e || !o) continue;
30252
30282
  e.updateMatrixWorld(!0);
30253
- let o = e.matrixWorld.elements, s = e.isInstancedMesh ? this._ownInstanceMatrices(e) : null, c = n.tplBakeInverse?.get(n.sourceMesh[a.start]) ?? null;
30254
- for (let e = 0; e < a.count; e++) {
30255
- let t = a.start + e;
30256
- n.isSet[t] && (s ? (p_(o, s, e * 16, r), n.setPlacementMatrix(t, r)) : c ? (p_(o, c, 0, r), n.setPlacementMatrix(t, r)) : n.setPlacementMatrix(t, o), this._writeLeafMatrix(t), i++);
30283
+ let s = e.matrixWorld.elements, c = e.isInstancedMesh ? this._ownInstanceMatrices(e) : null, l = n.tplBakeInverse?.get(n.sourceMesh[o.start]) ?? null;
30284
+ for (let e = 0; e < o.count; e++) {
30285
+ let t = o.start + e;
30286
+ n.isSet[t] && (c ? (m_(s, c, e * 16, r), n.setPlacementMatrix(t, r)) : l ? (m_(s, l, 0, r), n.setPlacementMatrix(t, r)) : n.setPlacementMatrix(t, s), this._writeLeafMatrix(t), i[t] = 1, a++);
30257
30287
  }
30258
30288
  }
30259
- return this._refitTLAS(), {
30289
+ return this._refitTLAS(i), i.fill(0), {
30260
30290
  refitTimeMs: performance.now() - t,
30261
- placements: i
30291
+ placements: a
30262
30292
  };
30263
30293
  }
30264
30294
  _ownInstanceMatrices(e) {
@@ -30267,7 +30297,7 @@ var dy = class {
30267
30297
  }
30268
30298
  _writeLeafMatrix(e) {
30269
30299
  let t = this.instanceTable.tlasLeafIndex[e];
30270
- t < 0 || T_.writeLeafMatrix(this.bvh.chunkFor(t), this.bvhIndexChunks.chunkFor(t), this.bvh.baseOf(t), this.instanceTable.world, e);
30300
+ t < 0 || E_.writeLeafMatrix(this.bvh.chunkFor(t), this.bvhIndexChunks.chunkFor(t), this.bvh.baseOf(t), this.instanceTable.world, e);
30271
30301
  }
30272
30302
  computeTLASDirtyRange() {
30273
30303
  return {
@@ -30391,7 +30421,7 @@ var dy = class {
30391
30421
  let n = new Float64Array(t * 6);
30392
30422
  e.writeWorldAABBs(n);
30393
30423
  let { tlasData: r, nodeCount: i } = await this._runTLASWorker(n, t);
30394
- return T_.fillLeaves(r, i, e), r;
30424
+ return E_.fillLeaves(r, i, e), r;
30395
30425
  } catch (e) {
30396
30426
  this._tlasWorkerFailed = !0, ay.warn(`TLAS worker unavailable (${e.message}); building on the main thread`);
30397
30427
  }
@@ -30414,6 +30444,7 @@ var dy = class {
30414
30444
  });
30415
30445
  }
30416
30446
  _setBVHData(e) {
30447
+ this._tlasLeafBoxesOf = null;
30417
30448
  let t = e ? e instanceof Qa ? e : Qa.adopt([e], e.length / 16, 16, e.length / 16) : null;
30418
30449
  this.bvh = t, t && this._foldLeaves && (t.foldedLeaves = !0), this.bvhIndexChunks = t ? t.viewAs(Uint32Array) : null, this.bvhData = t ? t.single : null, this.bvhIndex = this.bvhIndexChunks ? this.bvhIndexChunks.single : null;
30419
30450
  }
@@ -30422,7 +30453,7 @@ var dy = class {
30422
30453
  this.triangles = n, this.triangleFloatChunks = n ? n.viewAs(Float32Array) : null, this.triangleData = n ? n.single : null, this.triangleFloats = this.triangleFloatChunks ? this.triangleFloatChunks.single : null;
30423
30454
  }
30424
30455
  _updateMeshTrianglePositions(e, t) {
30425
- let n = Mi.POSITION_A_OFFSET, r = Mi.POSITION_B_OFFSET, i = Mi.POSITION_C_OFFSET, a = Mi.NORMAL_A_PACKED_OFFSET, o = Mi.NORMAL_B_PACKED_OFFSET, s = Mi.NORMAL_C_PACKED_OFFSET, c = this.triangles, l = this.triangleFloatChunks, u = this.instanceTable, d = u.bvhToOriginalOf(e), f = u.triOffsetOf(e), p = u.triCountOf(e), m = u.matrixInverseOf(e), h = m_(m);
30456
+ let n = Mi.POSITION_A_OFFSET, r = Mi.POSITION_B_OFFSET, i = Mi.POSITION_C_OFFSET, a = Mi.NORMAL_A_PACKED_OFFSET, o = Mi.NORMAL_B_PACKED_OFFSET, s = Mi.NORMAL_C_PACKED_OFFSET, c = this.triangles, l = this.triangleFloatChunks, u = this.instanceTable, d = u.bvhToOriginalOf(e), f = u.triOffsetOf(e), p = u.triCountOf(e), m = u.matrixInverseOf(e), h = h_(m);
30426
30457
  for (let e = 0; e < p; e++) {
30427
30458
  let u = d ? d[e] : e, p = f + e, g = l.chunkFor(p), _ = c.chunkFor(p), v = c.baseOf(p), y = u * 9, b = t[y], x = t[y + 1], S = t[y + 2], C = t[y + 3], w = t[y + 4], T = t[y + 5], E = t[y + 6], D = t[y + 7], O = t[y + 8];
30428
30459
  if (!h) {
@@ -30451,7 +30482,7 @@ var dy = class {
30451
30482
  this._patchNormalsRange(t, n.triOffsetOf(e), n.triCountOf(e), n.matrixWorldOf(e), n.bvhToOriginalOf(e));
30452
30483
  }
30453
30484
  _patchNormalsRange(e, t, n, r, i) {
30454
- let a = Mi.NORMAL_A_PACKED_OFFSET, o = Mi.NORMAL_B_PACKED_OFFSET, s = Mi.NORMAL_C_PACKED_OFFSET, c = r, l = !c || m_(c), u = [
30485
+ let a = Mi.NORMAL_A_PACKED_OFFSET, o = Mi.NORMAL_B_PACKED_OFFSET, s = Mi.NORMAL_C_PACKED_OFFSET, c = r, l = !c || h_(c), u = [
30455
30486
  a,
30456
30487
  o,
30457
30488
  s
@@ -30469,22 +30500,23 @@ var dy = class {
30469
30500
  }
30470
30501
  }
30471
30502
  }
30472
- _refitTLAS() {
30473
- let e = this.instanceTable.tlasNodeCount;
30474
- (!this._tlasBounds || this._tlasBounds.length < e * 6) && (this._tlasBounds = new Float32Array(e * 6));
30475
- let t = this.instanceTable;
30476
- for (let n = e - 1; n >= 0; n--) {
30477
- let e = this.bvhIndexChunks.chunkFor(n), r = this.bvh.chunkFor(n), i = this.bvh.baseOf(n), a = e[i + 3];
30478
- if (a === Ui.BLAS_POINTER_LEAF) {
30479
- let r = e[i + 1] & Hi;
30480
- r < t.count && t.writeWorldAABB(r, this._tlasBounds, n * 6);
30481
- } else if (a < Ui.TRIANGLE_LEAF) {
30482
- let t = a, o = e[i + 7], s = t * 6, c = o * 6, l = this._tlasBounds;
30483
- r[i] = l[s], r[i + 1] = l[s + 1], r[i + 2] = l[s + 2], r[i + 4] = l[s + 3], r[i + 5] = l[s + 4], r[i + 6] = l[s + 5], r[i + 8] = l[c], r[i + 9] = l[c + 1], r[i + 10] = l[c + 2], r[i + 12] = l[c + 3], r[i + 13] = l[c + 4], r[i + 14] = l[c + 5];
30484
- let u = n * 6;
30485
- l[u] = Math.min(l[s], l[c]), l[u + 1] = Math.min(l[s + 1], l[c + 1]), l[u + 2] = Math.min(l[s + 2], l[c + 2]), l[u + 3] = Math.max(l[s + 3], l[c + 3]), l[u + 4] = Math.max(l[s + 4], l[c + 4]), l[u + 5] = Math.max(l[s + 5], l[c + 5]);
30503
+ _refitTLAS(e = null) {
30504
+ let t = this.instanceTable.tlasNodeCount;
30505
+ (!this._tlasBounds || this._tlasBounds.length < t * 6) && (this._tlasBounds = new Float32Array(t * 6), this._tlasLeafBoxesOf = null);
30506
+ let n = this.instanceTable, r = e && this._tlasLeafBoxesOf === n;
30507
+ for (let i = t - 1; i >= 0; i--) {
30508
+ let t = this.bvhIndexChunks.chunkFor(i), a = this.bvh.chunkFor(i), o = this.bvh.baseOf(i), s = t[o + 3];
30509
+ if (s === Ui.BLAS_POINTER_LEAF) {
30510
+ let a = t[o + 1] & Hi;
30511
+ a < n.count && !(r && !e[a]) && n.writeWorldAABB(a, this._tlasBounds, i * 6);
30512
+ } else if (s < Ui.TRIANGLE_LEAF) {
30513
+ let e = s, n = t[o + 7], r = e * 6, c = n * 6, l = this._tlasBounds;
30514
+ a[o] = l[r], a[o + 1] = l[r + 1], a[o + 2] = l[r + 2], a[o + 4] = l[r + 3], a[o + 5] = l[r + 4], a[o + 6] = l[r + 5], a[o + 8] = l[c], a[o + 9] = l[c + 1], a[o + 10] = l[c + 2], a[o + 12] = l[c + 3], a[o + 13] = l[c + 4], a[o + 14] = l[c + 5];
30515
+ let u = i * 6;
30516
+ l[u] = Math.min(l[r], l[c]), l[u + 1] = Math.min(l[r + 1], l[c + 1]), l[u + 2] = Math.min(l[r + 2], l[c + 2]), l[u + 3] = Math.max(l[r + 3], l[c + 3]), l[u + 4] = Math.max(l[r + 4], l[c + 4]), l[u + 5] = Math.max(l[r + 5], l[c + 5]);
30486
30517
  }
30487
30518
  }
30519
+ this._tlasLeafBoxesOf = n;
30488
30520
  }
30489
30521
  scheduleBackgroundRebuild(e, t) {
30490
30522
  if (!this.instanceTable || !this.triangles) return;
@@ -30534,7 +30566,7 @@ var dy = class {
30534
30566
  let n = this.instanceTable.entryAt(e);
30535
30567
  if (!n || !this.instanceTable.isOwner(e)) continue;
30536
30568
  let i = this._pendingRebuilds.get(e);
30537
- i && i.terminate(), r(e, n, Ls(Qg));
30569
+ i && i.terminate(), r(e, n, Ls($g));
30538
30570
  }
30539
30571
  }
30540
30572
  _swapBLAS(e, t, n, r) {
@@ -31166,12 +31198,19 @@ var vy = class {
31166
31198
  updateTriangleData(e, t) {
31167
31199
  e?.chunks?.length > 1 ? this._triangleRecords = e : e && (this._triangleFlat = e.chunks ? e.chunks[0] : e), t ? this.updateBufferRanges(t, []) : this._uploadTriangles(0, this._triangleRecordCount);
31168
31200
  }
31169
- updateBVHData(e) {
31201
+ updateBVHData(e, t) {
31170
31202
  if (this._bvhRecords) {
31171
- Nr(this.renderer, this.bvhStorageAttr, this._bvhRecords.chunks);
31203
+ e?.chunks?.length > 1 && (this._bvhRecords = e), t ? this.updateBufferRanges([], t) : Nr(this.renderer, this.bvhStorageAttr, this._bvhRecords.chunks);
31204
+ return;
31205
+ }
31206
+ let n = e?.chunks ? e.chunks[0] : e;
31207
+ if (!t) {
31208
+ this._updateStorageBuffer(this.bvhStorageAttr, n);
31172
31209
  return;
31173
31210
  }
31174
- this._updateStorageBuffer(this.bvhStorageAttr, e?.chunks ? e.chunks[0] : e);
31211
+ let r = this.bvhStorageAttr?.array;
31212
+ if (n && r && n !== r) for (let e of t) r.set(n.subarray(e.offset, e.offset + e.count), e.offset);
31213
+ this.updateBufferRanges([], t);
31175
31214
  }
31176
31215
  updateBufferRanges(e, t) {
31177
31216
  if (this.triangleGeoAttr && e.length > 0) {
@@ -33896,7 +33935,7 @@ var Zx = a("wavefront"), Qx = 256, $x = [
33896
33935
  }
33897
33936
  _computePathBudget() {
33898
33937
  if (this._pathBudgetOverride > 0) return this._pathBudgetOverride;
33899
- let e = this.renderer?.backend?.device?.limits, t = e?.maxStorageBufferBindingSize || 128 * 1024 * 1024, n = e?.maxBufferSize || t, r = Math.floor(t * .9 / 112), i = N_(this.hostMemoryGB).gb * 1024 * 1024 * 1024, a = Math.min(i * .25, n * 4), o = Math.floor(a / 192), s = Math.min(r, o, 2048 * 2048);
33938
+ let e = this.renderer?.backend?.device?.limits, t = e?.maxStorageBufferBindingSize || 128 * 1024 * 1024, n = e?.maxBufferSize || t, r = Math.floor(t * .9 / 112), i = P_(this.hostMemoryGB).gb * 1024 * 1024 * 1024, a = Math.min(i * .25, n * 4), o = Math.floor(a / 192), s = Math.min(r, o, 2048 * 2048);
33900
33939
  return s = Math.max(262144, s), s;
33901
33940
  }
33902
33941
  _updateChunkLayout() {
@@ -43458,7 +43497,18 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43458
43497
  // survives the denoise.
43459
43498
  textureStore( dst, vec2<u32>( px, py ), vec4<f32>( src[ si ].xyz / scaleBuf[ 0 ], inColor[ si ].w ) );
43460
43499
  }
43461
- `, Sk = class extends en {
43500
+ `, Sk = 8, Ck = `
43501
+ @group(0) @binding(0) var src: texture_2d<f32>;
43502
+ @group(0) @binding(1) var<storage, read_write> dst: array<vec4<f32>>;
43503
+ @group(0) @binding(2) var<uniform> size: vec2<u32>;
43504
+
43505
+ @compute @workgroup_size(${Sk}, ${Sk})
43506
+ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43507
+
43508
+ if ( gid.x >= size.x || gid.y >= size.y ) { return; }
43509
+ dst[ gid.y * size.x + gid.x ] = textureLoad( src, gid.xy, 0 );
43510
+ }
43511
+ `, wk = class extends en {
43462
43512
  constructor(e, t = {}) {
43463
43513
  if (super(), !e) throw Error("OIDNDenoiser requires a renderer");
43464
43514
  this.renderer = e, this._renderWidth = e.domElement.width, this._renderHeight = e.domElement.height, this.backendParamsGetter = t.backendParams || null, this.getGPUTextures = t.getGPUTextures || null, this.gpuDevice = null, this._gpuInputBuffers = {
@@ -43468,7 +43518,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43468
43518
  }, this._gpuInputBufferSize = {
43469
43519
  width: 0,
43470
43520
  height: 0
43471
- }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._lumReducePipeline = null, this._lumFinalizePipeline = null, this._lumLayout = null, this._lumBindGroup = null, this._lumPartials = null, this._lumParams = null, this._inputScaleBuffer = null, this._colorScalePipeline = null, this._colorScaleBindGroup = null, this._unpackPipeline = null, this._outGPUTexture = null, this._outTexture = null, this._outTexSize = {
43521
+ }, this._packPipeline = null, this._packLayout = null, this._packParams = null, this._lumReducePipeline = null, this._lumFinalizePipeline = null, this._lumLayout = null, this._lumBindGroup = null, this._lumPartials = null, this._lumParams = null, this._inputScaleBuffer = null, this._colorScalePipeline = null, this._colorScaleBindGroup = null, this._unpackPipeline = null, this._outGPUTexture = null, this._outTexture = null, this._outTexSize = {
43472
43522
  width: 0,
43473
43523
  height: 0
43474
43524
  }, this.config = {
@@ -43603,45 +43653,13 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43603
43653
  if (!r?.color) return sk.warn("GPU textures not ready yet"), !1;
43604
43654
  let i = this.gpuDevice;
43605
43655
  if (!i) return sk.warn("gpuDevice not available"), !1;
43606
- this._ensureGPUInputBuffers(t, n);
43607
- let a = i.createCommandEncoder({ label: "oidn-tex-to-buf" }), o = t * 16, s = this._gpuInputPaddedRowBytes, c = s > o, l = this._gpuInputPadBuffer, u = (e, r) => {
43608
- if (!c) a.copyTextureToBuffer({
43609
- texture: e,
43610
- mipLevel: 0
43611
- }, {
43612
- buffer: r,
43613
- offset: 0,
43614
- bytesPerRow: o,
43615
- rowsPerImage: n
43616
- }, {
43617
- width: t,
43618
- height: n,
43619
- depthOrArrayLayers: 1
43620
- });
43621
- else {
43622
- a.copyTextureToBuffer({
43623
- texture: e,
43624
- mipLevel: 0
43625
- }, {
43626
- buffer: l,
43627
- offset: 0,
43628
- bytesPerRow: s,
43629
- rowsPerImage: n
43630
- }, {
43631
- width: t,
43632
- height: n,
43633
- depthOrArrayLayers: 1
43634
- });
43635
- for (let e = 0; e < n; e++) a.copyBufferToBuffer(l, e * s, r, e * o, o);
43636
- }
43637
- };
43638
- u(r.color, this._gpuInputBuffers.color), u(r.albedo, this._gpuInputBuffers.albedo), u(r.normal, this._gpuInputBuffers.normal), i.queue.submit([a.finish()]), this._computeInputScale(i, t * n), this._applyColorScale(i, t * n), !e && !this._hasOutput && this._unpackToTexture(this._gpuInputBuffers.color, t, {
43656
+ this._ensureGPUInputBuffers(t, n), this._copyInputs(i, r, t, n), this._computeInputScale(i, t * n), this._applyColorScale(i, t * n), !e && !this._hasOutput && this._unpackToTexture(this._gpuInputBuffers.color, t, {
43639
43657
  x: 0,
43640
43658
  y: 0,
43641
43659
  width: t,
43642
43660
  height: n
43643
43661
  }, !1);
43644
- let d = {
43662
+ let a = {
43645
43663
  color: {
43646
43664
  data: this._gpuInputBuffers.color,
43647
43665
  width: t,
@@ -43658,7 +43676,41 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43658
43676
  height: n
43659
43677
  }
43660
43678
  };
43661
- return this._executeWithAbortGPU(d, e);
43679
+ return this._executeWithAbortGPU(a, e);
43680
+ }
43681
+ _copyInputs(e, t, n, r) {
43682
+ let i = e.createCommandEncoder({ label: "oidn-tex-to-buf" }), a = n * 16, o = a % 256 == 0 ? null : this._beginPack(e, i, n, r), s = (t, s) => {
43683
+ o ? (o.setBindGroup(0, e.createBindGroup({
43684
+ layout: this._packLayout,
43685
+ entries: [
43686
+ {
43687
+ binding: 0,
43688
+ resource: t.createView()
43689
+ },
43690
+ {
43691
+ binding: 1,
43692
+ resource: { buffer: s }
43693
+ },
43694
+ {
43695
+ binding: 2,
43696
+ resource: { buffer: this._packParams }
43697
+ }
43698
+ ]
43699
+ })), o.dispatchWorkgroups(Math.ceil(n / Sk), Math.ceil(r / Sk))) : i.copyTextureToBuffer({
43700
+ texture: t,
43701
+ mipLevel: 0
43702
+ }, {
43703
+ buffer: s,
43704
+ offset: 0,
43705
+ bytesPerRow: a,
43706
+ rowsPerImage: r
43707
+ }, {
43708
+ width: n,
43709
+ height: r,
43710
+ depthOrArrayLayers: 1
43711
+ });
43712
+ };
43713
+ s(t.color, this._gpuInputBuffers.color), s(t.albedo, this._gpuInputBuffers.albedo), s(t.normal, this._gpuInputBuffers.normal), o?.end(), e.queue.submit([i.finish()]);
43662
43714
  }
43663
43715
  _ensureGPUInputBuffers(e, t) {
43664
43716
  let { width: n, height: r } = this._gpuInputBufferSize;
@@ -43681,19 +43733,51 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43681
43733
  width: e,
43682
43734
  height: t
43683
43735
  };
43684
- let s = e * 16, c = Math.ceil(s / 256) * 256;
43685
- c === s ? this._gpuInputPaddedRowBytes = s : (this._gpuInputPadBuffer = i.createBuffer({
43686
- label: "oidn-in-pad",
43687
- size: c * t,
43688
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
43689
- }), this._gpuInputPaddedRowBytes = c);
43736
+ }
43737
+ _beginPack(e, t, n, r) {
43738
+ this._packPipeline ||= (this._packLayout = e.createBindGroupLayout({
43739
+ label: "oidn-pack",
43740
+ entries: [
43741
+ {
43742
+ binding: 0,
43743
+ visibility: GPUShaderStage.COMPUTE,
43744
+ texture: { sampleType: "unfilterable-float" }
43745
+ },
43746
+ {
43747
+ binding: 1,
43748
+ visibility: GPUShaderStage.COMPUTE,
43749
+ buffer: { type: "storage" }
43750
+ },
43751
+ {
43752
+ binding: 2,
43753
+ visibility: GPUShaderStage.COMPUTE,
43754
+ buffer: { type: "uniform" }
43755
+ }
43756
+ ]
43757
+ }), e.createComputePipeline({
43758
+ label: "oidn-pack",
43759
+ layout: e.createPipelineLayout({ bindGroupLayouts: [this._packLayout] }),
43760
+ compute: {
43761
+ module: e.createShaderModule({
43762
+ label: "oidn-pack",
43763
+ code: Ck
43764
+ }),
43765
+ entryPoint: "main"
43766
+ }
43767
+ })), this._packParams || (this._packParams = e.createBuffer({
43768
+ label: "oidn-pack-size",
43769
+ size: 8,
43770
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
43771
+ }), e.queue.writeBuffer(this._packParams, 0, new Uint32Array([n, r])));
43772
+ let i = t.beginComputePass({ label: "oidn-pack" });
43773
+ return i.setPipeline(this._packPipeline), i;
43690
43774
  }
43691
43775
  _destroyGPUInputBuffers() {
43692
- this._gpuInputBuffers.color?.destroy(), this._gpuInputBuffers.albedo?.destroy(), this._gpuInputBuffers.normal?.destroy(), this._gpuInputPadBuffer?.destroy(), this._colorScaleBindGroup = null, this._lumBindGroup = null, this._lumPartials?.destroy(), this._lumPartials = null, this._lumParams?.destroy(), this._lumParams = null, this._inputScaleBuffer?.destroy(), this._inputScaleBuffer = null, this._gpuInputBuffers = {
43776
+ this._gpuInputBuffers.color?.destroy(), this._gpuInputBuffers.albedo?.destroy(), this._gpuInputBuffers.normal?.destroy(), this._packParams?.destroy(), this._colorScaleBindGroup = null, this._lumBindGroup = null, this._lumPartials?.destroy(), this._lumPartials = null, this._lumParams?.destroy(), this._lumParams = null, this._inputScaleBuffer?.destroy(), this._inputScaleBuffer = null, this._gpuInputBuffers = {
43693
43777
  color: null,
43694
43778
  albedo: null,
43695
43779
  normal: null
43696
- }, this._gpuInputPadBuffer = null, this._gpuInputPaddedRowBytes = 0, this._gpuInputBufferSize = {
43780
+ }, this._packParams = null, this._gpuInputBufferSize = {
43697
43781
  width: 0,
43698
43782
  height: 0
43699
43783
  };
@@ -43839,7 +43923,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43839
43923
  }
43840
43924
  gpuBytes() {
43841
43925
  let { color: e, albedo: t, normal: n } = this._gpuInputBuffers, r = this._outGPUTexture ? this._outTexSize.width * this._outTexSize.height * 8 : 0;
43842
- return (e?.size ?? 0) + (t?.size ?? 0) + (n?.size ?? 0) + (this._gpuInputPadBuffer?.size ?? 0) + r;
43926
+ return (e?.size ?? 0) + (t?.size ?? 0) + (n?.size ?? 0) + r;
43843
43927
  }
43844
43928
  _ensureOutputTexture(e, t, n) {
43845
43929
  if (this._outGPUTexture && this._outTexSize.width === t && this._outTexSize.height === n) return;
@@ -43993,7 +44077,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
43993
44077
  dispose() {
43994
44078
  this.abort(), this.unet?.dispose(), this._destroyGPUInputBuffers(), this._releaseOutputTexture(), this._colorScalePipeline = null, this._lumReducePipeline = null, this._lumFinalizePipeline = null, this._lumLayout = null, this._unpackPipeline = null, this.unet = null, this._weights.clear(), this.state.abortController = null, this.removeAllListeners?.(), sk.debug("disposed");
43995
44079
  }
43996
- }, Ck = Object.freeze({
44080
+ }, Tk = Object.freeze({
43997
44081
  maxLength: 8,
43998
44082
  smoothLength: 2,
43999
44083
  roughStart: .45,
@@ -44001,7 +44085,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44001
44085
  depthTolerance: .05,
44002
44086
  normalTolerance: .8,
44003
44087
  movedLength: 2
44004
- }), wk = 8, Tk = 304, Ek = 16, Dk = 1, Ok = 2, kk = 4, Ak = 1073741824, jk = "\nstruct Params {\n size: vec2<u32>,\n reset: u32,\n flags: u32,\n maxLength: f32,\n smoothLength: f32,\n depthTolerance: f32,\n normalTolerance: f32,\n roughStart: f32,\n roughEnd: f32,\n samples: f32,\n historyScale: f32,\n camWorld: mat4x4<f32>,\n projInv: mat4x4<f32>,\n prevViewProj: mat4x4<f32>,\n prevCamPos: vec4<f32>,\n moved: vec4<u32>,\n movedLength: f32,\n prevCamDir: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> P: Params;\n\nfn finite3( v: vec3<f32> ) -> bool {\n let e = bitcast<vec3<u32>>( v ) & vec3<u32>( 0x7f800000u );\n return all( e != vec3<u32>( 0x7f800000u ) );\n}\n\n// [0,1]-encoded in and out, renormalised like FinalWrite's clean aux.\nfn mixNormal( h: vec3<f32>, c: vec3<f32>, t: f32 ) -> vec3<f32> {\n let m = mix( h * 2.0 - 1.0, c * 2.0 - 1.0, t );\n let l = length( m );\n return select( c, m / l * 0.5 + 0.5, l > 1e-4 );\n}\n", Mk = jk + `
44088
+ }), Ek = 8, Dk = 304, Ok = 16, kk = 1, Ak = 2, jk = 4, Mk = 1073741824, Nk = "\nstruct Params {\n size: vec2<u32>,\n reset: u32,\n flags: u32,\n maxLength: f32,\n smoothLength: f32,\n depthTolerance: f32,\n normalTolerance: f32,\n roughStart: f32,\n roughEnd: f32,\n samples: f32,\n historyScale: f32,\n camWorld: mat4x4<f32>,\n projInv: mat4x4<f32>,\n prevViewProj: mat4x4<f32>,\n prevCamPos: vec4<f32>,\n moved: vec4<u32>,\n movedLength: f32,\n prevCamDir: vec4<f32>,\n};\n\n@group(0) @binding(0) var<uniform> P: Params;\n\nfn finite3( v: vec3<f32> ) -> bool {\n let e = bitcast<vec3<u32>>( v ) & vec3<u32>( 0x7f800000u );\n return all( e != vec3<u32>( 0x7f800000u ) );\n}\n\n// [0,1]-encoded in and out, renormalised like FinalWrite's clean aux.\nfn mixNormal( h: vec3<f32>, c: vec3<f32>, t: f32 ) -> vec3<f32> {\n let m = mix( h * 2.0 - 1.0, c * 2.0 - 1.0, t );\n let l = length( m );\n return select( c, m / l * 0.5 + 0.5, l > 1e-4 );\n}\n", Pk = Nk + `
44005
44089
  @group(0) @binding(1) var geoCur: texture_2d<f32>;
44006
44090
  @group(0) @binding(2) var geoPrev: texture_2d<f32>;
44007
44091
  @group(0) @binding(3) var<storage, read_write> picked: array<i32>;
@@ -44027,7 +44111,7 @@ fn movedIndex( leaf: u32 ) -> i32 {
44027
44111
 
44028
44112
  }
44029
44113
 
44030
- @compute @workgroup_size(${wk}, ${wk})
44114
+ @compute @workgroup_size(${Ek}, ${Ek})
44031
44115
  fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44032
44116
 
44033
44117
  if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
@@ -44042,7 +44126,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44042
44126
  let size = vec2<f32>( P.size );
44043
44127
  let uv = ( vec2<f32>( gid.xy ) + 0.5 ) / size;
44044
44128
  // Depth is along the ray: from the camera, or from its image plane when orthographic.
44045
- let ortho = ( P.flags & ${kk}u ) != 0u;
44129
+ let ortho = ( P.flags & ${jk}u ) != 0u;
44046
44130
  let ndc = vec2<f32>( uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0 );
44047
44131
  var origin = P.camWorld[ 3 ].xyz;
44048
44132
  var dir: vec3<f32>;
@@ -44066,7 +44150,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44066
44150
  let toPrev = movedToPrev[ u32( m ) ];
44067
44151
  wp = ( toPrev * vec4<f32>( wp, 1.0 ) ).xyz;
44068
44152
  n = normalize( ( toPrev * vec4<f32>( n, 0.0 ) ).xyz );
44069
- movedFlag = ${Ak};
44153
+ movedFlag = ${Mk};
44070
44154
 
44071
44155
  }
44072
44156
 
@@ -44103,7 +44187,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44103
44187
  if ( pick >= 0 ) { atomicAdd( &copies[ u32( pick ) ], 1u ); }
44104
44188
 
44105
44189
  }
44106
- `, Nk = jk + `
44190
+ `, Fk = Nk + `
44107
44191
  @group(0) @binding(1) var curColor: texture_2d<f32>;
44108
44192
  @group(0) @binding(2) var curAlbedo: texture_2d<f32>;
44109
44193
  @group(0) @binding(3) var curNormal: texture_2d<f32>;
@@ -44117,7 +44201,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44117
44201
  @group(0) @binding(11) var outAlbedo: texture_storage_2d<rgba32float, write>;
44118
44202
  @group(0) @binding(12) var outNormal: texture_storage_2d<rgba32float, write>;
44119
44203
 
44120
- @compute @workgroup_size(${wk}, ${wk})
44204
+ @compute @workgroup_size(${Ek}, ${Ek})
44121
44205
  fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44122
44206
 
44123
44207
  if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
@@ -44133,8 +44217,8 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44133
44217
  var ha = ca.xyz;
44134
44218
  var hn = cn.xyz;
44135
44219
  let raw = picked[ gid.y * P.size.x + gid.x ];
44136
- let movedPx = raw >= 0 && ( raw & ${Ak} ) != 0;
44137
- let pick = select( raw, raw & ~${Ak}, raw >= 0 );
44220
+ let movedPx = raw >= 0 && ( raw & ${Mk} ) != 0;
44221
+ let pick = select( raw, raw & ~${Mk}, raw >= 0 );
44138
44222
 
44139
44223
  if ( pick >= 0 ) {
44140
44224
 
@@ -44148,7 +44232,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44148
44232
  ha = a.xyz;
44149
44233
  hn = textureLoad( histNormal, q, 0 ).xyz;
44150
44234
  len = a.w;
44151
- if ( ( P.flags & ${Ok}u ) != 0u ) { len = len / f32( max( copies[ u32( pick ) ], 1u ) ); }
44235
+ if ( ( P.flags & ${Ak}u ) != 0u ) { len = len / f32( max( copies[ u32( pick ) ], 1u ) ); }
44152
44236
 
44153
44237
  }
44154
44238
 
@@ -44162,11 +44246,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44162
44246
 
44163
44247
  textureStore( outColor, p, vec4<f32>( mix( hc, cur.xyz, t ), cur.w ) );
44164
44248
  textureStore( outAlbedo, p, vec4<f32>( mix( ha, ca.xyz, t ), newLen ) );
44165
- let n = select( cn.xyz, mixNormal( hn, cn.xyz, t ), ( P.flags & ${Dk}u ) != 0u );
44249
+ let n = select( cn.xyz, mixNormal( hn, cn.xyz, t ), ( P.flags & ${kk}u ) != 0u );
44166
44250
  textureStore( outNormal, p, vec4<f32>( n, cn.w ) );
44167
44251
 
44168
44252
  }
44169
- `, Pk = jk + `
44253
+ `, Ik = Nk + `
44170
44254
  @group(0) @binding(1) var accColor: texture_2d<f32>;
44171
44255
  @group(0) @binding(2) var accAlbedo: texture_2d<f32>;
44172
44256
  @group(0) @binding(3) var accNormal: texture_2d<f32>;
@@ -44177,7 +44261,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44177
44261
  @group(0) @binding(8) var outAlbedo: texture_storage_2d<rgba32float, write>;
44178
44262
  @group(0) @binding(9) var outNormal: texture_storage_2d<rgba32float, write>;
44179
44263
 
44180
- @compute @workgroup_size(${wk}, ${wk})
44264
+ @compute @workgroup_size(${Ek}, ${Ek})
44181
44265
  fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44182
44266
 
44183
44267
  if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
@@ -44211,32 +44295,32 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44211
44295
  let t = P.samples / max( k + P.samples, 1e-6 );
44212
44296
  textureStore( outColor, p, vec4<f32>( mix( hc, ac.xyz, t ), ac.w ) );
44213
44297
  textureStore( outAlbedo, p, vec4<f32>( mix( ha, aa.xyz, t ), min( k + P.samples, P.maxLength ) ) );
44214
- let n = select( an.xyz, mixNormal( hn, an.xyz, t ), ( P.flags & ${Dk}u ) != 0u );
44298
+ let n = select( an.xyz, mixNormal( hn, an.xyz, t ), ( P.flags & ${kk}u ) != 0u );
44215
44299
  textureStore( outNormal, p, vec4<f32>( n, an.w ) );
44216
44300
 
44217
44301
  }
44218
- `, Fk = (e) => ({
44302
+ `, Lk = (e) => ({
44219
44303
  binding: e,
44220
44304
  visibility: GPUShaderStage.COMPUTE,
44221
44305
  texture: { sampleType: "unfilterable-float" }
44222
- }), Ik = (e) => ({
44306
+ }), Rk = (e) => ({
44223
44307
  binding: e,
44224
44308
  visibility: GPUShaderStage.COMPUTE,
44225
44309
  storageTexture: {
44226
44310
  access: "write-only",
44227
44311
  format: "rgba32float"
44228
44312
  }
44229
- }), Lk = (e, t) => ({
44313
+ }), zk = (e, t) => ({
44230
44314
  binding: e,
44231
44315
  visibility: GPUShaderStage.COMPUTE,
44232
44316
  buffer: { type: t }
44233
- }), Rk = class {
44317
+ }), Bk = class {
44234
44318
  constructor(e) {
44235
44319
  this.device = e, this.settings = {
44236
- ...Ck,
44320
+ ...Tk,
44237
44321
  cleanAux: !1,
44238
44322
  splitCopies: !0
44239
- }, this.valid = !1, this.width = 0, this.height = 0, this._sets = null, this._current = 0, this._picked = null, this._copies = null, this._paramsBuffer = null, this._pipelines = null, this._movedLeaves = null, this._movedToPrev = null, this._movedCapacity = 0, this._movedCount = 0, this._paramData = new ArrayBuffer(Tk), this._paramU32 = new Uint32Array(this._paramData), this._paramF32 = new Float32Array(this._paramData), this._prevViewProj = new Float32Array(16), this._prevCamPos = new Float32Array(4), this._prevCamDir = new Float32Array(4);
44323
+ }, this.valid = !1, this.width = 0, this.height = 0, this._sets = null, this._current = 0, this._picked = null, this._copies = null, this._paramsBuffer = null, this._pipelines = null, this._movedLeaves = null, this._movedToPrev = null, this._movedCapacity = 0, this._movedCount = 0, this._paramData = new ArrayBuffer(Dk), this._paramU32 = new Uint32Array(this._paramData), this._paramF32 = new Float32Array(this._paramData), this._prevViewProj = new Float32Array(16), this._prevCamPos = new Float32Array(4), this._prevCamDir = new Float32Array(4);
44240
44324
  }
44241
44325
  get textures() {
44242
44326
  return this.valid ? this._sets[this._current] : null;
@@ -44344,23 +44428,23 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44344
44428
  }),
44345
44429
  layout: i
44346
44430
  };
44347
- }, n = Lk(0, "uniform");
44431
+ }, n = zk(0, "uniform");
44348
44432
  this._pipelines = {
44349
- select: t("oidn-history-select", Mk, [
44433
+ select: t("oidn-history-select", Pk, [
44350
44434
  n,
44351
- Fk(1),
44352
- Fk(2),
44353
- Lk(3, "storage"),
44354
- Lk(4, "storage"),
44435
+ Lk(1),
44436
+ Lk(2),
44437
+ zk(3, "storage"),
44438
+ zk(4, "storage"),
44355
44439
  {
44356
44440
  binding: 5,
44357
44441
  visibility: GPUShaderStage.COMPUTE,
44358
44442
  texture: { sampleType: "uint" }
44359
44443
  },
44360
- Lk(6, "read-only-storage"),
44361
- Lk(7, "read-only-storage")
44444
+ zk(6, "read-only-storage"),
44445
+ zk(7, "read-only-storage")
44362
44446
  ]),
44363
- blend: t("oidn-history-blend", Nk, [
44447
+ blend: t("oidn-history-blend", Fk, [
44364
44448
  n,
44365
44449
  ...[
44366
44450
  1,
@@ -44370,14 +44454,14 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44370
44454
  5,
44371
44455
  6,
44372
44456
  7
44373
- ].map(Fk),
44374
- Lk(8, "read-only-storage"),
44375
- Lk(9, "read-only-storage"),
44376
- Ik(10),
44377
- Ik(11),
44378
- Ik(12)
44457
+ ].map(Lk),
44458
+ zk(8, "read-only-storage"),
44459
+ zk(9, "read-only-storage"),
44460
+ Rk(10),
44461
+ Rk(11),
44462
+ Rk(12)
44379
44463
  ]),
44380
- merge: t("oidn-history-merge", Pk, [
44464
+ merge: t("oidn-history-merge", Ik, [
44381
44465
  n,
44382
44466
  ...[
44383
44467
  1,
@@ -44386,16 +44470,16 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44386
44470
  4,
44387
44471
  5,
44388
44472
  6
44389
- ].map(Fk),
44390
- Ik(7),
44391
- Ik(8),
44392
- Ik(9)
44473
+ ].map(Lk),
44474
+ Rk(7),
44475
+ Rk(8),
44476
+ Rk(9)
44393
44477
  ])
44394
44478
  }, this._paramsBuffer = e.createBuffer({
44395
44479
  label: "oidn-history-params",
44396
- size: Tk,
44480
+ size: Dk,
44397
44481
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
44398
- }), this._growMoved(Ek);
44482
+ }), this._growMoved(Ok);
44399
44483
  }
44400
44484
  _growMoved(e) {
44401
44485
  this._movedLeaves?.destroy(), this._movedToPrev?.destroy();
@@ -44421,11 +44505,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44421
44505
  a.setPipeline(t), a.setBindGroup(0, this.device.createBindGroup({
44422
44506
  layout: n,
44423
44507
  entries: i
44424
- })), a.dispatchWorkgroups(Math.ceil(this.width / wk), Math.ceil(this.height / wk)), a.end();
44508
+ })), a.dispatchWorkgroups(Math.ceil(this.width / Ek), Math.ceil(this.height / Ek)), a.end();
44425
44509
  }
44426
44510
  _writeParams(e, t, n, r) {
44427
44511
  let i = this.settings, a = this._paramU32, o = this._paramF32;
44428
- a[0] = this.width, a[1] = this.height, a[2] = +!!t, a[3] = (i.cleanAux ? Dk : 0) | (i.splitCopies ? Ok : 0) | (e.orthographic ? kk : 0), o[4] = i.maxLength, o[5] = i.smoothLength, o[6] = i.depthTolerance, o[7] = i.normalTolerance, o[8] = i.roughStart, o[9] = i.roughEnd, o[10] = n, o[11] = r, o.set(e.world, 12), o.set(e.projInv, 28), o.set(this._prevViewProj, 44), o.set(this._prevCamPos, 60), a[64] = this._movedCount, o[68] = i.movedLength, o.set(this._prevCamDir, 72), this.device.queue.writeBuffer(this._paramsBuffer, 0, this._paramData);
44512
+ a[0] = this.width, a[1] = this.height, a[2] = +!!t, a[3] = (i.cleanAux ? kk : 0) | (i.splitCopies ? Ak : 0) | (e.orthographic ? jk : 0), o[4] = i.maxLength, o[5] = i.smoothLength, o[6] = i.depthTolerance, o[7] = i.normalTolerance, o[8] = i.roughStart, o[9] = i.roughEnd, o[10] = n, o[11] = r, o.set(e.world, 12), o.set(e.projInv, 28), o.set(this._prevViewProj, 44), o.set(this._prevCamPos, 60), a[64] = this._movedCount, o[68] = i.movedLength, o.set(this._prevCamDir, 72), this.device.queue.writeBuffer(this._paramsBuffer, 0, this._paramData);
44429
44513
  }
44430
44514
  _rememberCamera(e) {
44431
44515
  this._prevViewProj.set(e.viewProj), this._prevCamPos[0] = e.world[12], this._prevCamPos[1] = e.world[13], this._prevCamPos[2] = e.world[14];
@@ -44435,11 +44519,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
44435
44519
  _releaseTextures() {
44436
44520
  this._sets?.forEach((e) => Object.values(e).forEach((e) => e.destroy())), this._picked?.destroy(), this._copies?.destroy(), this._sets = null, this._picked = null, this._copies = null, this.width = 0, this.height = 0, this.valid = !1;
44437
44521
  }
44438
- }, zk = "const e=Object.freeze({ADAPTER_SOFTWARE:`adapter.software`,ASSET_UNREACHABLE:`asset.unreachable`,ASSET_AMBIGUOUS_ENTRY:`asset.ambiguous_entry`,ASSET_ARCHIVE_TOO_LARGE:`asset.archive_too_large`,ASSET_ENTRY_TOO_LARGE:`asset.entry_too_large`,TEXTURE_BUILD_FAILED:`texture.build_failed`,TEXTURE_PROCESSING_FALLBACK:`texture.processing_fallback`,TEXTURE_LIMIT_EXCEEDED:`texture.limit_exceeded`,ENVIRONMENT_LOAD_FAILED:`environment.load_failed`,SETTING_UNKNOWN_KEY:`setting.unknown_key`,RENDER_SIZE_DECLINED:`render.size_declined`,STAGE_RENDER_FAILED:`stage.render_failed`,RENDER_RESERVE_CAPPED:`render.reserve_capped`,SCENE_MEMORY_BUDGET:`scene.memory_budget`,EMISSIVE_INSTANCES_COLLAPSED:`emissive.instances_collapsed`,REFIT_SHARED_GEOMETRY:`refit.shared_geometry`,VIEW_TRANSFORM_DISPLAY_MISMATCH:`viewTransform.display_mismatch`,VIEW_TRANSFORM_BAKE_FAILED:`viewTransform.bake_failed`,COLOR_CONFIG_LOAD_FAILED:`color.config_load_failed`,STORAGE_UNAVAILABLE:`storage.unavailable`,STORAGE_QUOTA_EXCEEDED:`storage.quota_exceeded`,STORAGE_WRITE_FAILED:`storage.write_failed`,STORAGE_READ_FAILED:`storage.read_failed`,STORAGE_ENTRY_CORRUPT:`storage.entry_corrupt`,STORAGE_CACHE_MISMATCH:`storage.cache_mismatch`,DENOISER_UNAVAILABLE:`denoiser.unavailable`,OUTPUT_SOURCE_FALLBACK:`output.source_fallback`,LIGHT_PLACEHOLDER_SKIPPED:`light.placeholder_skipped`});Object.freeze({ERROR:`error`,WARNING:`warning`});const t=new Map;function n(e,t){return e.exclusive||t===`exclusive`&&e.shared>0?!1:(t===`exclusive`?e.exclusive=!0:e.shared++,!0)}function r(e,r,a){let o=t.get(e);o||(o={shared:0,exclusive:!1,queue:[]},t.set(e,o));let s=i(()=>{for(r===`exclusive`?o.exclusive=!1:o.shared--;o.queue.length&&n(o,o.queue[0].mode);)o.queue.shift().grant();!o.exclusive&&o.shared===0&&o.queue.length===0&&t.delete(e)});return o.queue.length===0&&n(o,r)?Promise.resolve(s):a?(!o.exclusive&&o.shared===0&&o.queue.length===0&&t.delete(e),Promise.resolve(null)):new Promise(e=>o.queue.push({mode:r,grant:()=>e(s)}))}function i(e){let t=!1;return()=>{t||(t=!0,e())}}const a=()=>typeof navigator<`u`&&navigator.locks?.request?navigator.locks:null;function o(e,{mode:t=`exclusive`,ifAvailable:n=!1}={}){let o=a();return o?new Promise((r,a)=>{o.request(e,{mode:t,ifAvailable:n},e=>{if(!e){r(null);return}return new Promise(e=>r(i(e)))}).catch(a)}):r(e,t,n)}async function s(){let e=a();if(!e)return new Set(t.keys());let{held:n=[]}=await e.query();return new Set(n.map(e=>e.name))}const c=new TextEncoder;function l(e){let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}async function u(e){let t=typeof e==`string`?c.encode(e):e;return l(new Uint8Array(await crypto.subtle.digest(`SHA-256`,t)))}async function d(e){return(await u(e)).slice(0,32)}var f=class{constructor(){this._handlers=new Map}addEventListener(e,t){this._handlers.has(e)||this._handlers.set(e,new Set),this._handlers.get(e).add(t)}removeEventListener(e,t){this._handlers.get(e)?.delete(t)}dispatchEvent(e){for(let t of[...this._handlers.get(e.type)??[]])t.call(this,e)}},p=class{constructor(e){this._root=e,this._writers=new Map,this._nextId=1}async _dir(e,t){let n=await this._root;for(let r of e)n=await n.getDirectoryHandle(r,{create:t});return n}async openWriter({path:e,name:t,truncate:n=!0,length:r}){let i=await(await(await this._dir(e,!0)).getFileHandle(t,{create:!0})).createSyncAccessHandle();n?i.truncate(0):r!==void 0&&i.getSize()>r&&i.truncate(r);let a=this._nextId++;return this._writers.set(a,{handle:i,end:i.getSize()}),{id:a}}write({id:e,buffer:t,byteOffset:n=0,byteLength:r,at:i}){let a=this._writers.get(e);if(!a)throw Error(`storage: writer ${e} is not open`);let o=new Uint8Array(t,n,r??t.byteLength-n),s=i??a.end,c=0;for(;c<o.length;){let e=a.handle.write(o.subarray(c),{at:s+c});if(e<=0)throw Error(`storage: write made no progress`);c+=e}return a.end=Math.max(a.end,s+o.length),{bytes:o.length}}closeWriter({id:e,abort:t=!1}){let n=this._writers.get(e);if(!n)return{size:0};this._writers.delete(e);try{return t||n.handle.flush(),{size:n.handle.getSize()}}finally{n.handle.close()}}async writeFile({path:e,name:t,buffer:n,byteOffset:r=0,byteLength:i}){let{id:a}=await this.openWriter({path:e,name:t});try{return this.write({id:a,buffer:n,byteOffset:r,byteLength:i}),this.closeWriter({id:a})}catch(e){throw this.closeWriter({id:a,abort:!0}),e}}async readRange({path:e,name:t,offset:n=0,length:r}){let i=await(await this._dir(e,!1)).getFileHandle(t),a=null;try{a=await i.createSyncAccessHandle()}catch(e){if(e.name!==`NoModificationAllowedError`)throw e}if(!a){let e=await i.getFile(),t=r===void 0?e.size:n+r;return{buffer:await e.slice(n,t).arrayBuffer()}}try{let e=a.getSize(),t=Math.max(0,Math.min(r??e-n,e-n)),i=new ArrayBuffer(t);return a.read(i,{at:n}),{buffer:i}}finally{a.close()}}dispose(){for(let e of[...this._writers.keys()])this.closeWriter({id:e,abort:!0})}},m=class{constructor(e){this._ops=new p(e)}async call(e,t){return this._ops[e](t)}dispose(){this._ops.dispose()}};const h=Object.freeze({CACHE:`cache`,USER:`user`,SCRATCH:`scratch`}),g=Object.freeze({DOWNLOADS:`downloads`,ARCHIVES:`archives`,SCENES:`scenes`,CDF:`cdf`,SPILL:`spill`}),_=`meta.json`,v=100*1024**3,y=64*1024**2,b=8*1024**2,x=new TextEncoder;function S(e,{copy:t,transfer:n}){if(typeof e==`string`&&(e=x.encode(e)),e instanceof ArrayBuffer){if(!t||n)return{args:{buffer:e},list:[e]};let r=e.slice(0);return{args:{buffer:r},list:[r]}}if(!ArrayBuffer.isView(e))throw TypeError(`storage: write expects an ArrayBuffer, a typed array, a Blob or a string`);let{buffer:r,byteOffset:i,byteLength:a}=e,o=typeof SharedArrayBuffer<`u`&&r instanceof SharedArrayBuffer;if(!t)return{args:{buffer:r,byteOffset:i,byteLength:a},list:[]};if(o){let e=new Uint8Array(a);return e.set(new Uint8Array(r,i,a)),{args:{buffer:e.buffer},list:[e.buffer]}}if(n&&i===0&&a===r.byteLength)return{args:{buffer:r},list:[r]};let s=r.slice(i,i+a);return{args:{buffer:s},list:[s]}}async function C(e,t){try{let n=await(await e.getFileHandle(t)).getFile();return JSON.parse(await n.text())}catch{return null}}async function*w(e){for await(let[t,n]of e.entries())n.kind===`directory`&&(yield[t,n])}var T=class{constructor(e,t,n,r,i){this.area=e,this.id=t,this.key=n.key,this.meta=n,this._dir=r,this._release=i}get bytes(){return this.meta.bytes}get extra(){return this.meta.extra??{}}async file(t){try{return await(await this._dir.getFileHandle(t)).getFile()}catch(n){return this.area.manager._issue(e.STORAGE_READ_FAILED,`could not read ${this.area.name}/${this.id}/${t}`,{error:n.message}),null}}async json(e){let t=await this.file(e);return t?JSON.parse(await t.text()):null}release(){this._release?.(),this._release=null}},E=class{constructor(e,t,n,r,i,{sizes:a={},append:o=!1}={}){this.area=e,this.id=t,this.key=n,this._info=r,this._release=i,this._writers=new Map,this._sizes={...a},this._append=o,this._done=!1}get _transport(){return this.area.manager._transport}get _path(){return[this.area.name,this.id]}async _writer(e){let t=this._writers.get(e);if(!t){let n=this._append&&e in this._sizes,r=n&&(this._info.growable??[]).includes(e)?this._sizes[e]:void 0;t=this._transport.call(`openWriter`,{path:this._path,name:e,truncate:!n,length:r}),this._writers.set(e,t)}return(await t).id}async write(e,t,{at:n,transfer:r=!1}={}){this._assertOpen();let{args:i,list:a}=(typeof Blob<`u`&&t instanceof Blob?null:S(t,{copy:!0,transfer:r}))??S(await t.arrayBuffer(),{copy:!0,transfer:!0}),o=await this._writer(e);return this._transport.call(`write`,{id:o,at:n,...i},a)}async writeFile(e,t){this._assertOpen(),typeof Blob<`u`&&t instanceof Blob&&(t=await t.arrayBuffer());let{args:n,list:r}=S(t,{copy:!0,transfer:!0}),{size:i}=await this._transport.call(`writeFile`,{path:this._path,name:e,...n},r);return this._sizes[e]=i,i}writeJSON(e,t){return this.writeFile(e,JSON.stringify(t))}async writeStream(e,t,{onProgress:n=null,signal:r=null,batchBytes:i=b}={}){let a=t.getReader(),o=[],s=new Uint8Array(i),c=0,l=0,u=async()=>{if(c===0)return;let t=c===i?s:s.slice(0,c);s=new Uint8Array(i),c=0,o.push(this.write(e,t,{transfer:!0})),o.length>=4&&await o.shift()};try{for(;;){if(r?.aborted)throw r.reason??new DOMException(`aborted`,`AbortError`);let{done:e,value:t}=await a.read();if(e)break;let o=0;for(;o<t.length;){let e=Math.min(t.length-o,i-c);s.set(t.subarray(o,o+e),c),c+=e,o+=e,l+=e,c===i&&await u()}n?.(l)}return await u(),await Promise.all(o),l}catch(e){throw a.cancel().catch(()=>{}),await Promise.allSettled(o),e}}async commit(e={}){this._assertOpen(),this._done=!0;try{for(let[e,t]of this._writers){let{size:n}=await this._transport.call(`closeWriter`,{id:(await t).id});this._sizes[e]=n}this._writers.clear();let t=Date.now(),n={v:1,key:this.key,label:this._info.label??``,kind:this.area.kind,files:{...this._sizes},bytes:Object.values(this._sizes).reduce((e,t)=>e+t,0),createdAt:this._info.createdAt??t,lastUsed:t,pinned:this._info.pinned===!0,extra:{...this._info.extra,...e}},r=this._info.growable??[];r.length&&(n.growable=r);let{args:i,list:a}=S(JSON.stringify(n),{copy:!1});return await this._transport.call(`writeFile`,{path:this._path,name:_,...i},a),this.area.manager._changed(this.area.name),n}catch(e){throw await this._discard(),this.area.manager._writeFailed(this.area.name,e),e}finally{this._release?.(),this._release=null}}async abort(){if(!this._done){this._done=!0;try{this._append?await this._closeAll(!0):await this._discard()}finally{this._release?.(),this._release=null}}}async _closeAll(e){for(let t of this._writers.values())try{await this._transport.call(`closeWriter`,{id:(await t).id,abort:e})}catch{}this._writers.clear()}async _discard(){await this._closeAll(!0),await this.area._removeDir(this.id)}_assertOpen(){if(this._done)throw Error(`storage: entry ${this.area.name}/${this.id} is already committed or aborted`)}},D=class{constructor(e,t,n){this.manager=e,this.name=t,this.kind=n}_lockName(e){return`${this.manager.namespace}:store:${this.name}:${e}`}async _dir(e=!1){try{return await this.manager._root.getDirectoryHandle(this.name,{create:e})}catch(e){if(e.name===`NotFoundError`)return null;throw e}}async _entryDir(e,t=!1){let n=await this._dir(t);if(!n)return null;try{return await n.getDirectoryHandle(e,{create:t})}catch(e){if(e.name===`NotFoundError`)return null;throw e}}async _removeDir(e){let t=await this._dir(!1);if(t)try{await t.removeEntry(e,{recursive:!0})}catch(e){if(e.name!==`NotFoundError`)throw e}}async _validMeta(e,t=null){let n=await C(e,_);if(!n||n.v!==1||typeof n.key!=`string`||t!==null&&n.key!==t)return null;let r=n.growable??[];for(let[t,i]of Object.entries(n.files??{}))try{let n=await(await e.getFileHandle(t)).getFile();if(n.size!==i&&!(r.includes(t)&&n.size>i))return null}catch{return null}return n}async open(t,{wait:n=!1}={}){let r=await d(t),i=await o(this._lockName(r),{mode:`shared`,ifAvailable:!n});if(!i)return null;try{let e=await this._entryDir(r),n=e?await this._validMeta(e,t):null;return n?(Date.now()-n.lastUsed>36e5&&this._touch(r,n),new T(this,r,n,e,i)):(i(),null)}catch(t){return i(),this.manager._issue(e.STORAGE_READ_FAILED,`could not open ${this.name} entry`,{error:t.message}),null}}async has(e){let t=await this.open(e);return t?.release(),!!t}_touch(e,t){let n={...t,lastUsed:Date.now()},{args:r,list:i}=S(JSON.stringify(n),{copy:!1});this.manager._transport.call(`writeFile`,{path:[this.name,e],name:_,...r},i).catch(()=>{}),t.lastUsed=n.lastUsed}async create(t,{label:n=``,pinned:r=!1,expectedBytes:i=0,extra:a={},growable:s=[]}={}){let c=await d(t),l=await o(this._lockName(c),{mode:`exclusive`});try{return i>0&&!await this.manager.ensureSpace(i,this.kind)?(l(),this.manager._issue(e.STORAGE_QUOTA_EXCEEDED,`no room for ${(i/1048576).toFixed(0)} MB in ${this.name}`,{area:this.name,expectedBytes:i}),null):(await this._removeDir(c),await this._entryDir(c,!0),new E(this,c,t,{label:n,pinned:r,extra:a,growable:s},l))}catch(e){return l(),this.manager._writeFailed(this.name,e),null}}async patchMeta(e,t){let n=await d(e),r=await o(this._lockName(n),{mode:`shared`,ifAvailable:!0});if(!r)return!1;try{let r=await this._entryDir(n),i=r?await this._validMeta(r,e):null;if(!i)return!1;let{args:a,list:o}=S(JSON.stringify({...i,...t,v:1,key:e}),{copy:!1});return await this.manager._transport.call(`writeFile`,{path:[this.name,n],name:_,...a},o),!0}finally{r()}}async edit(e){let t=await d(e),n=await o(this._lockName(t),{mode:`exclusive`});try{let r=await this._entryDir(t),i=r?await this._validMeta(r,e):null;if(!i)return n(),null;let a={label:i.label,pinned:i.pinned,extra:i.extra,createdAt:i.createdAt,growable:i.growable};return new E(this,t,e,a,n,{sizes:i.files,append:!0})}catch(e){return n(),this.manager._writeFailed(this.name,e),null}}async remove(e){return this.removeById(await d(e))}async removeById(e){let t=await o(this._lockName(e),{mode:`exclusive`,ifAvailable:!0});if(!t)return!1;try{return await this._removeDir(e),this.manager._changed(this.name),!0}finally{t()}}async list(){let e=await this._dir(!1);if(!e)return[];let t=[];for await(let[n,r]of w(e)){let e=await C(r,_);e?.v===1&&t.push({...e,id:n})}return t}async clear(){let e=0;for(let{id:t}of await this.list())await this.removeById(t)&&e++;return e}async sweep(){let e=await this._dir(!1);if(!e)return 0;let t=await s(),n=0;for await(let[r,i]of w(e))t.has(this._lockName(r))||await this._validMeta(i)||await this.removeById(r)&&n++;return n}},O=class extends f{constructor({root:e,transport:t,namespace:n}){super(),this.namespace=n,this._root=e,this._transport=t,this._areas=new Map,this._budget=null;for(let e of Object.values(g))this.defineArea(e,{kind:e===g.SPILL?h.SCRATCH:h.CACHE})}defineArea(e,{kind:t=h.CACHE}={}){let n=this._areas.get(e);if(n){if(n.kind!==t)throw Error(`storage: area \"${e}\" is already defined as ${n.kind}`);return n}let r=new D(this,e,t);return this._areas.set(e,r),r}area(e){let t=this._areas.get(e);if(!t)throw Error(`storage: unknown area \"${e}\"`);return t}get areaNames(){return[...this._areas.keys()]}async estimate(){let e=typeof navigator<`u`?navigator.storage:null;if(!e?.estimate)return{quota:1/0,usage:0};let{quota:t=1/0,usage:n=0}=await e.estimate();return{quota:t,usage:n}}async persisted(){return await globalThis.navigator?.storage?.persisted?.()===!0}async persist(){let e=await globalThis.navigator?.storage?.persist?.()===!0;return this._changed(null),e}async budget(){if(this._budget!==null)return this._budget;let{quota:e}=await this.estimate();return Math.min(e*.3,v)}setBudget(e){this._budget=e===null?null:Math.max(0,e),this._changed(null)}async _cacheEntries(){let e=[];for(let t of this._areas.values())if(t.kind===h.CACHE)for(let n of await t.list())e.push({area:t,meta:n});return e}async usage(){let{quota:e,usage:t}=await this.estimate(),n={},r=0;for(let e of this._areas.values()){let t=await e.list(),i=t.reduce((e,t)=>e+(t.bytes??0),0);n[e.name]={kind:e.kind,bytes:i,entries:t.length},e.kind===h.CACHE&&(r+=i)}return{quota:e,usage:t,persisted:await this.persisted(),budget:await this.budget(),cacheBytes:r,areas:n}}async collect({freeBytes:e=null}={}){let t=await this._cacheEntries(),n=await this.budget(),r=t.reduce((e,t)=>e+(t.meta.bytes??0),0),i=e??Math.max(0,r-n);if(i<=0)return 0;let a=await s(),o=t.filter(({area:e,meta:t})=>!t.pinned&&!a.has(e._lockName(t.id))).sort((e,t)=>e.meta.lastUsed-t.meta.lastUsed),c=0;for(let{area:e,meta:t}of o){if(c>=i)break;await e.removeById(t.id)&&(c+=t.bytes??0,r-=t.bytes??0)}return c}async ensureSpace(e,t=h.CACHE){let n=async()=>{let{quota:n,usage:r}=await this.estimate(),i=e+y-(n-r);return t===h.CACHE?{free:i,budget:(await this._cacheEntries()).reduce((e,t)=>e+(t.meta.bytes??0),0)+e-await this.budget()}:{free:i,budget:0}},r=await n();return r.free<=0&&r.budget<=0?!0:(await this.collect({freeBytes:Math.max(r.free,r.budget)}),(await n()).free<=0)}async sweep(){let e=0;for(let t of this._areas.values())e+=await t.sweep(),t.kind===h.SCRATCH&&(e+=await t.clear());return e}_changed(e){this.dispatchEvent({type:`change`,area:e})}_issue(e,t,n={}){this.dispatchEvent({type:`issue`,code:e,message:t,detail:n})}_writeFailed(t,n){let r=n?.name===`QuotaExceededError`;this._issue(r?e.STORAGE_QUOTA_EXCEEDED:e.STORAGE_WRITE_FAILED,`${t}: ${n?.message??n}`,{area:t,error:n?.name})}dispose(){this._transport?.dispose(),this._transport=null,this._areas.clear()}};function k({namespace:e,root:t}){let n=new m(t);n.inline=!0;let r=new O({root:t,transport:n,namespace:e});return r.sweep().catch(()=>{}),r}const A=Object.freeze({IMMUTABLE:`immutable`,REVALIDATE:`revalidate`,NETWORK:`network`}),j=(e,t)=>({loaded:e,total:t,lengthComputable:t>0&&e<=t}),M=(e,t)=>e.headers?.get?.(t)??null,N=e=>e.reason??new DOMException(`aborted`,`AbortError`);function P(e){try{let t=new URL(e,globalThis.location?.href??`http://localhost/`).pathname;return decodeURIComponent(t.split(`/`).pop())||`download`}catch{return`download`}}async function F(e,{onProgress:t,signal:n}){let r=Number(M(e,`content-length`))||0,i=M(e,`content-type`)??``;if(!e.body)return new Blob([await e.arrayBuffer()],{type:i});let a=e.body.getReader(),o=[],s=0;for(;;){if(n?.aborted)throw a.cancel().catch(()=>{}),N(n);let{done:e,value:i}=await a.read();if(e)break;o.push(i),s+=i.length,t?.(j(s,r))}return new Blob(o,{type:i})}const I=(e,t,n)=>new File([e],t,{type:n||e.type,lastModified:e.lastModified??Date.now()}),L=()=>{};var R=class{constructor(e){this._storage=e,this._revalidating=new Set}get _area(){return this._storage?.area(g.DOWNLOADS)??null}async fetch(e,{key:t=e,name:n=P(e),policy:r=A.REVALIDATE,maxAgeMs:i=864e5,onProgress:a=null,signal:o=null,fetchOptions:s={}}={}){let c=this._area;if(c&&r!==A.NETWORK){let o=await c.open(t);if(o){let c=await o.file(`data`);if(c)return r===A.REVALIDATE&&Date.now()-(o.extra.checkedAt??0)>=i&&this._revalidate(e,t,n,o.extra,s),a?.(j(c.size,c.size)),{file:I(c,n,o.extra.contentType),release:()=>o.release(),fromCache:!0};o.release()}}return this._download(e,t,n,{onProgress:a,signal:o,fetchOptions:s,cache:!!c})}async has(e){return await this._area?.has(e)===!0}async _download(e,t,n,{onProgress:r,signal:i,fetchOptions:a,cache:o}){if(i?.aborted)throw N(i);let s=await fetch(e,{...a,signal:i});if(!s.ok)throw Error(`HTTP ${s.status} fetching ${e}`);let c=Number(M(s,`content-length`))||0,l={url:e,contentType:M(s,`content-type`)??``,lastModified:M(s,`last-modified`),contentLength:c||null,checkedAt:Date.now()},u=o&&s.body?await this._area.create(t,{label:n,expectedBytes:c}):null;if(!u)return{file:I(await F(s,{onProgress:r,signal:i}),n,l.contentType),release:L,fromCache:!1};try{await u.writeStream(`data`,s.body,{signal:i,onProgress:e=>r?.(j(e,c))}),await u.commit(l)}catch(o){if(await u.abort(),o?.name!==`QuotaExceededError`)throw o;return this._download(e,t,n,{onProgress:r,signal:i,fetchOptions:a,cache:!1})}let d=await this._area.open(t,{wait:!0}),f=d&&await d.file(`data`);if(!f)throw d?.release(),Error(`storage: ${n} vanished right after it was saved`);return{file:I(f,n,l.contentType),release:()=>d.release(),fromCache:!1}}async _revalidate(e,t,n,r,i){if(this._revalidating.has(t))return;this._revalidating.add(t);let a=!1;try{let t=new Headers(i?.headers);t.set(`Range`,`bytes=0-0`);let n=await fetch(e,{...i,headers:t});if(n.body?.cancel().catch(()=>{}),n.ok){let e=M(n,`last-modified`),t=n.status===206?Number(M(n,`content-range`)?.match(/\\/(\\d+)$/)?.[1])||null:Number(M(n,`content-length`))||null;a=!!(e&&r.lastModified&&e!==r.lastModified||t&&r.contentLength&&t!==r.contentLength)}}catch{}try{if(a){let{release:r}=await this._download(e,t,n,{fetchOptions:i,cache:!0});r()}else await this._area.patchMeta(t,{extra:{...r,checkedAt:Date.now()}})}catch{}finally{this._revalidating.delete(t)}}};let z={ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,cacheNamespace:`rayzee`,storage:`auto`},B=null;async function V(){return B||(B=await import(z.ortRuntimeUrl),B.env.wasm.wasmPaths=z.ortWasmPaths,B.env.logLevel=`error`,B)}let H=null,U=null,W=null;function G(){return W??=(async()=>{if(z.storage===!1||!navigator.storage?.getDirectory)return new R(null);try{let e=await(await navigator.storage.getDirectory()).getDirectoryHandle(z.cacheNamespace,{create:!0}),t=k({namespace:z.cacheNamespace,root:e});return await K(t).catch(()=>{}),new R(t)}catch{return new R(null)}})(),W}async function K(e){let t=`${z.cacheNamespace}:ai-upscaler-models`;if(typeof indexedDB>`u`||!indexedDB.databases||!(await indexedDB.databases()).some(e=>e.name===t))return;let n=await new Promise((e,n)=>{let r=indexedDB.open(t);r.onerror=()=>n(r.error),r.onsuccess=()=>{let t=r.result;if(!t.objectStoreNames.contains(`models`)){t.close(),e([]);return}let i=[],a=t.transaction(`models`,`readonly`).objectStore(`models`).openCursor();a.onerror=()=>n(a.error),a.onsuccess=()=>{let n=a.result;if(!n){t.close(),e(i);return}i.push([n.key,n.value]),n.continue()}}}),r=e.area(`downloads`);for(let[e,t]of n){if(typeof e!=`string`||!(t instanceof ArrayBuffer)||await r.has(e))continue;let n=await r.create(e,{label:e.split(`/`).pop(),expectedBytes:t.byteLength});n&&(await n.write(`data`,t,{transfer:!0}),await n.commit({url:e,contentType:`application/octet-stream`,checkedAt:Date.now()}))}await new Promise(e=>{let n=indexedDB.deleteDatabase(t);n.onsuccess=n.onerror=n.onblocked=()=>e()})}async function q(e){let{file:t,release:n,fromCache:r}=await(await G()).fetch(e);try{let e=await t.arrayBuffer();return r&&console.log(`AI Upscaler Worker: model loaded from cache (${(e.byteLength/1024/1024).toFixed(1)}MB)`),e}finally{n()}}async function J(e,t){if(H&&U===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}H&&=(await H.release(),null);let[n,r]=await Promise.all([q(e),V()]);H=await r.InferenceSession.create(n,t),U=e;let i=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);i=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${i}`)}catch{}let a=(n.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${a}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:i})}async function Y(e,t,n,r){let i=await V(),a=H.inputNames[0],o=H.outputNames[0],s=new i.Tensor(`float32`,e,[1,3,n,t]),c=(await H.run({[a]:s}))[o].data;self.postMessage({type:`inferred`,outputData:c,id:r},[c.buffer])}self.onmessage=async e=>{let{type:t}=e.data;try{t===`load`?(e.data.ortRuntimeUrl&&(z.ortRuntimeUrl=e.data.ortRuntimeUrl),e.data.ortWasmPaths&&(z.ortWasmPaths=e.data.ortWasmPaths),e.data.cacheNamespace&&(z.cacheNamespace=e.data.cacheNamespace),e.data.storage!==void 0&&(z.storage=e.data.storage),await J(e.data.url,e.data.sessionOptions)):t===`infer`?await Y(e.data.tileData,e.data.width,e.data.height,e.data.id):t===`dispose`&&H&&(await H.release(),H=null,U=null)}catch(t){self.postMessage({type:`error`,message:t.message,id:e.data?.id})}};", Bk = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", zk], { type: "text/javascript;charset=utf-8" });
44439
- function Vk(e) {
44522
+ }, Vk = "const e=Object.freeze({ADAPTER_SOFTWARE:`adapter.software`,ASSET_UNREACHABLE:`asset.unreachable`,ASSET_AMBIGUOUS_ENTRY:`asset.ambiguous_entry`,ASSET_ARCHIVE_TOO_LARGE:`asset.archive_too_large`,ASSET_ENTRY_TOO_LARGE:`asset.entry_too_large`,TEXTURE_BUILD_FAILED:`texture.build_failed`,TEXTURE_PROCESSING_FALLBACK:`texture.processing_fallback`,TEXTURE_LIMIT_EXCEEDED:`texture.limit_exceeded`,ENVIRONMENT_LOAD_FAILED:`environment.load_failed`,SETTING_UNKNOWN_KEY:`setting.unknown_key`,RENDER_SIZE_DECLINED:`render.size_declined`,STAGE_RENDER_FAILED:`stage.render_failed`,RENDER_RESERVE_CAPPED:`render.reserve_capped`,SCENE_MEMORY_BUDGET:`scene.memory_budget`,EMISSIVE_INSTANCES_COLLAPSED:`emissive.instances_collapsed`,REFIT_SHARED_GEOMETRY:`refit.shared_geometry`,VIEW_TRANSFORM_DISPLAY_MISMATCH:`viewTransform.display_mismatch`,VIEW_TRANSFORM_BAKE_FAILED:`viewTransform.bake_failed`,COLOR_CONFIG_LOAD_FAILED:`color.config_load_failed`,STORAGE_UNAVAILABLE:`storage.unavailable`,STORAGE_QUOTA_EXCEEDED:`storage.quota_exceeded`,STORAGE_WRITE_FAILED:`storage.write_failed`,STORAGE_READ_FAILED:`storage.read_failed`,STORAGE_ENTRY_CORRUPT:`storage.entry_corrupt`,STORAGE_CACHE_MISMATCH:`storage.cache_mismatch`,DENOISER_UNAVAILABLE:`denoiser.unavailable`,OUTPUT_SOURCE_FALLBACK:`output.source_fallback`,LIGHT_PLACEHOLDER_SKIPPED:`light.placeholder_skipped`});Object.freeze({ERROR:`error`,WARNING:`warning`});const t=new Map;function n(e,t){return e.exclusive||t===`exclusive`&&e.shared>0?!1:(t===`exclusive`?e.exclusive=!0:e.shared++,!0)}function r(e,r,a){let o=t.get(e);o||(o={shared:0,exclusive:!1,queue:[]},t.set(e,o));let s=i(()=>{for(r===`exclusive`?o.exclusive=!1:o.shared--;o.queue.length&&n(o,o.queue[0].mode);)o.queue.shift().grant();!o.exclusive&&o.shared===0&&o.queue.length===0&&t.delete(e)});return o.queue.length===0&&n(o,r)?Promise.resolve(s):a?(!o.exclusive&&o.shared===0&&o.queue.length===0&&t.delete(e),Promise.resolve(null)):new Promise(e=>o.queue.push({mode:r,grant:()=>e(s)}))}function i(e){let t=!1;return()=>{t||(t=!0,e())}}const a=()=>typeof navigator<`u`&&navigator.locks?.request?navigator.locks:null;function o(e,{mode:t=`exclusive`,ifAvailable:n=!1}={}){let o=a();return o?new Promise((r,a)=>{o.request(e,{mode:t,ifAvailable:n},e=>{if(!e){r(null);return}return new Promise(e=>r(i(e)))}).catch(a)}):r(e,t,n)}async function s(){let e=a();if(!e)return new Set(t.keys());let{held:n=[]}=await e.query();return new Set(n.map(e=>e.name))}const c=new TextEncoder;function l(e){let t=``;for(let n of e)t+=n.toString(16).padStart(2,`0`);return t}async function u(e){let t=typeof e==`string`?c.encode(e):e;return l(new Uint8Array(await crypto.subtle.digest(`SHA-256`,t)))}async function d(e){return(await u(e)).slice(0,32)}var f=class{constructor(){this._handlers=new Map}addEventListener(e,t){this._handlers.has(e)||this._handlers.set(e,new Set),this._handlers.get(e).add(t)}removeEventListener(e,t){this._handlers.get(e)?.delete(t)}dispatchEvent(e){for(let t of[...this._handlers.get(e.type)??[]])t.call(this,e)}},p=class{constructor(e){this._root=e,this._writers=new Map,this._nextId=1}async _dir(e,t){let n=await this._root;for(let r of e)n=await n.getDirectoryHandle(r,{create:t});return n}async openWriter({path:e,name:t,truncate:n=!0,length:r}){let i=await(await(await this._dir(e,!0)).getFileHandle(t,{create:!0})).createSyncAccessHandle();n?i.truncate(0):r!==void 0&&i.getSize()>r&&i.truncate(r);let a=this._nextId++;return this._writers.set(a,{handle:i,end:i.getSize()}),{id:a}}write({id:e,buffer:t,byteOffset:n=0,byteLength:r,at:i}){let a=this._writers.get(e);if(!a)throw Error(`storage: writer ${e} is not open`);let o=new Uint8Array(t,n,r??t.byteLength-n),s=i??a.end,c=0;for(;c<o.length;){let e=a.handle.write(o.subarray(c),{at:s+c});if(e<=0)throw Error(`storage: write made no progress`);c+=e}return a.end=Math.max(a.end,s+o.length),{bytes:o.length}}closeWriter({id:e,abort:t=!1}){let n=this._writers.get(e);if(!n)return{size:0};this._writers.delete(e);try{return t||n.handle.flush(),{size:n.handle.getSize()}}finally{n.handle.close()}}async writeFile({path:e,name:t,buffer:n,byteOffset:r=0,byteLength:i}){let{id:a}=await this.openWriter({path:e,name:t});try{return this.write({id:a,buffer:n,byteOffset:r,byteLength:i}),this.closeWriter({id:a})}catch(e){throw this.closeWriter({id:a,abort:!0}),e}}async readRange({path:e,name:t,offset:n=0,length:r}){let i=await(await this._dir(e,!1)).getFileHandle(t),a=null;try{a=await i.createSyncAccessHandle()}catch(e){if(e.name!==`NoModificationAllowedError`)throw e}if(!a){let e=await i.getFile(),t=r===void 0?e.size:n+r;return{buffer:await e.slice(n,t).arrayBuffer()}}try{let e=a.getSize(),t=Math.max(0,Math.min(r??e-n,e-n)),i=new ArrayBuffer(t);return a.read(i,{at:n}),{buffer:i}}finally{a.close()}}dispose(){for(let e of[...this._writers.keys()])this.closeWriter({id:e,abort:!0})}},m=class{constructor(e){this._ops=new p(e)}async call(e,t){return this._ops[e](t)}dispose(){this._ops.dispose()}};const h=Object.freeze({CACHE:`cache`,USER:`user`,SCRATCH:`scratch`}),g=Object.freeze({DOWNLOADS:`downloads`,ARCHIVES:`archives`,SCENES:`scenes`,CDF:`cdf`,SPILL:`spill`}),_=`meta.json`,v=100*1024**3,y=64*1024**2,b=8*1024**2,x=new TextEncoder;function S(e,{copy:t,transfer:n}){if(typeof e==`string`&&(e=x.encode(e)),e instanceof ArrayBuffer){if(!t||n)return{args:{buffer:e},list:[e]};let r=e.slice(0);return{args:{buffer:r},list:[r]}}if(!ArrayBuffer.isView(e))throw TypeError(`storage: write expects an ArrayBuffer, a typed array, a Blob or a string`);let{buffer:r,byteOffset:i,byteLength:a}=e,o=typeof SharedArrayBuffer<`u`&&r instanceof SharedArrayBuffer;if(!t)return{args:{buffer:r,byteOffset:i,byteLength:a},list:[]};if(o){let e=new Uint8Array(a);return e.set(new Uint8Array(r,i,a)),{args:{buffer:e.buffer},list:[e.buffer]}}if(n&&i===0&&a===r.byteLength)return{args:{buffer:r},list:[r]};let s=r.slice(i,i+a);return{args:{buffer:s},list:[s]}}async function C(e,t){try{let n=await(await e.getFileHandle(t)).getFile();return JSON.parse(await n.text())}catch{return null}}async function*w(e){for await(let[t,n]of e.entries())n.kind===`directory`&&(yield[t,n])}var T=class{constructor(e,t,n,r,i){this.area=e,this.id=t,this.key=n.key,this.meta=n,this._dir=r,this._release=i}get bytes(){return this.meta.bytes}get extra(){return this.meta.extra??{}}async file(t){try{return await(await this._dir.getFileHandle(t)).getFile()}catch(n){return this.area.manager._issue(e.STORAGE_READ_FAILED,`could not read ${this.area.name}/${this.id}/${t}`,{error:n.message}),null}}async json(e){let t=await this.file(e);return t?JSON.parse(await t.text()):null}release(){this._release?.(),this._release=null}},E=class{constructor(e,t,n,r,i,{sizes:a={},append:o=!1}={}){this.area=e,this.id=t,this.key=n,this._info=r,this._release=i,this._writers=new Map,this._sizes={...a},this._append=o,this._done=!1}get _transport(){return this.area.manager._transport}get _path(){return[this.area.name,this.id]}async _writer(e){let t=this._writers.get(e);if(!t){let n=this._append&&e in this._sizes,r=n&&(this._info.growable??[]).includes(e)?this._sizes[e]:void 0;t=this._transport.call(`openWriter`,{path:this._path,name:e,truncate:!n,length:r}),this._writers.set(e,t)}return(await t).id}async write(e,t,{at:n,transfer:r=!1}={}){this._assertOpen();let{args:i,list:a}=(typeof Blob<`u`&&t instanceof Blob?null:S(t,{copy:!0,transfer:r}))??S(await t.arrayBuffer(),{copy:!0,transfer:!0}),o=await this._writer(e);return this._transport.call(`write`,{id:o,at:n,...i},a)}async writeFile(e,t){this._assertOpen(),typeof Blob<`u`&&t instanceof Blob&&(t=await t.arrayBuffer());let{args:n,list:r}=S(t,{copy:!0,transfer:!0}),{size:i}=await this._transport.call(`writeFile`,{path:this._path,name:e,...n},r);return this._sizes[e]=i,i}writeJSON(e,t){return this.writeFile(e,JSON.stringify(t))}async writeStream(e,t,{onProgress:n=null,signal:r=null,batchBytes:i=b}={}){let a=t.getReader(),o=[],s=new Uint8Array(i),c=0,l=0,u=async()=>{if(c===0)return;let t=c===i?s:s.slice(0,c);s=new Uint8Array(i),c=0,o.push(this.write(e,t,{transfer:!0})),o.length>=4&&await o.shift()};try{for(;;){if(r?.aborted)throw r.reason??new DOMException(`aborted`,`AbortError`);let{done:e,value:t}=await a.read();if(e)break;let o=0;for(;o<t.length;){let e=Math.min(t.length-o,i-c);s.set(t.subarray(o,o+e),c),c+=e,o+=e,l+=e,c===i&&await u()}n?.(l)}return await u(),await Promise.all(o),l}catch(e){throw a.cancel().catch(()=>{}),await Promise.allSettled(o),e}}async commit(e={}){this._assertOpen(),this._done=!0;try{for(let[e,t]of this._writers){let{size:n}=await this._transport.call(`closeWriter`,{id:(await t).id});this._sizes[e]=n}this._writers.clear();let t=Date.now(),n={v:1,key:this.key,label:this._info.label??``,kind:this.area.kind,files:{...this._sizes},bytes:Object.values(this._sizes).reduce((e,t)=>e+t,0),createdAt:this._info.createdAt??t,lastUsed:t,pinned:this._info.pinned===!0,extra:{...this._info.extra,...e}},r=this._info.growable??[];r.length&&(n.growable=r);let{args:i,list:a}=S(JSON.stringify(n),{copy:!1});return await this._transport.call(`writeFile`,{path:this._path,name:_,...i},a),this.area.manager._changed(this.area.name),n}catch(e){throw await this._discard(),this.area.manager._writeFailed(this.area.name,e),e}finally{this._release?.(),this._release=null}}async abort(){if(!this._done){this._done=!0;try{this._append?await this._closeAll(!0):await this._discard()}finally{this._release?.(),this._release=null}}}async _closeAll(e){for(let t of this._writers.values())try{await this._transport.call(`closeWriter`,{id:(await t).id,abort:e})}catch{}this._writers.clear()}async _discard(){await this._closeAll(!0),await this.area._removeDir(this.id)}_assertOpen(){if(this._done)throw Error(`storage: entry ${this.area.name}/${this.id} is already committed or aborted`)}},D=class{constructor(e,t,n){this.manager=e,this.name=t,this.kind=n}_lockName(e){return`${this.manager.namespace}:store:${this.name}:${e}`}async _dir(e=!1){try{return await this.manager._root.getDirectoryHandle(this.name,{create:e})}catch(e){if(e.name===`NotFoundError`)return null;throw e}}async _entryDir(e,t=!1){let n=await this._dir(t);if(!n)return null;try{return await n.getDirectoryHandle(e,{create:t})}catch(e){if(e.name===`NotFoundError`)return null;throw e}}async _removeDir(e){let t=await this._dir(!1);if(t)try{await t.removeEntry(e,{recursive:!0})}catch(e){if(e.name!==`NotFoundError`)throw e}}async _validMeta(e,t=null){let n=await C(e,_);if(!n||n.v!==1||typeof n.key!=`string`||t!==null&&n.key!==t)return null;let r=n.growable??[];for(let[t,i]of Object.entries(n.files??{}))try{let n=await(await e.getFileHandle(t)).getFile();if(n.size!==i&&!(r.includes(t)&&n.size>i))return null}catch{return null}return n}async open(t,{wait:n=!1}={}){let r=await d(t),i=await o(this._lockName(r),{mode:`shared`,ifAvailable:!n});if(!i)return null;try{let e=await this._entryDir(r),n=e?await this._validMeta(e,t):null;return n?(Date.now()-n.lastUsed>36e5&&this._touch(r,n),new T(this,r,n,e,i)):(i(),null)}catch(t){return i(),this.manager._issue(e.STORAGE_READ_FAILED,`could not open ${this.name} entry`,{error:t.message}),null}}async has(e){let t=await this.open(e);return t?.release(),!!t}_touch(e,t){let n={...t,lastUsed:Date.now()},{args:r,list:i}=S(JSON.stringify(n),{copy:!1});this.manager._transport.call(`writeFile`,{path:[this.name,e],name:_,...r},i).catch(()=>{}),t.lastUsed=n.lastUsed}async create(t,{label:n=``,pinned:r=!1,expectedBytes:i=0,extra:a={},growable:s=[]}={}){let c=await d(t),l=await o(this._lockName(c),{mode:`exclusive`});try{return i>0&&!await this.manager.ensureSpace(i,this.kind)?(l(),this.manager._issue(e.STORAGE_QUOTA_EXCEEDED,`no room for ${(i/1048576).toFixed(0)} MB in ${this.name}`,{area:this.name,expectedBytes:i}),null):(await this._removeDir(c),await this._entryDir(c,!0),new E(this,c,t,{label:n,pinned:r,extra:a,growable:s},l))}catch(e){return l(),this.manager._writeFailed(this.name,e),null}}async patchMeta(e,t){let n=await d(e),r=await o(this._lockName(n),{mode:`shared`,ifAvailable:!0});if(!r)return!1;try{let r=await this._entryDir(n),i=r?await this._validMeta(r,e):null;if(!i)return!1;let{args:a,list:o}=S(JSON.stringify({...i,...t,v:1,key:e}),{copy:!1});return await this.manager._transport.call(`writeFile`,{path:[this.name,n],name:_,...a},o),!0}finally{r()}}async edit(e){let t=await d(e),n=await o(this._lockName(t),{mode:`exclusive`});try{let r=await this._entryDir(t),i=r?await this._validMeta(r,e):null;if(!i)return n(),null;let a={label:i.label,pinned:i.pinned,extra:i.extra,createdAt:i.createdAt,growable:i.growable};return new E(this,t,e,a,n,{sizes:i.files,append:!0})}catch(e){return n(),this.manager._writeFailed(this.name,e),null}}async remove(e){return this.removeById(await d(e))}async removeById(e){let t=await o(this._lockName(e),{mode:`exclusive`,ifAvailable:!0});if(!t)return!1;try{return await this._removeDir(e),this.manager._changed(this.name),!0}finally{t()}}async list(){let e=await this._dir(!1);if(!e)return[];let t=[];for await(let[n,r]of w(e)){let e=await C(r,_);e?.v===1&&t.push({...e,id:n})}return t}async clear(){let e=0;for(let{id:t}of await this.list())await this.removeById(t)&&e++;return e}async sweep(){let e=await this._dir(!1);if(!e)return 0;let t=await s(),n=0;for await(let[r,i]of w(e))t.has(this._lockName(r))||await this._validMeta(i)||await this.removeById(r)&&n++;return n}},O=class extends f{constructor({root:e,transport:t,namespace:n}){super(),this.namespace=n,this._root=e,this._transport=t,this._areas=new Map,this._budget=null;for(let e of Object.values(g))this.defineArea(e,{kind:e===g.SPILL?h.SCRATCH:h.CACHE})}defineArea(e,{kind:t=h.CACHE}={}){let n=this._areas.get(e);if(n){if(n.kind!==t)throw Error(`storage: area \"${e}\" is already defined as ${n.kind}`);return n}let r=new D(this,e,t);return this._areas.set(e,r),r}area(e){let t=this._areas.get(e);if(!t)throw Error(`storage: unknown area \"${e}\"`);return t}get areaNames(){return[...this._areas.keys()]}async estimate(){let e=typeof navigator<`u`?navigator.storage:null;if(!e?.estimate)return{quota:1/0,usage:0};let{quota:t=1/0,usage:n=0}=await e.estimate();return{quota:t,usage:n}}async persisted(){return await globalThis.navigator?.storage?.persisted?.()===!0}async persist(){let e=await globalThis.navigator?.storage?.persist?.()===!0;return this._changed(null),e}async budget(){if(this._budget!==null)return this._budget;let{quota:e}=await this.estimate();return Math.min(e*.3,v)}setBudget(e){this._budget=e===null?null:Math.max(0,e),this._changed(null)}async _cacheEntries(){let e=[];for(let t of this._areas.values())if(t.kind===h.CACHE)for(let n of await t.list())e.push({area:t,meta:n});return e}async usage(){let{quota:e,usage:t}=await this.estimate(),n={},r=0;for(let e of this._areas.values()){let t=await e.list(),i=t.reduce((e,t)=>e+(t.bytes??0),0);n[e.name]={kind:e.kind,bytes:i,entries:t.length},e.kind===h.CACHE&&(r+=i)}return{quota:e,usage:t,persisted:await this.persisted(),budget:await this.budget(),cacheBytes:r,areas:n}}async collect({freeBytes:e=null}={}){let t=await this._cacheEntries(),n=await this.budget(),r=t.reduce((e,t)=>e+(t.meta.bytes??0),0),i=e??Math.max(0,r-n);if(i<=0)return 0;let a=await s(),o=t.filter(({area:e,meta:t})=>!t.pinned&&!a.has(e._lockName(t.id))).sort((e,t)=>e.meta.lastUsed-t.meta.lastUsed),c=0;for(let{area:e,meta:t}of o){if(c>=i)break;await e.removeById(t.id)&&(c+=t.bytes??0,r-=t.bytes??0)}return c}async ensureSpace(e,t=h.CACHE){let n=async()=>{let{quota:n,usage:r}=await this.estimate(),i=e+y-(n-r);return t===h.CACHE?{free:i,budget:(await this._cacheEntries()).reduce((e,t)=>e+(t.meta.bytes??0),0)+e-await this.budget()}:{free:i,budget:0}},r=await n();return r.free<=0&&r.budget<=0?!0:(await this.collect({freeBytes:Math.max(r.free,r.budget)}),(await n()).free<=0)}async sweep(){let e=0;for(let t of this._areas.values())e+=await t.sweep(),t.kind===h.SCRATCH&&(e+=await t.clear());return e}_changed(e){this.dispatchEvent({type:`change`,area:e})}_issue(e,t,n={}){this.dispatchEvent({type:`issue`,code:e,message:t,detail:n})}_writeFailed(t,n){let r=n?.name===`QuotaExceededError`;this._issue(r?e.STORAGE_QUOTA_EXCEEDED:e.STORAGE_WRITE_FAILED,`${t}: ${n?.message??n}`,{area:t,error:n?.name})}dispose(){this._transport?.dispose(),this._transport=null,this._areas.clear()}};function k({namespace:e,root:t}){let n=new m(t);n.inline=!0;let r=new O({root:t,transport:n,namespace:e});return r.sweep().catch(()=>{}),r}const A=Object.freeze({IMMUTABLE:`immutable`,REVALIDATE:`revalidate`,NETWORK:`network`}),j=(e,t)=>({loaded:e,total:t,lengthComputable:t>0&&e<=t}),M=(e,t)=>e.headers?.get?.(t)??null,N=e=>e.reason??new DOMException(`aborted`,`AbortError`);function P(e){try{let t=new URL(e,globalThis.location?.href??`http://localhost/`).pathname;return decodeURIComponent(t.split(`/`).pop())||`download`}catch{return`download`}}async function F(e,{onProgress:t,signal:n}){let r=Number(M(e,`content-length`))||0,i=M(e,`content-type`)??``;if(!e.body)return new Blob([await e.arrayBuffer()],{type:i});let a=e.body.getReader(),o=[],s=0;for(;;){if(n?.aborted)throw a.cancel().catch(()=>{}),N(n);let{done:e,value:i}=await a.read();if(e)break;o.push(i),s+=i.length,t?.(j(s,r))}return new Blob(o,{type:i})}const I=(e,t,n)=>new File([e],t,{type:n||e.type,lastModified:e.lastModified??Date.now()}),L=()=>{};var R=class{constructor(e){this._storage=e,this._revalidating=new Set}get _area(){return this._storage?.area(g.DOWNLOADS)??null}async fetch(e,{key:t=e,name:n=P(e),policy:r=A.REVALIDATE,maxAgeMs:i=864e5,onProgress:a=null,signal:o=null,fetchOptions:s={}}={}){let c=this._area;if(c&&r!==A.NETWORK){let o=await c.open(t);if(o){let c=await o.file(`data`);if(c)return r===A.REVALIDATE&&Date.now()-(o.extra.checkedAt??0)>=i&&this._revalidate(e,t,n,o.extra,s),a?.(j(c.size,c.size)),{file:I(c,n,o.extra.contentType),release:()=>o.release(),fromCache:!0};o.release()}}return this._download(e,t,n,{onProgress:a,signal:o,fetchOptions:s,cache:!!c})}async has(e){return await this._area?.has(e)===!0}async _download(e,t,n,{onProgress:r,signal:i,fetchOptions:a,cache:o}){if(i?.aborted)throw N(i);let s=await fetch(e,{...a,signal:i});if(!s.ok)throw Error(`HTTP ${s.status} fetching ${e}`);let c=Number(M(s,`content-length`))||0,l={url:e,contentType:M(s,`content-type`)??``,lastModified:M(s,`last-modified`),contentLength:c||null,checkedAt:Date.now()},u=o&&s.body?await this._area.create(t,{label:n,expectedBytes:c}):null;if(!u)return{file:I(await F(s,{onProgress:r,signal:i}),n,l.contentType),release:L,fromCache:!1};try{await u.writeStream(`data`,s.body,{signal:i,onProgress:e=>r?.(j(e,c))}),await u.commit(l)}catch(o){if(await u.abort(),o?.name!==`QuotaExceededError`)throw o;return this._download(e,t,n,{onProgress:r,signal:i,fetchOptions:a,cache:!1})}let d=await this._area.open(t,{wait:!0}),f=d&&await d.file(`data`);if(!f)throw d?.release(),Error(`storage: ${n} vanished right after it was saved`);return{file:I(f,n,l.contentType),release:()=>d.release(),fromCache:!1}}async _revalidate(e,t,n,r,i){if(this._revalidating.has(t))return;this._revalidating.add(t);let a=!1;try{let t=new Headers(i?.headers);t.set(`Range`,`bytes=0-0`);let n=await fetch(e,{...i,headers:t});if(n.body?.cancel().catch(()=>{}),n.ok){let e=M(n,`last-modified`),t=n.status===206?Number(M(n,`content-range`)?.match(/\\/(\\d+)$/)?.[1])||null:Number(M(n,`content-length`))||null;a=!!(e&&r.lastModified&&e!==r.lastModified||t&&r.contentLength&&t!==r.contentLength)}}catch{}try{if(a){let{release:r}=await this._download(e,t,n,{fetchOptions:i,cache:!0});r()}else await this._area.patchMeta(t,{extra:{...r,checkedAt:Date.now()}})}catch{}finally{this._revalidating.delete(t)}}};let z={ortRuntimeUrl:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/ort.webgpu.bundle.min.mjs`,ortWasmPaths:`https://cdn.jsdelivr.net/npm/onnxruntime-web@1.24.3/dist/`,cacheNamespace:`rayzee`,storage:`auto`},B=null;async function V(){return B||(B=await import(z.ortRuntimeUrl),B.env.wasm.wasmPaths=z.ortWasmPaths,B.env.logLevel=`error`,B)}let H=null,U=null,W=null;function G(){return W??=(async()=>{if(z.storage===!1||!navigator.storage?.getDirectory)return new R(null);try{let e=await(await navigator.storage.getDirectory()).getDirectoryHandle(z.cacheNamespace,{create:!0}),t=k({namespace:z.cacheNamespace,root:e});return await K(t).catch(()=>{}),new R(t)}catch{return new R(null)}})(),W}async function K(e){let t=`${z.cacheNamespace}:ai-upscaler-models`;if(typeof indexedDB>`u`||!indexedDB.databases||!(await indexedDB.databases()).some(e=>e.name===t))return;let n=await new Promise((e,n)=>{let r=indexedDB.open(t);r.onerror=()=>n(r.error),r.onsuccess=()=>{let t=r.result;if(!t.objectStoreNames.contains(`models`)){t.close(),e([]);return}let i=[],a=t.transaction(`models`,`readonly`).objectStore(`models`).openCursor();a.onerror=()=>n(a.error),a.onsuccess=()=>{let n=a.result;if(!n){t.close(),e(i);return}i.push([n.key,n.value]),n.continue()}}}),r=e.area(`downloads`);for(let[e,t]of n){if(typeof e!=`string`||!(t instanceof ArrayBuffer)||await r.has(e))continue;let n=await r.create(e,{label:e.split(`/`).pop(),expectedBytes:t.byteLength});n&&(await n.write(`data`,t,{transfer:!0}),await n.commit({url:e,contentType:`application/octet-stream`,checkedAt:Date.now()}))}await new Promise(e=>{let n=indexedDB.deleteDatabase(t);n.onsuccess=n.onerror=n.onblocked=()=>e()})}async function q(e){let{file:t,release:n,fromCache:r}=await(await G()).fetch(e);try{let e=await t.arrayBuffer();return r&&console.log(`AI Upscaler Worker: model loaded from cache (${(e.byteLength/1024/1024).toFixed(1)}MB)`),e}finally{n()}}async function J(e,t){if(H&&U===e){self.postMessage({type:`loaded`,backend:`webgpu`});return}H&&=(await H.release(),null);let[n,r]=await Promise.all([q(e),V()]);H=await r.InferenceSession.create(n,t),U=e;let i=512;try{let e=await navigator.gpu?.requestAdapter(),t=await e?.requestAdapterInfo?.()||e?.info,n=/apple|swiftshader|llvmpipe/i.test(t?.vendor||``)||/apple|swiftshader/i.test(t?.architecture||``),r=t?.device?.toLowerCase?.()?.includes(`integrated`)||/intel.*iris|intel.*uhd|intel.*hd|amd.*vega|radeon.*graphics/i.test(t?.description||``);i=n?128:r?256:512,console.log(`AI Upscaler Worker: GPU=\"${t?.description||t?.device||`unknown`}\", tileSize=${i}`)}catch{}let a=(n.byteLength/1024/1024).toFixed(1);console.log(`AI Upscaler Worker: model loaded (${a}MB), backend: webgpu`),self.postMessage({type:`loaded`,backend:`webgpu`,tileSize:i})}async function Y(e,t,n,r){let i=await V(),a=H.inputNames[0],o=H.outputNames[0],s=new i.Tensor(`float32`,e,[1,3,n,t]),c=(await H.run({[a]:s}))[o].data;self.postMessage({type:`inferred`,outputData:c,id:r},[c.buffer])}self.onmessage=async e=>{let{type:t}=e.data;try{t===`load`?(e.data.ortRuntimeUrl&&(z.ortRuntimeUrl=e.data.ortRuntimeUrl),e.data.ortWasmPaths&&(z.ortWasmPaths=e.data.ortWasmPaths),e.data.cacheNamespace&&(z.cacheNamespace=e.data.cacheNamespace),e.data.storage!==void 0&&(z.storage=e.data.storage),await J(e.data.url,e.data.sessionOptions)):t===`infer`?await Y(e.data.tileData,e.data.width,e.data.height,e.data.id):t===`dispose`&&H&&(await H.release(),H=null,U=null)}catch(t){self.postMessage({type:`error`,message:t.message,id:e.data?.id})}};", Hk = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", Vk], { type: "text/javascript;charset=utf-8" });
44523
+ function Uk(e) {
44440
44524
  let t;
44441
44525
  try {
44442
- if (t = Bk && (self.URL || self.webkitURL).createObjectURL(Bk), !t) throw "";
44526
+ if (t = Hk && (self.URL || self.webkitURL).createObjectURL(Hk), !t) throw "";
44443
44527
  let n = new Worker(t, {
44444
44528
  type: "module",
44445
44529
  name: e?.name
@@ -44448,7 +44532,7 @@ function Vk(e) {
44448
44532
  (self.URL || self.webkitURL).revokeObjectURL(t);
44449
44533
  }), n;
44450
44534
  } catch {
44451
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(zk), {
44535
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(Vk), {
44452
44536
  type: "module",
44453
44537
  name: e?.name
44454
44538
  });
@@ -44456,7 +44540,7 @@ function Vk(e) {
44456
44540
  }
44457
44541
  //#endregion
44458
44542
  //#region src/Passes/AIUpscaler.js
44459
- var Hk = (e) => Y_(e) ? ((e) => e > 1 ? 1 : e < 0 ? 0 : e) : ((e) => e ** +X_), Uk = {
44543
+ var Wk = {
44460
44544
  fast: {
44461
44545
  2: "2x-spanx2-ch48.onnx",
44462
44546
  4: "4xNomos8k_span_otf_strong_fp32_opset17.onnx"
@@ -44470,17 +44554,17 @@ var Hk = (e) => Y_(e) ? ((e) => e > 1 ? 1 : e < 0 ? 0 : e) : ((e) => e ** +X_),
44470
44554
  4: "4xNomos2_hq_mosr_fp32.onnx"
44471
44555
  }
44472
44556
  };
44473
- function Wk() {
44557
+ function Gk() {
44474
44558
  let { upscalerModelBaseUrl: e } = A(), t = {};
44475
- for (let n in Uk) {
44559
+ for (let n in Wk) {
44476
44560
  t[n] = {};
44477
- for (let r in Uk[n]) t[n][r] = e + Uk[n][r];
44561
+ for (let r in Wk[n]) t[n][r] = e + Wk[n][r];
44478
44562
  }
44479
44563
  return t;
44480
44564
  }
44481
- var Gk = {
44565
+ var Kk = {
44482
44566
  get QUALITY_PRESETS() {
44483
- return Wk();
44567
+ return Gk();
44484
44568
  },
44485
44569
  TILE_SIZE: 512,
44486
44570
  TILE_OVERLAP: 16,
@@ -44491,17 +44575,17 @@ var Gk = {
44491
44575
  }],
44492
44576
  graphOptimizationLevel: "all"
44493
44577
  }
44494
- }, Kk = class extends en {
44578
+ }, qk = class extends en {
44495
44579
  constructor(e, t, n = {}) {
44496
44580
  if (super(), !e || !t) throw Error("AIUpscaler requires output canvas and renderer");
44497
- this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => At), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.refreshInput = n.refreshInput || null, this.tileSize = n.tileSize || Gk.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
44581
+ this.renderer = t, this.input = t.domElement, this.output = e, this.getSourceCanvas = n.getSourceCanvas || null, this.getGPUTextures = n.getGPUTextures || null, this.getExposure = n.getExposure || (() => 1), this.getToneMapping = n.getToneMapping || (() => At), this.getSaturation = n.getSaturation || (() => 1), this.enabled = !1, this.hdr = !1, this.scaleFactor = n.scaleFactor || 2, this.quality = n.quality || "fast", this.refreshInput = n.refreshInput || null, this.tileSize = n.tileSize || Kk.TILE_SIZE, this._tileSizeOverride = !!n.tileSize, this.state = {
44498
44582
  isUpscaling: !1,
44499
44583
  isLoading: !1,
44500
44584
  abortController: null
44501
- }, this._worker = null, this._currentModelUrl = null, this._tileId = 0, this._pendingWorkerHandlers = /* @__PURE__ */ new Set(), this._upscaledAlpha = null, this._upscaledAlphaWidth = 0, this._backupCanvas = null, this._baseWidth = e.width, this._baseHeight = e.height, this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0;
44585
+ }, this._worker = null, this._currentModelUrl = null, this._tileId = 0, this._pendingWorkerHandlers = /* @__PURE__ */ new Set(), this._upscaledAlpha = null, this._upscaledAlphaWidth = 0, this._backupCanvas = null, this._baseWidth = e.width, this._baseHeight = e.height, this._toneMapper = null;
44502
44586
  }
44503
44587
  async _ensureSession() {
44504
- let e = Gk.QUALITY_PRESETS[this.quality];
44588
+ let e = Kk.QUALITY_PRESETS[this.quality];
44505
44589
  if (!e) throw Error(`Unknown quality preset: ${this.quality}`);
44506
44590
  let t = e[this.scaleFactor];
44507
44591
  if (!t) throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);
@@ -44511,14 +44595,14 @@ var Gk = {
44511
44595
  message: `Loading ${this.scaleFactor}x upscale model...`
44512
44596
  });
44513
44597
  try {
44514
- this._worker ||= new Vk(), await new Promise((e, n) => {
44598
+ this._worker ||= new Uk(), await new Promise((e, n) => {
44515
44599
  let r = (t) => {
44516
44600
  t.data.type === "loaded" ? (this._worker.removeEventListener("message", r), t.data.tileSize && !this._tileSizeOverride && (this.tileSize = t.data.tileSize), console.log(`AI Upscaler: ${this.scaleFactor}x model loaded, backend: ${t.data.backend}, tileSize: ${this.tileSize}`), e()) : t.data.type === "error" && (this._worker.removeEventListener("message", r), n(Error(t.data.message)));
44517
44601
  }, { ortRuntimeUrl: i, ortWasmPaths: a, cacheNamespace: o, storage: s } = A();
44518
44602
  this._worker.addEventListener("message", r), this._worker.postMessage({
44519
44603
  type: "load",
44520
44604
  url: t,
44521
- sessionOptions: Gk.SESSION_OPTIONS,
44605
+ sessionOptions: Kk.SESSION_OPTIONS,
44522
44606
  ortRuntimeUrl: i,
44523
44607
  ortWasmPaths: a,
44524
44608
  cacheNamespace: o,
@@ -44592,8 +44676,8 @@ var Gk = {
44592
44676
  willReadFrequently: !0,
44593
44677
  alpha: !0
44594
44678
  });
44595
- this._cacheUpscaledAlpha(t, n * i, r * i), t.isHDR && (this._hdrToneMapFn = q_.get(this.getToneMapping()) || q_.get(At), this._hdrEncode = Hk(this.getToneMapping()), this._hdrExposure = Q_(this.getExposure(), this.getToneMapping()), this._hdrSaturation = this.getSaturation(), this._tmOut = new Float32Array(3));
44596
- let o = Gk.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
44679
+ this._cacheUpscaledAlpha(t, n * i, r * i);
44680
+ let o = Kk.TILE_OVERLAP, s = this.tileSize, c = s - o * 2, l = Math.ceil(n / c), u = Math.ceil(r / c), d = l * u, f = 0;
44597
44681
  for (let o = 0; o < u; o++) for (let u = 0; u < l; u++) {
44598
44682
  if (e.aborted) throw new DOMException("Aborted", "AbortError");
44599
44683
  let l = Math.min(u * c, Math.max(0, n - s)), p = Math.min(o * c, Math.max(0, r - s)), m = Math.min(s, n - l), h = Math.min(s, r - p), g = this._extractTile(t, l, p, m, h), _ = await this._inferTile(g, m, h), v = l * i, y = p * i, b = m * i, x = h * i, S = this._tensorToImageData(_, b, x, v, y);
@@ -44633,46 +44717,39 @@ var Gk = {
44633
44717
  async _captureSourceHDR() {
44634
44718
  let e = this.getGPUTextures();
44635
44719
  if (!e?.color) throw Error("No GPU color texture available for HDR capture");
44636
- let t = this.renderer.backend.device, n = e.color, r = n.width, i = n.height, a = Math.ceil(r * 16 / 256) * 256, o = a * i;
44637
- (this._hdrStagingWidth !== r || this._hdrStagingHeight !== i) && (this._hdrStagingBuffer?.destroy(), this._hdrStagingBuffer = t.createBuffer({
44638
- label: "aiupscaler-hdr-readback",
44639
- size: o,
44640
- usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
44641
- }), this._hdrStagingWidth = r, this._hdrStagingHeight = i);
44642
- let s = this._hdrStagingBuffer, c = t.createCommandEncoder();
44643
- c.copyTextureToBuffer({ texture: n }, {
44644
- buffer: s,
44645
- bytesPerRow: a,
44646
- rowsPerImage: i
44647
- }, {
44648
- width: r,
44649
- height: i,
44650
- depthOrArrayLayers: 1
44651
- }), t.queue.submit([c.finish()]), await s.mapAsync(GPUMapMode.READ);
44652
- let l = new Float32Array(s.getMappedRange()), u = r * 4, d = a / 4, f = new Float32Array(r * i * 4);
44653
- for (let e = 0; e < i; e++) {
44654
- let t = e * d, n = e * u;
44655
- f.set(l.subarray(t, t + u), n);
44656
- }
44657
- return s.unmap(), {
44658
- data: f,
44659
- width: r,
44660
- height: i,
44720
+ let t = e.color, { width: n, height: r } = t;
44721
+ this._toneMapper ??= new T(this.renderer.backend.device, "aiupscaler-tonemap", {
44722
+ input: "texture",
44723
+ output: "planar"
44724
+ }), this._toneMapper.ensureSize(n, r);
44725
+ let i = await this._toneMapper.toPlanar(t, {
44726
+ exposure: this.getExposure(),
44727
+ toneMapping: this.getToneMapping() ?? At,
44728
+ saturation: this.getSaturation()
44729
+ });
44730
+ return this._toneMapper.release(), {
44731
+ planes: i,
44732
+ width: n,
44733
+ height: r,
44661
44734
  isHDR: !0
44662
44735
  };
44663
44736
  }
44664
44737
  _extractTile(e, t, n, r, i) {
44665
- let { data: a, width: o } = e, s = e.isHDR, c = r * i, l = new Float32Array(3 * c);
44738
+ let { width: a } = e, o = r * i, s = new Float32Array(3 * o);
44739
+ if (e.isHDR) {
44740
+ let { planes: c } = e, l = a * e.height;
44741
+ for (let e = 0; e < 3; e++) for (let u = 0; u < i; u++) {
44742
+ let i = e * l + (n + u) * a + t;
44743
+ s.set(c.subarray(i, i + r), e * o + u * r);
44744
+ }
44745
+ return s;
44746
+ }
44747
+ let { data: c } = e;
44666
44748
  for (let e = 0; e < i; e++) for (let i = 0; i < r; i++) {
44667
- let u = ((n + e) * o + (t + i)) * 4, d = e * r + i;
44668
- if (s) {
44669
- let e = this._hdrToneMapFn, t = this._hdrExposure, n = this._hdrSaturation, r = a[u] * t, i = a[u + 1] * t, o = a[u + 2] * t;
44670
- n !== 1 && (this._tmOut[0] = r, this._tmOut[1] = i, this._tmOut[2] = o, nv(this._tmOut, n), r = this._tmOut[0], i = this._tmOut[1], o = this._tmOut[2]), e(r, i, o, 1, this._tmOut);
44671
- let s = this._hdrEncode;
44672
- l[d] = s(this._tmOut[0]), l[c + d] = s(this._tmOut[1]), l[2 * c + d] = s(this._tmOut[2]);
44673
- } else l[d] = a[u] / 255, l[c + d] = a[u + 1] / 255, l[2 * c + d] = a[u + 2] / 255;
44749
+ let l = ((n + e) * a + (t + i)) * 4, u = e * r + i;
44750
+ s[u] = c[l] / 255, s[o + u] = c[l + 1] / 255, s[2 * o + u] = c[l + 2] / 255;
44674
44751
  }
44675
- return l;
44752
+ return s;
44676
44753
  }
44677
44754
  async _inferTile(e, t, n) {
44678
44755
  let r = ++this._tileId;
@@ -44698,41 +44775,41 @@ var Gk = {
44698
44775
  return a;
44699
44776
  }
44700
44777
  _cacheUpscaledAlpha(e, t, n) {
44701
- let { data: r, width: i, height: a } = e, o = e.isHDR, s = o ? 1 : 255, c = !1;
44702
- for (let e = 3; e < r.length; e += 4) if (r[e] < s) {
44703
- c = !0;
44778
+ let { width: r, height: i } = e, a = r * i, o = e.isHDR, s = o ? e.planes.subarray(3 * a) : e.data, c = o ? 1 : 4, l = o ? 0 : 3, u = o ? 1 : 255, d = !1;
44779
+ for (let e = l; e < s.length; e += c) if (s[e] < u) {
44780
+ d = !0;
44704
44781
  break;
44705
44782
  }
44706
- if (!c) {
44783
+ if (!d) {
44707
44784
  this._upscaledAlpha = null, this._upscaledAlphaWidth = 0;
44708
44785
  return;
44709
44786
  }
44710
- let l = document.createElement("canvas");
44711
- l.width = i, l.height = a;
44712
- let u = l.getContext("2d"), d = u.createImageData(i, a);
44713
- for (let e = 0, t = i * a; e < t; e++) {
44714
- let t = o ? Math.min(Math.max(r[e * 4 + 3] * 255, 0), 255) | 0 : r[e * 4 + 3];
44715
- d.data[e * 4] = t, d.data[e * 4 + 1] = t, d.data[e * 4 + 2] = t, d.data[e * 4 + 3] = 255;
44716
- }
44717
- u.putImageData(d, 0, 0);
44718
44787
  let f = document.createElement("canvas");
44719
- f.width = t, f.height = n;
44720
- let p = f.getContext("2d");
44721
- p.imageSmoothingEnabled = !0, p.imageSmoothingQuality = "high", p.drawImage(l, 0, 0, t, n);
44722
- let m = p.getImageData(0, 0, t, n).data, h = new Uint8Array(t * n);
44723
- for (let e = 0, r = t * n; e < r; e++) h[e] = m[e * 4];
44724
- this._upscaledAlpha = h, this._upscaledAlphaWidth = t;
44788
+ f.width = r, f.height = i;
44789
+ let p = f.getContext("2d"), m = p.createImageData(r, i);
44790
+ for (let e = 0; e < a; e++) {
44791
+ let t = o ? Math.min(Math.max(s[e] * 255, 0), 255) | 0 : s[e * 4 + 3];
44792
+ m.data[e * 4] = t, m.data[e * 4 + 1] = t, m.data[e * 4 + 2] = t, m.data[e * 4 + 3] = 255;
44793
+ }
44794
+ p.putImageData(m, 0, 0);
44795
+ let h = document.createElement("canvas");
44796
+ h.width = t, h.height = n;
44797
+ let g = h.getContext("2d");
44798
+ g.imageSmoothingEnabled = !0, g.imageSmoothingQuality = "high", g.drawImage(f, 0, 0, t, n);
44799
+ let _ = g.getImageData(0, 0, t, n).data, v = new Uint8Array(t * n);
44800
+ for (let e = 0, r = t * n; e < r; e++) v[e] = _[e * 4];
44801
+ this._upscaledAlpha = v, this._upscaledAlphaWidth = t;
44725
44802
  }
44726
44803
  _createBackup(e) {
44727
44804
  this._backupCanvas = document.createElement("canvas"), this._backupCanvas.width = e.width, this._backupCanvas.height = e.height;
44728
44805
  let t = this._backupCanvas.getContext("2d");
44729
44806
  if (e.isHDR) {
44730
- let { data: n, width: r, height: i } = e, a = t.createImageData(r, i), o = a.data, s = q_.get(this.getToneMapping()) || q_.get(At), c = Q_(this.getExposure(), this.getToneMapping()), l = Hk(this.getToneMapping()), u = this.getSaturation(), d = new Float32Array(3);
44731
- for (let e = 0, t = r * i; e < t; e++) {
44732
- let t = e * 4, r = n[t] * c, i = n[t + 1] * c, a = n[t + 2] * c;
44733
- u !== 1 && (d[0] = r, d[1] = i, d[2] = a, nv(d, u), r = d[0], i = d[1], a = d[2]), s(r, i, a, 1, d), o[t] = l(d[0]) * 255 + .5 | 0, o[t + 1] = l(d[1]) * 255 + .5 | 0, o[t + 2] = l(d[2]) * 255 + .5 | 0, o[t + 3] = 255;
44807
+ let { planes: n, width: r, height: i } = e, a = r * i, o = t.createImageData(r, i), s = o.data;
44808
+ for (let e = 0; e < a; e++) {
44809
+ let t = e * 4;
44810
+ s[t] = n[e] * 255 + .5 | 0, s[t + 1] = n[a + e] * 255 + .5 | 0, s[t + 2] = n[2 * a + e] * 255 + .5 | 0, s[t + 3] = 255;
44734
44811
  }
44735
- t.putImageData(a, 0, 0);
44812
+ t.putImageData(o, 0, 0);
44736
44813
  } else t.putImageData(e, 0, 0);
44737
44814
  }
44738
44815
  _restoreBackup() {
@@ -44742,7 +44819,7 @@ var Gk = {
44742
44819
  this.hdr = !!e;
44743
44820
  }
44744
44821
  setQuality(e) {
44745
- if (!Gk.QUALITY_PRESETS[e]) {
44822
+ if (!Kk.QUALITY_PRESETS[e]) {
44746
44823
  console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);
44747
44824
  return;
44748
44825
  }
@@ -44763,9 +44840,9 @@ var Gk = {
44763
44840
  this._pendingWorkerHandlers.clear();
44764
44841
  }
44765
44842
  async dispose() {
44766
- this.abort(), this._cleanupPendingWorkerHandlers(), this._worker &&= (this._worker.postMessage({ type: "dispose" }), this._worker.terminate(), null), this._currentModelUrl = null, this._backupCanvas = null, this._upscaledAlpha = null, this.state.abortController = null, this._hdrStagingBuffer?.destroy(), this._hdrStagingBuffer = null, this._hdrStagingWidth = 0, this._hdrStagingHeight = 0, console.log("AIUpscaler disposed");
44843
+ this.abort(), this._cleanupPendingWorkerHandlers(), this._worker &&= (this._worker.postMessage({ type: "dispose" }), this._worker.terminate(), null), this._currentModelUrl = null, this._backupCanvas = null, this._upscaledAlpha = null, this.state.abortController = null, this._toneMapper?.dispose(), this._toneMapper = null, console.log("AIUpscaler disposed");
44767
44844
  }
44768
- }, qk = a("neural"), Jk = 120, Yk = 2, Xk = 1, Zk = 0, Qk = 300, $k = 5, eA = 3, tA = 3, nA = 16, rA = (e) => Math.max(0, 1 - e / nA), iA = class extends en {
44845
+ }, Jk = a("neural"), Yk = 120, Xk = 2, Zk = 1, Qk = 0, $k = 300, eA = 5, tA = 3, nA = 3, rA = 16, iA = (e) => Math.max(0, 1 - e / rA), aA = class extends en {
44769
44846
  constructor({ renderer: e, mainCanvas: t, stages: n, pipeline: r, getExposure: i, getSaturation: a, issues: o = null }) {
44770
44847
  super(), this.renderer = e, this._issues = o, this.mainCanvas = t, this.upscalerCanvas = this._createUpscalerCanvas(t), this.pipeline = r, this._stages = n, this._getExposure = i, this._getSaturation = a, this.denoiser = null, this.upscaler = null, this.upscalerBackend = "esrgan", this._neuralUpscaler = null, this.neuralRendering = !1, this.neuralRenderingSettings = {}, this._retouch = null, this._superResModule = null, this._neuralPostBusy = !1, this._finalQuality = Q.oidnQuality, this.finalDenoise = Q.enableOIDN, this.continuousDenoise = Q.continuousDenoise, this.continuousDenoiseInterval = Q.continuousDenoiseInterval, this._lastCadenceAt = -Infinity, this._lastCadenceSamples = 0, this._failedRefreshes = 0, this._cadenceSuspended = !1, this._movingDenoiseMs = [], this._movingHopeless = !1, this._holdWhileMoving = null, this._onReset = null, this._onPostProcessRefresh = null, this._onDisplayRefresh = null, this.temporalHistory = Q.oidnTemporalHistory, this._history = null, this._historyDirty = !0, this._knownResetCount = 0, this._seenTracedFrames = 0, this._viewProj = new yn(), this._historyCamera = {
44771
44848
  world: null,
@@ -44798,7 +44875,7 @@ var Gk = {
44798
44875
  }
44799
44876
  setupDenoiser() {
44800
44877
  let t = this._stages.pathTracer;
44801
- this.denoiser = new Sk(this.renderer, {
44878
+ this.denoiser = new wk(this.renderer, {
44802
44879
  ...Q,
44803
44880
  backendParams: () => ({
44804
44881
  device: this.renderer.backend.device,
@@ -44837,7 +44914,7 @@ var Gk = {
44837
44914
  setupUpscaler() {
44838
44915
  if (!this.upscalerCanvas) return;
44839
44916
  let t = this._stages.pathTracer;
44840
- this.upscaler = new Kk(this.upscalerCanvas, this.renderer, {
44917
+ this.upscaler = new qk(this.upscalerCanvas, this.renderer, {
44841
44918
  scaleFactor: Q.upscalerScale || 2,
44842
44919
  quality: Q.upscalerQuality || "fast",
44843
44920
  getSourceCanvas: () => this.renderer.domElement,
@@ -44913,8 +44990,8 @@ var Gk = {
44913
44990
  get holdsWhileMoving() {
44914
44991
  if (!this._stages.pathTracer?.viewIsChanging || !this.continuousDenoise || this._cadenceSuspended || !this.denoiser?.enabled || this._movingHopeless) return !1;
44915
44992
  let e = this.movingCostMs, t = this._movingDenoiseMs.length;
44916
- e > Qk * eA && (this._movingHopeless = !0, this._syncGBufferStages());
44917
- let n = !this._movingHopeless && (t < 2 || e <= Qk);
44993
+ e > $k * tA && (this._movingHopeless = !0, this._syncGBufferStages());
44994
+ let n = !this._movingHopeless && (t < 2 || e <= $k);
44918
44995
  return this._holdWhileMoving = (this._holdWhileMoving === null || this._holdWhileMoving) && n, this._holdWhileMoving;
44919
44996
  }
44920
44997
  skipsTrace() {
@@ -44931,7 +45008,7 @@ var Gk = {
44931
45008
  this.pipeline?.context?.removeTexture("oidn:output"), this.denoiser?.invalidateOutput();
44932
45009
  }
44933
45010
  _checkHeldFrameHealthy() {
44934
- !this.denoiser?.hasOutput || this._failedRefreshes < tA || this._unpublishOutput();
45011
+ !this.denoiser?.hasOutput || this._failedRefreshes < nA || this._unpublishOutput();
44935
45012
  }
44936
45013
  tickContinuousDenoise(e) {
44937
45014
  let t = this.denoiser;
@@ -44941,12 +45018,12 @@ var Gk = {
44941
45018
  if (!n) this._holdWhileMoving = null, this._movingDenoiseMs.length = 0;
44942
45019
  else if (!this.holdsWhileMoving) return !1;
44943
45020
  if (t.state.isDenoising || t.state.isLoading || !n && e <= this._lastCadenceSamples) return !1;
44944
- let r = performance.now(), i = n ? Zk : this._lastCadenceSamples === 0 ? Xk : Yk, a = Math.max(this.continuousDenoiseInterval, t.lastDenoiseMs * i);
45021
+ let r = performance.now(), i = n ? Qk : this._lastCadenceSamples === 0 ? Zk : Xk, a = Math.max(this.continuousDenoiseInterval, t.lastDenoiseMs * i);
44945
45022
  if (r - this._lastCadenceAt < a) return !1;
44946
- this._lastCadenceAt = r, this._lastCadenceSamples = e, t.lastDenoiseMs > Jk && (this._cadenceDowngraded = !0);
45023
+ this._lastCadenceAt = r, this._lastCadenceSamples = e, t.lastDenoiseMs > Yk && (this._cadenceDowngraded = !0);
44947
45024
  let o = this._cadenceDowngraded ? this.previewQuality() : this._finalQuality;
44948
45025
  return t.quality !== o && t.updateQuality(o), t.start({ continuous: !0 }).then((e) => {
44949
- this._failedRefreshes = e ? 0 : this._failedRefreshes + 1, !(!e || !n) && (this._movingDenoiseMs.push(t.lastDenoiseMs), this._movingDenoiseMs.length > $k && this._movingDenoiseMs.shift());
45026
+ this._failedRefreshes = e ? 0 : this._failedRefreshes + 1, !(!e || !n) && (this._movingDenoiseMs.push(t.lastDenoiseMs), this._movingDenoiseMs.length > eA && this._movingDenoiseMs.shift());
44950
45027
  }), !0;
44951
45028
  }
44952
45029
  previewQuality() {
@@ -44988,7 +45065,7 @@ var Gk = {
44988
45065
  r && (this._ensureHistory().merge(r, t.frameCount, this._historyCameraNow(), {
44989
45066
  commit: !0,
44990
45067
  keepHistory: !this._historyDirty && !n,
44991
- historyScale: rA(t.frameCount)
45068
+ historyScale: iA(t.frameCount)
44992
45069
  }), this._historyDirty = !1);
44993
45070
  }
44994
45071
  afterReset() {
@@ -45031,9 +45108,9 @@ var Gk = {
45031
45108
  let e = this._stages.pathTracer, t = this._history;
45032
45109
  if (!t?.valid || this._historyDirty || !this.historyActive || e.isComplete || e.resetCount !== this._knownResetCount || t.width !== this._lastRenderWidth || t.height !== this._lastRenderHeight) return null;
45033
45110
  if (e.frameCount <= 1) return t.textures;
45034
- if (e.frameCount >= nA) return null;
45111
+ if (e.frameCount >= rA) return null;
45035
45112
  let n = this._historyInputs();
45036
- return n ? t.merge(n, e.frameCount, this._historyCameraNow(), { historyScale: rA(e.frameCount) }) : null;
45113
+ return n ? t.merge(n, e.frameCount, this._historyCameraNow(), { historyScale: iA(e.frameCount) }) : null;
45037
45114
  }
45038
45115
  _historyInputs() {
45039
45116
  let e = this._stages.pathTracer, t = this.pipeline?.context, n = this.renderer?.backend;
@@ -45058,7 +45135,7 @@ var Gk = {
45058
45135
  return t.world = e.cameraWorldMatrix.value.elements, t.projInv = e.cameraProjectionMatrixInverse.value.elements, t.viewProj = this._viewProj.elements, t.orthographic = e.uniforms?.get("cameraProjection")?.value === hi.orthographic, t;
45059
45136
  }
45060
45137
  _ensureHistory() {
45061
- return this._history ??= new Rk(this.renderer.backend.device), this._history.settings.cleanAux = !!this.denoiser?.expectsCleanAux(this._finalQuality), this._history;
45138
+ return this._history ??= new Bk(this.renderer.backend.device), this._history.settings.cleanAux = !!this.denoiser?.expectsCleanAux(this._finalQuality), this._history;
45062
45139
  }
45063
45140
  _releaseHistory() {
45064
45141
  this._history?.dispose(), this._history = null, this._historyDirty = !0, this._movedPlacements.clear();
@@ -45095,15 +45172,15 @@ var Gk = {
45095
45172
  return;
45096
45173
  }
45097
45174
  if (!this.pipeline?.context?.getTexture("oidn:output")) {
45098
- qk.warn("neural pass skipped: no denoised picture — it needs OIDN");
45175
+ Jk.warn("neural pass skipped: no denoised picture — it needs OIDN");
45099
45176
  return;
45100
45177
  }
45101
45178
  this._neuralPostBusy = !0, this.dispatchEvent({ type: e.UPSCALING_START });
45102
45179
  try {
45103
- let i = await import("./NeuralSuperRes-PkgDLQcD.js").then((e) => e.t);
45180
+ let i = await import("./NeuralSuperRes-FVqRJKQV.js").then((e) => e.t);
45104
45181
  this._superResModule = i;
45105
- let a = r ? await import("./NeuralRetouch-CYgkQY8Z.js").then((e) => e.t) : null, o = this.denoiser?._outTexSize, s = (o?.width ?? 0) * (o?.height ?? 0), c = r && s <= a.RETOUCH_MAX_PIXELS;
45106
- if (r && !c && (qk.warn(`Neural rendering skipped: the render is ${(s / 1e6).toFixed(1)} MP, above the ${(a.RETOUCH_MAX_PIXELS / 1e6).toFixed(1)} MP the pass survives.` + (n ? " The upscale still ran." : "")), this._releaseNeuralRetouch()), !n && !c) return;
45182
+ let a = r ? await import("./NeuralRetouch-vkdXXyK2.js").then((e) => e.t) : null, o = this.denoiser?._outTexSize, s = (o?.width ?? 0) * (o?.height ?? 0), c = r && s <= a.RETOUCH_MAX_PIXELS;
45183
+ if (r && !c && (Jk.warn(`Neural rendering skipped: the render is ${(s / 1e6).toFixed(1)} MP, above the ${(a.RETOUCH_MAX_PIXELS / 1e6).toFixed(1)} MP the pass survives.` + (n ? " The upscale still ran." : "")), this._releaseNeuralRetouch()), !n && !c) return;
45107
45184
  let l = {
45108
45185
  exposure: this._getEffectiveExposure(),
45109
45186
  toneMapping: this._getToneMapping(),
@@ -45138,7 +45215,7 @@ var Gk = {
45138
45215
  height: d.height
45139
45216
  });
45140
45217
  } catch (e) {
45141
- qk.warn("neural pass failed", e);
45218
+ Jk.warn("neural pass failed", e);
45142
45219
  } finally {
45143
45220
  this._neuralPostBusy = !1, this.dispatchEvent({ type: e.UPSCALING_END });
45144
45221
  }
@@ -45304,7 +45381,7 @@ var Gk = {
45304
45381
  let t = Ci[e];
45305
45382
  t && (this._stages.asvgf?.updateParameters(t), this._stages.bilateralFilter?.updateParameters(t), this._stages.variance && t.varianceBoost !== void 0 && (this._stages.variance.varianceBoost.value = t.varianceBoost));
45306
45383
  }
45307
- }, aA = class {
45384
+ }, oA = class {
45308
45385
  constructor() {
45309
45386
  this.layer = "hud", this.visible = !1, this._tileBounds = null, this._imageWidth = 1, this._imageHeight = 1, this.enabled = !0, this._borderColor = "rgba(255, 0, 0, 0.6)", this._borderWidthRatio = 1 / 540, this._borderWidthMin = 1.5, this._borderWidthMax = 4;
45310
45387
  }
@@ -45328,7 +45405,7 @@ var Gk = {
45328
45405
  dispose() {
45329
45406
  this.visible = !1;
45330
45407
  }
45331
- }, oA = class {
45408
+ }, sA = class {
45332
45409
  constructor(e, t) {
45333
45410
  this.layer = "scene", this._enabled = !0, this._scene = e, this._camera = t, this._build([]);
45334
45411
  }
@@ -45366,11 +45443,11 @@ var Gk = {
45366
45443
  this._enabled = !1, this._outlineNode?.dispose(), this._material?.dispose(), this._quad = null;
45367
45444
  }
45368
45445
  };
45369
- function sA(e = !1) {
45446
+ function cA(e = !1) {
45370
45447
  let t = document.createElement("canvas");
45371
45448
  return t.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" + (e ? "display:none;" : ""), t;
45372
45449
  }
45373
- function cA(e, t = Infinity) {
45450
+ function lA(e, t = Infinity) {
45374
45451
  let n = e?.getBoundingClientRect();
45375
45452
  if (!n || n.width === 0 || n.height === 0) return null;
45376
45453
  let r = Math.min(window.devicePixelRatio || 1, 2), i = Math.round(n.width * r), a = Math.round(n.height * r), o = t / Math.max(i, a);
@@ -45381,9 +45458,9 @@ function cA(e, t = Infinity) {
45381
45458
  }
45382
45459
  //#endregion
45383
45460
  //#region src/managers/helpers/ViewOverlayRenderer.js
45384
- var lA = 4096, uA = class {
45461
+ var uA = 4096, dA = class {
45385
45462
  constructor() {
45386
- this.canvas = sA(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
45463
+ this.canvas = cA(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
45387
45464
  }
45388
45465
  async init({ device: e, sizeSource: t }) {
45389
45466
  this._sizeSource = t;
@@ -45400,7 +45477,7 @@ var lA = 4096, uA = class {
45400
45477
  }
45401
45478
  syncSize() {
45402
45479
  if (!this.renderer) return;
45403
- let e = cA(this._sizeSource, lA);
45480
+ let e = lA(this._sizeSource, uA);
45404
45481
  !e || e.width === this.canvas.width && e.height === this.canvas.height || this.renderer.setSize(e.width, e.height, !1);
45405
45482
  }
45406
45483
  begin() {
@@ -45412,18 +45489,18 @@ var lA = 4096, uA = class {
45412
45489
  dispose() {
45413
45490
  ei(this.renderer), this.renderer = null, this.canvas.parentElement?.removeChild(this.canvas);
45414
45491
  }
45415
- }, dA = a("overlay"), fA = (e, t) => e.visible && e.layer === t && e.render, pA = class {
45492
+ }, fA = a("overlay"), pA = (e, t) => e.visible && e.layer === t && e.render, mA = class {
45416
45493
  constructor(e) {
45417
- this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = sA(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
45494
+ this.camera = e, this._helpers = /* @__PURE__ */ new Map(), this._hudCanvas = cA(), this._hudCtx = this._hudCanvas.getContext("2d"), this._helperScene = null, this._viewOverlay = null;
45418
45495
  }
45419
45496
  async initViewRenderer({ device: e, sizeSource: t }) {
45420
45497
  if (!(!e || !t)) try {
45421
- this._viewOverlay = await new uA().init({
45498
+ this._viewOverlay = await new dA().init({
45422
45499
  device: e,
45423
45500
  sizeSource: t
45424
45501
  });
45425
45502
  } catch (e) {
45426
- dA.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
45503
+ fA.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
45427
45504
  }
45428
45505
  }
45429
45506
  gpuResources() {
@@ -45443,11 +45520,11 @@ var lA = 4096, uA = class {
45443
45520
  }
45444
45521
  setupDefaultHelpers({ helperScene: t, meshScene: n, pipeline: r, denoisingManager: i, app: a, renderWidth: o, renderHeight: s }) {
45445
45522
  this.setHelperScene(t);
45446
- let c = new aA();
45523
+ let c = new oA();
45447
45524
  this.register("tiles", c), c.setRenderSize(o || 1, s || 1), a.addEventListener(e.RESOLUTION_CHANGED, (e) => {
45448
45525
  c.setRenderSize(e.width, e.height);
45449
45526
  }), r.eventBus.on("pipeline:reset", () => c.hide()), this._wireDenoiserTileEvents(c, i);
45450
- let l = new oA(n, this.camera);
45527
+ let l = new sA(n, this.camera);
45451
45528
  this.register("outline", l);
45452
45529
  }
45453
45530
  _wireDenoiserTileEvents(e, t) {
@@ -45459,7 +45536,7 @@ var lA = 4096, uA = class {
45459
45536
  }));
45460
45537
  }
45461
45538
  register(e, t) {
45462
- this._helpers.has(e) && (dA.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
45539
+ this._helpers.has(e) && (fA.warn(`helper "${e}" already registered — replacing.`), this._helpers.get(e).dispose?.()), this._helpers.set(e, t);
45463
45540
  }
45464
45541
  unregister(e) {
45465
45542
  let t = this._helpers.get(e);
@@ -45497,16 +45574,16 @@ var lA = 4096, uA = class {
45497
45574
  }
45498
45575
  _renderSceneLayer(e) {
45499
45576
  this._helperScene?.render(e, this.camera);
45500
- for (let t of this._helpers.values()) fA(t, "scene") && t.render(e, this.camera);
45577
+ for (let t of this._helpers.values()) pA(t, "scene") && t.render(e, this.camera);
45501
45578
  }
45502
45579
  _hasVisibleSceneOverlay() {
45503
45580
  if (this._helperScene?.isDrawing) return !0;
45504
- for (let e of this._helpers.values()) if (fA(e, "scene")) return !0;
45581
+ for (let e of this._helpers.values()) if (pA(e, "scene")) return !0;
45505
45582
  return !1;
45506
45583
  }
45507
45584
  refreshHUD() {
45508
45585
  let e = this._hudCanvas, t = this._hudCtx, n = !1;
45509
- for (let e of this._helpers.values()) if (fA(e, "hud")) {
45586
+ for (let e of this._helpers.values()) if (pA(e, "hud")) {
45510
45587
  n = !0;
45511
45588
  break;
45512
45589
  }
@@ -45515,10 +45592,10 @@ var lA = 4096, uA = class {
45515
45592
  return;
45516
45593
  }
45517
45594
  e.style.display !== "" && (e.style.display = "");
45518
- let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? cA(e) : null;
45595
+ let r = e.clientWidth, i = e.clientHeight, a = r > 0 && i > 0 ? lA(e) : null;
45519
45596
  if (a) {
45520
45597
  (e.width !== a.width || e.height !== a.height) && (e.width = a.width, e.height = a.height), t.clearRect(0, 0, a.width, a.height), t.save(), t.scale(a.width / r, a.height / i);
45521
- for (let e of this._helpers.values()) fA(e, "hud") && e.render(t, r, i);
45598
+ for (let e of this._helpers.values()) pA(e, "hud") && e.render(t, r, i);
45522
45599
  t.restore(), e.style.display !== "" && (e.style.display = "");
45523
45600
  }
45524
45601
  }
@@ -45526,7 +45603,19 @@ var lA = 4096, uA = class {
45526
45603
  for (let e of this._helpers.values()) e.dispose?.();
45527
45604
  this._helpers.clear(), this._viewOverlay?.dispose(), this._viewOverlay = null, this._hudCanvas.parentElement && this._hudCanvas.parentElement.removeChild(this._hudCanvas);
45528
45605
  }
45529
- }, mA = class extends en {
45606
+ };
45607
+ //#endregion
45608
+ //#region src/managers/AnimationManager.js
45609
+ function hA(e, t) {
45610
+ let n = [...e].filter((t) => {
45611
+ for (let n = t.parent; n; n = n.parent) if (e.has(n)) return !1;
45612
+ return !0;
45613
+ }), r = 0, i = 0;
45614
+ t.traverse?.(() => r++);
45615
+ for (let e of n) e.traverse?.(() => i++);
45616
+ return i + n.length / 2 < r ? n : null;
45617
+ }
45618
+ var gA = class extends en {
45530
45619
  constructor() {
45531
45620
  super(), this.mixer = null, this.timer = new ir(), this.actions = [], this.isPlaying = !1, this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._meshPositions = null, this._tempVec = new ur(), this._skinnedCache = null, this._clipsCache = null, this._savedTimeScale = 1, this.onFinished = null, this._rigid = !1, this._plans = null, this._allPlan = null, this._activeClip = 0, this._slotOf = null, this._lastWorld = null, this._lastVisible = null, this._lastMeshWorld = null, this._lastMorphWeights = null, this.wakeCallback = null, this.applyPoseCallback = null;
45532
45621
  }
@@ -45559,22 +45648,28 @@ var lA = 4096, uA = class {
45559
45648
  if (t.traverse?.((e) => {
45560
45649
  n.has(e.name) || n.set(e.name, e), n.set(e.uuid, e);
45561
45650
  }), this._plans = e.map((e) => {
45562
- let t = /* @__PURE__ */ new Set(), r = !1;
45563
- for (let i of e.tracks) {
45564
- let { nodeName: e, propertyName: a } = Ln.parseTrackName(i.name), o = n.get(e);
45565
- o && (t.add(o), a === "visible" && (r = !0));
45566
- }
45567
- let i = [];
45568
- for (let e = 0; e < this._meshes.length; e++) for (let n = this._meshes[e]; n; n = n.parent) if (t.has(n)) {
45569
- i.push(e);
45651
+ let r = /* @__PURE__ */ new Set(), i = !1, a = !1;
45652
+ for (let o of e.tracks) {
45653
+ let { nodeName: e, propertyName: s } = Ln.parseTrackName(o.name), c = e === "" || e === "." ? t : n.get(e);
45654
+ if (!c) {
45655
+ a = !0;
45656
+ continue;
45657
+ }
45658
+ r.add(c), s === "visible" && (i = !0);
45659
+ }
45660
+ let o = [];
45661
+ for (let e = 0; e < this._meshes.length; e++) for (let t = this._meshes[e]; t; t = t.parent) if (r.has(t)) {
45662
+ o.push(e);
45570
45663
  break;
45571
45664
  }
45572
- let a = /* @__PURE__ */ new Set();
45573
- for (let e of t) e.traverse((e) => e.isCamera && a.add(e));
45665
+ let s = /* @__PURE__ */ new Set();
45666
+ for (let e of r) e.traverse((e) => e.isCamera && s.add(e));
45574
45667
  return {
45575
- meshes: Int32Array.from(i),
45576
- visibility: r,
45577
- cameras: [...a]
45668
+ meshes: Int32Array.from(o),
45669
+ visibility: i,
45670
+ cameras: [...s],
45671
+ nodes: a ? null : r,
45672
+ roots: a ? null : hA(r, t)
45578
45673
  };
45579
45674
  }), this._allPlan = null, !this._rigid) return;
45580
45675
  this._slotOf = new Int32Array(this._meshes.length).fill(-1);
@@ -45586,12 +45681,14 @@ var lA = 4096, uA = class {
45586
45681
  if (!this._plans) return null;
45587
45682
  if (e >= 0) return this._plans[e] ?? null;
45588
45683
  if (!this._allPlan) {
45589
- let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = !1;
45590
- for (let r of this._plans) r.meshes.forEach((t) => e.add(t)), r.cameras.forEach((e) => t.add(e)), n ||= r.visibility;
45684
+ let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = !1, r = /* @__PURE__ */ new Set();
45685
+ for (let i of this._plans) i.meshes.forEach((t) => e.add(t)), i.cameras.forEach((e) => t.add(e)), n ||= i.visibility, r && i.nodes ? i.nodes.forEach((e) => r.add(e)) : r = null;
45591
45686
  this._allPlan = {
45592
45687
  meshes: Int32Array.from(e),
45593
45688
  visibility: n,
45594
- cameras: [...t]
45689
+ cameras: [...t],
45690
+ nodes: r,
45691
+ roots: r ? hA(r, this._mixerRoot) : null
45595
45692
  };
45596
45693
  }
45597
45694
  return this._allPlan;
@@ -45667,15 +45764,18 @@ var lA = 4096, uA = class {
45667
45764
  return r && r.length === n ? r : e[t] = new Float32Array(n);
45668
45765
  }
45669
45766
  _poseReader() {
45670
- if (this._mixerRoot.updateMatrixWorld(!0), this._rigid) return this._applyRigidPose(this._activeClip), null;
45671
- let e = this._planFor(this._activeClip)?.cameras;
45672
- e?.length && this.applyPoseCallback?.({
45767
+ let e = this._rigid ? this._planFor(this._activeClip)?.roots : null;
45768
+ if (e) for (let t of e) t.updateMatrixWorld(!0);
45769
+ else this._mixerRoot.updateMatrixWorld(!0);
45770
+ if (this._rigid) return this._applyRigidPose(this._activeClip), null;
45771
+ let t = this._planFor(this._activeClip)?.cameras;
45772
+ t?.length && this.applyPoseCallback?.({
45673
45773
  meshIndices: [],
45674
45774
  visibilityChanged: !1,
45675
- cameras: e
45775
+ cameras: t
45676
45776
  });
45677
- let t = new Int8Array(this._meshes.length);
45678
- return (e) => (t[e] === 0 && (t[e] = this._meshes[e].isSkinnedMesh || this._poseChanged(e) ? 1 : -1), t[e] > 0 ? this._computeMeshPositions(e) : null);
45777
+ let n = new Int8Array(this._meshes.length);
45778
+ return (e) => (n[e] === 0 && (n[e] = this._meshes[e].isSkinnedMesh || this._poseChanged(e) ? 1 : -1), n[e] > 0 ? this._computeMeshPositions(e) : null);
45679
45779
  }
45680
45780
  _poseChanged(e) {
45681
45781
  let t = this._meshes[e], n = this._lastMeshWorld, r = t.matrixWorld.elements, i = e * 16, a = !1;
@@ -45720,19 +45820,19 @@ var lA = 4096, uA = class {
45720
45820
  dispose() {
45721
45821
  this.mixer &&= (this.mixer.stopAllAction(), this.mixer.uncacheRoot(this._mixerRoot), null), this.actions = [], this.isPlaying = !1, this.timer.reset(), this._scene = null, this._mixerRoot = null, this._meshes = null, this._meshTriRanges = null, this._meshPositions = null, this._skinnedCache = null, this._clipsCache = null, this._rigid = !1, this._plans = null, this._allPlan = null, this._activeClip = 0, this._slotOf = null, this._lastWorld = null, this._lastVisible = null, this._lastMeshWorld = null, this._lastMorphWeights = null;
45722
45822
  }
45723
- }, hA = new ur(0, 0, -1), gA = (e) => {
45823
+ }, _A = new ur(0, 0, -1), vA = (e) => {
45724
45824
  for (; e.parent;) e = e.parent;
45725
45825
  return e.isScene ? e : null;
45726
- }, _A = class {
45826
+ }, yA = class {
45727
45827
  constructor({ camera: e, canvas: t, orbitControls: n, app: r }) {
45728
45828
  this._app = r, this._orbitControls = n, this._camera = e, this._controls = new kr(e, t), this._gizmoScene = new Zn(), this._gizmoScene.add(this._controls.getHelper()), this._attached = null, this._isDragging = !1, this._meshes = null, this._refitInFlight = !1, this._baselineComputed = !1, this._moved = /* @__PURE__ */ new Set(), this._tempForward = new ur(), this._lightTargetDistance = null, this._lastLightPosition = null, this._onDraggingChanged = this._onDraggingChanged.bind(this), this._onObjectChange = this._onObjectChange.bind(this), this._controls.addEventListener("dragging-changed", this._onDraggingChanged), this._controls.addEventListener("objectChange", this._onObjectChange);
45729
45829
  }
45730
45830
  setMeshData(e) {
45731
45831
  this._meshes = e;
45732
- for (let e of this._moved) gA(e) || this._moved.delete(e);
45832
+ for (let e of this._moved) vA(e) || this._moved.delete(e);
45733
45833
  }
45734
45834
  get movedObjects() {
45735
- return [...this._moved].filter((e) => gA(e));
45835
+ return [...this._moved].filter((e) => vA(e));
45736
45836
  }
45737
45837
  noteMoved(e) {
45738
45838
  e && !e.isLight && this._moved.add(e);
@@ -45793,7 +45893,7 @@ var lA = 4096, uA = class {
45793
45893
  }
45794
45894
  _syncLightAim(e) {
45795
45895
  let t = this._tempForward.copy(e.target.position).sub(e.position), n = t.length();
45796
- n > 1e-4 ? (e.quaternion.setFromUnitVectors(hA, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1;
45896
+ n > 1e-4 ? (e.quaternion.setFromUnitVectors(_A, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1;
45797
45897
  }
45798
45898
  _recomputeAndRefit() {
45799
45899
  if (!this._meshes || this._refitInFlight || !this._attached) return;
@@ -45829,7 +45929,7 @@ var lA = 4096, uA = class {
45829
45929
  dispose() {
45830
45930
  this._controls.removeEventListener("dragging-changed", this._onDraggingChanged), this._controls.removeEventListener("objectChange", this._onObjectChange), this.detach(), this._gizmoScene.remove(this._controls.getHelper()), this._controls.dispose(), this._meshes = null, this._moved.clear(), this._baselineComputed = !1, this._tempForward = null, this._lightTargetDistance = null, this._lastLightPosition = null, this._app = null, this._orbitControls = null, this._camera = null, this._controls = null, this._gizmoScene = null;
45831
45931
  }
45832
- }, vA = class {
45932
+ }, bA = class {
45833
45933
  constructor(e) {
45834
45934
  this.layer = "scene", this._transformManager = e, this._enabled = !0;
45835
45935
  }
@@ -45848,8 +45948,8 @@ var lA = 4096, uA = class {
45848
45948
  dispose() {
45849
45949
  this._enabled = !1;
45850
45950
  }
45851
- }, yA = 1, bA = (e) => typeof e == "string" && /^https?:\/\//.test(e);
45852
- function xA(e, t) {
45951
+ }, xA = 1, SA = (e) => typeof e == "string" && /^https?:\/\//.test(e);
45952
+ function CA(e, t) {
45853
45953
  let n = [];
45854
45954
  for (; e && e !== t;) {
45855
45955
  let t = e.parent;
@@ -45858,12 +45958,12 @@ function xA(e, t) {
45858
45958
  }
45859
45959
  return e === t ? n : null;
45860
45960
  }
45861
- function SA(e, t) {
45961
+ function wA(e, t) {
45862
45962
  let n = e;
45863
45963
  for (let e of t) if (n = n?.children[e], !n) return null;
45864
45964
  return n;
45865
45965
  }
45866
- function CA(e) {
45966
+ function TA(e) {
45867
45967
  return {
45868
45968
  key: e.assetLoader?.sceneSourceKey ?? null,
45869
45969
  name: e.sceneModel?.name ?? null,
@@ -45871,7 +45971,7 @@ function CA(e) {
45871
45971
  materials: e.stages.pathTracer?.materialData.materialCount ?? 0
45872
45972
  };
45873
45973
  }
45874
- function wA(e) {
45974
+ function EA(e) {
45875
45975
  let t = /* @__PURE__ */ new Map();
45876
45976
  for (let n of e.sceneMeshes) {
45877
45977
  let e = n.userData?.materialIndex;
@@ -45879,7 +45979,7 @@ function wA(e) {
45879
45979
  }
45880
45980
  return t;
45881
45981
  }
45882
- function TA(e) {
45982
+ function DA(e) {
45883
45983
  if (!e) return null;
45884
45984
  let t = e.status(), n = t.activeView, r = t.config?.id ?? n?.configId ?? null;
45885
45985
  return {
@@ -45894,15 +45994,15 @@ function TA(e) {
45894
45994
  context: t.context ?? null
45895
45995
  };
45896
45996
  }
45897
- function EA(e) {
45898
- let t = e.meshScene, n = wA(e), r = [];
45997
+ function OA(e) {
45998
+ let t = e.meshScene, n = EA(e), r = [];
45899
45999
  return t.traverse((e) => {
45900
- e !== t && e.visible === !1 && r.push(xA(e, t));
46000
+ e !== t && e.visible === !1 && r.push(CA(e, t));
45901
46001
  }), {
45902
46002
  v: 1,
45903
46003
  engine: Hv,
45904
46004
  savedAt: Date.now(),
45905
- scene: CA(e),
46005
+ scene: TA(e),
45906
46006
  appended: t.children.filter((t) => t !== e.sceneModel && t.userData?.__rayzeeSceneObject).map((e) => ({
45907
46007
  name: e.userData.__rayzeeName ?? e.name,
45908
46008
  url: e.userData.__rayzeeSourceUrl ?? null,
@@ -45910,7 +46010,7 @@ function EA(e) {
45910
46010
  })),
45911
46011
  settings: e.settings.serialize(),
45912
46012
  environment: e.environmentManager?.serialize() ?? null,
45913
- color: TA(e.color),
46013
+ color: DA(e.color),
45914
46014
  lights: e.lightManager.serialize(),
45915
46015
  cameras: e.cameraManager.serialize(),
45916
46016
  timeline: e.timeline?.serialize() ?? null,
@@ -45920,7 +46020,7 @@ function EA(e) {
45920
46020
  })),
45921
46021
  hidden: r,
45922
46022
  moved: (e.transformManager?.movedObjects ?? []).map((e) => ({
45923
- path: xA(e, t),
46023
+ path: CA(e, t),
45924
46024
  name: e.name,
45925
46025
  position: e.position.toArray(),
45926
46026
  quaternion: e.quaternion.toArray(),
@@ -45928,15 +46028,15 @@ function EA(e) {
45928
46028
  })).filter((e) => e.path)
45929
46029
  };
45930
46030
  }
45931
- function DA(e, t, n) {
46031
+ function kA(e, t, n) {
45932
46032
  let r = e[t];
45933
46033
  r?.copy && (n?.isColor || n?.isVector2 || n?.isVector3) ? r.copy(n) : e[t] = n, e.needsUpdate = !0;
45934
46034
  }
45935
- async function OA(e, t, n, r) {
46035
+ async function AA(e, t, n, r) {
45936
46036
  if (!t) return;
45937
46037
  let i = e.environmentManager;
45938
46038
  if (t.hdri && t.hdri !== i.hdriSource) {
45939
- let i = bA(t.hdri) ? t.hdri : await n({
46039
+ let i = SA(t.hdri) ? t.hdri : await n({
45940
46040
  kind: "environment",
45941
46041
  source: t.hdri
45942
46042
  });
@@ -45948,7 +46048,7 @@ async function OA(e, t, n, r) {
45948
46048
  }
45949
46049
  await i.restore(t);
45950
46050
  }
45951
- async function kA(e, t, n, r) {
46051
+ async function jA(e, t, n, r) {
45952
46052
  let i = e.color;
45953
46053
  if (!t || !i) return;
45954
46054
  let a = i.status(), o = a.activeView, s = !!t.view && !!o && o.display === t.view.display && o.view === t.view.view && (o.look ?? null) === t.view.look, c = a.config?.id ?? null, l = c ?? o?.configId ?? null;
@@ -45973,7 +46073,7 @@ async function kA(e, t, n, r) {
45973
46073
  r("color", e.message, { config: t.config?.id ?? null });
45974
46074
  }
45975
46075
  }
45976
- async function AA(e, t, { resolve: n = async () => null } = {}) {
46076
+ async function MA(e, t, { resolve: n = async () => null } = {}) {
45977
46077
  if (t?.v !== 1) throw Error(`scene state version ${t?.v} is not 1`);
45978
46078
  let r = [], i = (e, t, n = {}) => r.push({
45979
46079
  section: e,
@@ -45994,11 +46094,11 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
45994
46094
  i("appended", e.message, { name: n.name });
45995
46095
  }
45996
46096
  }
45997
- let a = CA(e), o = t.scene ?? {}, s = o.meshes === a.meshes && o.materials === a.materials;
46097
+ let a = TA(e), o = t.scene ?? {}, s = o.meshes === a.meshes && o.materials === a.materials;
45998
46098
  s || i("scene", "the loaded scene is not the one saved: objects and materials left as loaded", {
45999
46099
  saved: o,
46000
46100
  now: a
46001
- }), await OA(e, t.environment, n, i), await kA(e, t.color, n, i);
46101
+ }), await AA(e, t.environment, n, i), await jA(e, t.color, n, i);
46002
46102
  let c = e.settings.restore(t.settings);
46003
46103
  c.length && i("settings", "not settings in this engine", { keys: c });
46004
46104
  let l = e.lightManager.restore(t.lights);
@@ -46007,7 +46107,7 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
46007
46107
  n && e.goboManager?.entries?.length && e.goboManager.setLightGobo(t.uuid, n.name, n), r && e.iesManager?.entries?.length && e.iesManager.setSpotLightProfile(t.uuid, r.name, r.intensity, { applyAutoCone: !1 });
46008
46108
  }
46009
46109
  if (s) {
46010
- let n = wA(e);
46110
+ let n = EA(e);
46011
46111
  for (let r of t.materials ?? []) {
46012
46112
  let t = n.get(r.index);
46013
46113
  if (!t || (t.name ?? "") !== r.name) {
@@ -46019,16 +46119,16 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
46019
46119
  }
46020
46120
  for (let [n, i] of Object.entries(r.props)) {
46021
46121
  let a = ys(i);
46022
- DA(t, n, a), e.setMaterialProperty(r.index, n, a);
46122
+ kA(t, n, a), e.setMaterialProperty(r.index, n, a);
46023
46123
  }
46024
46124
  }
46025
- let r = e.meshScene, a = new Set((t.hidden ?? []).map((e) => SA(r, e)).filter(Boolean));
46125
+ let r = e.meshScene, a = new Set((t.hidden ?? []).map((e) => wA(r, e)).filter(Boolean));
46026
46126
  r.traverse((e) => {
46027
46127
  e !== r && !e.isLight && (e.visible = !a.has(e));
46028
46128
  }), e.updateAllMeshVisibility();
46029
46129
  let o = [];
46030
46130
  for (let n of t.moved ?? []) {
46031
- let t = SA(r, n.path);
46131
+ let t = wA(r, n.path);
46032
46132
  if (!t || t.name !== n.name) {
46033
46133
  i("moved", "no such object", { name: n.name });
46034
46134
  continue;
@@ -46048,11 +46148,11 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
46048
46148
  let { mismatched: u } = e.cameraManager.restore(t.cameras);
46049
46149
  return u.length && i("cameras", "model cameras changed", { names: u }), e._dispatchCamerasUpdated(), e.timeline?.restore(t.timeline), e.reset(), { skipped: r };
46050
46150
  }
46051
- var jA = ({ element: e, pbrtEntry: t } = {}) => ({
46151
+ var NA = ({ element: e, pbrtEntry: t } = {}) => ({
46052
46152
  ...e === void 0 ? {} : { element: e },
46053
46153
  ...t === void 0 ? {} : { pbrtEntry: t }
46054
- }), MA = /* @__PURE__ */ new WeakMap(), NA = new Set([...Object.values(e), ...Object.values(r)]), PA = /* @__PURE__ */ new Set();
46055
- async function FA(e, t) {
46154
+ }), PA = /* @__PURE__ */ new WeakMap(), FA = new Set([...Object.values(e), ...Object.values(r)]), IA = /* @__PURE__ */ new Set();
46155
+ async function LA(e, t) {
46056
46156
  if (!t || typeof self < "u") return e.init();
46057
46157
  globalThis.self = {
46058
46158
  requestAnimationFrame: () => 0,
@@ -46064,32 +46164,32 @@ async function FA(e, t) {
46064
46164
  delete globalThis.self;
46065
46165
  }
46066
46166
  }
46067
- var IA = a("engine");
46068
- function LA(e, t) {
46167
+ var RA = a("engine");
46168
+ function zA(e, t) {
46069
46169
  e.lost.then((e) => {
46070
46170
  t.app && t.app._handleDeviceLost(e);
46071
46171
  });
46072
46172
  }
46073
- var RA = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
46074
- function zA(e) {
46173
+ var BA = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
46174
+ function VA(e) {
46075
46175
  let t = e.info ?? {}, n = `${t.vendor ?? ""} ${t.architecture ?? ""} ${t.device ?? ""} ${t.description ?? ""}`;
46076
46176
  return {
46077
46177
  vendor: t.vendor ?? "",
46078
46178
  architecture: t.architecture ?? "",
46079
46179
  device: t.device ?? "",
46080
46180
  description: t.description ?? "",
46081
- isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || RA.test(n)
46181
+ isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || BA.test(n)
46082
46182
  };
46083
46183
  }
46084
- var BA = class extends en {
46184
+ var HA = class extends en {
46085
46185
  constructor(t, n = {}) {
46086
46186
  super(), this._headless = n.headless === !0 || !t, t ??= vO();
46087
46187
  try {
46088
- MA.get(t)?.dispose();
46188
+ PA.get(t)?.dispose();
46089
46189
  } catch (e) {
46090
- IA.warn("prior canvas owner dispose failed", e);
46190
+ RA.warn("prior canvas owner dispose failed", e);
46091
46191
  }
46092
- MA.set(t, this), this.canvas = t, this._autoResize = !this._headless && n.autoResize !== !1, this._maxSceneBytes = n.maxSceneBytes, this._hostMemoryGB = n.hostMemoryGB, this._storageOption = n.storage, this._memorySpill = n.memorySpill === !0, this.storage = null, this._storageRelease = null, this._container = n.container || null, this._applySceneMetadataEnabled = n.applySceneMetadata !== !1, this._applyingSceneMetadata = !1, this._profile = mi(n.profile), this._profileName = n.profile ?? "viewer", this._issues = new Ka({
46192
+ PA.set(t, this), this.canvas = t, this._autoResize = !this._headless && n.autoResize !== !1, this._maxSceneBytes = n.maxSceneBytes, this._hostMemoryGB = n.hostMemoryGB, this._storageOption = n.storage, this._memorySpill = n.memorySpill === !0, this.storage = null, this._storageRelease = null, this._container = n.container || null, this._applySceneMetadataEnabled = n.applySceneMetadata !== !1, this._applyingSceneMetadata = !1, this._profile = mi(n.profile), this._profileName = n.profile ?? "viewer", this._issues = new Ka({
46093
46193
  strict: n.strict === !0,
46094
46194
  onIssue: (t) => this.dispatchEvent({
46095
46195
  type: e.ISSUE,
@@ -46100,7 +46200,7 @@ var BA = class extends en {
46100
46200
  environmentRotation: this._profile.environmentRotation,
46101
46201
  saturation: this._profile.saturation,
46102
46202
  dofMode: this._profile.dofMode
46103
- }, { issues: this._issues }), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._emittersMoved = !1, this._maxTextureSize = Q.maxTextureSize, this.pipeline = null, this._pendingReservedRenderSize = null, this.stages = {}, this.cameraManager = null, this.timeline = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new mA(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this._pathTracerEnabled = !0, this._rasterPrecompile = null, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new wC(), this._resizeDebounceTimer = null, this._displayWidth = 0, this._displayHeight = 0, this._renderScale = 1, this._pendingRenderScale = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._gpuDevice = null, this._deviceLostHolder = null, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null, this.adapterInfo = null;
46203
+ }, { issues: this._issues }), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._animRefitInFlight = !1, this._emittersMoved = !1, this._maxTextureSize = Q.maxTextureSize, this.pipeline = null, this._pendingReservedRenderSize = null, this.stages = {}, this.cameraManager = null, this.timeline = null, this.lightManager = null, this.goboManager = null, this.iesManager = null, this.denoisingManager = null, this.overlayManager = null, this.interactionManager = null, this.transformManager = null, this.animationManager = new gA(), this.environmentManager = null, this.isInitialized = !1, this.pauseRendering = !1, this._pathTracerEnabled = !0, this._rasterPrecompile = null, this.animationManagerId = null, this.needsReset = !1, this._loadingInProgress = !1, this._needsDisplayRefresh = !1, this._paused = !1, this._emissiveSamplingUserSet = !1, this.completion = new wC(), this._resizeDebounceTimer = null, this._displayWidth = 0, this._displayHeight = 0, this._renderScale = 1, this._pendingRenderScale = null, this._trackedListeners = [], this._disposed = !1, this._deviceLost = !1, this._gpuDevice = null, this._deviceLostHolder = null, this._deterministic = !1, this._dispatchPinned = !1, this._deterministicRestore = null, this.adapterInfo = null;
46104
46204
  }
46105
46205
  _addTrackedListener(e, t, n) {
46106
46206
  e && (e.addEventListener(t, n), this._trackedListeners.push({
@@ -46113,13 +46213,13 @@ var BA = class extends en {
46113
46213
  for (let { target: e, type: t, handler: n } of this._trackedListeners) try {
46114
46214
  e.removeEventListener(t, n);
46115
46215
  } catch (e) {
46116
- IA.warn("failed to remove listener", t, e);
46216
+ RA.warn("failed to remove listener", t, e);
46117
46217
  }
46118
46218
  this._trackedListeners.length = 0;
46119
46219
  }
46120
46220
  async init() {
46121
46221
  let e = this._initStorage();
46122
- return await this._initRenderer(), this._applyPendingReservedRenderSize(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), await e, this._attachStorage(), this.stages.pathTracer.setTriangleData(new Uint32Array(Mi.FLOATS_PER_TRIANGLE), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, IA.debug("WebGPU path tracer app initialized"), this;
46222
+ return await this._initRenderer(), this._applyPendingReservedRenderSize(), this._initCameraManager(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), await e, this._attachStorage(), this.stages.pathTracer.setTriangleData(new Uint32Array(Mi.FLOATS_PER_TRIANGLE), 0), this.stages.pathTracer.setBVHData(new Float32Array(16)), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, RA.debug("WebGPU path tracer app initialized"), this;
46123
46223
  }
46124
46224
  async _initStorage() {
46125
46225
  let t = this._storageOption ?? (this._issues.strict && !d("storage") ? !1 : A().storage);
@@ -46155,7 +46255,7 @@ var BA = class extends en {
46155
46255
  });
46156
46256
  }
46157
46257
  addEventListener(e, t) {
46158
- !NA.has(e) && !PA.has(e) && (PA.add(e), IA.warn(`no engine event is named "${e}", so this listener will never fire — see EngineEvents`)), super.addEventListener(e, t);
46258
+ !FA.has(e) && !IA.has(e) && (IA.add(e), RA.warn(`no engine event is named "${e}", so this listener will never fire — see EngineEvents`)), super.addEventListener(e, t);
46159
46259
  }
46160
46260
  animate() {
46161
46261
  if (this._headless) throw Error("a headless app has no render loop — drive it with renderFrames() or renderUntilComplete()");
@@ -46166,7 +46266,7 @@ var BA = class extends en {
46166
46266
  }
46167
46267
  if (this.timeline.update(), this.cameraManager.updateControls(), this._applyPendingRenderScale(), this.animationManager?.isPlaying && !this._animRefitInFlight) {
46168
46268
  let e = this.animationManager.update();
46169
- e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => IA.error("animation refit error:", e)).finally(() => {
46269
+ e && (this._animRefitInFlight = !0, this.refitBVH(e).catch((e) => RA.error("animation refit error:", e)).finally(() => {
46170
46270
  this._animRefitInFlight = !1;
46171
46271
  }));
46172
46272
  }
@@ -46223,7 +46323,7 @@ var BA = class extends en {
46223
46323
  this.animationManagerId &&= (cancelAnimationFrame(this.animationManagerId), null);
46224
46324
  }
46225
46325
  _handleDeviceLost(t) {
46226
- this._deviceLost || (this._deviceLost = !0, IA.error(`WebGPU device lost (${t?.reason || "unknown"}): ${t?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
46326
+ this._deviceLost || (this._deviceLost = !0, RA.error(`WebGPU device lost (${t?.reason || "unknown"}): ${t?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
46227
46327
  type: e.DEVICE_LOST,
46228
46328
  reason: t?.reason,
46229
46329
  message: t?.message
@@ -46253,9 +46353,9 @@ var BA = class extends en {
46253
46353
  let e = ht().value, t = Ne().value;
46254
46354
  e?._listeners?.dispose && (e._listeners.dispose.length = 0), t?._listeners?.dispose && (t._listeners.dispose.length = 0);
46255
46355
  } catch (e) {
46256
- IA.warn("failed to clear TSL texture singleton listeners", e);
46356
+ RA.warn("failed to clear TSL texture singleton listeners", e);
46257
46357
  }
46258
- this.canvas && MA.get(this.canvas) === this && MA.delete(this.canvas), this._gpuDevice &&= (this._gpuDevice.onuncapturederror = null, null), this._deviceLostHolder &&= (this._deviceLostHolder.app = null, null), ei(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
46358
+ this.canvas && PA.get(this.canvas) === this && PA.delete(this.canvas), this._gpuDevice &&= (this._gpuDevice.onuncapturederror = null, null), this._deviceLostHolder &&= (this._deviceLostHolder.app = null, null), ei(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
46259
46359
  }
46260
46360
  }
46261
46361
  unloadScene() {
@@ -46320,7 +46420,7 @@ var BA = class extends en {
46320
46420
  url: t,
46321
46421
  filename: r,
46322
46422
  cacheKey: n.cacheKey ?? null,
46323
- ...jA(n)
46423
+ ...NA(n)
46324
46424
  });
46325
46425
  return;
46326
46426
  }
@@ -46342,7 +46442,7 @@ var BA = class extends en {
46342
46442
  kind: "local-file",
46343
46443
  file: e,
46344
46444
  key: e.sample ? _o(e) : null,
46345
- ...jA(n)
46445
+ ...NA(n)
46346
46446
  };
46347
46447
  }), this._sceneSourceFile = t;
46348
46448
  return;
@@ -46558,10 +46658,10 @@ var BA = class extends en {
46558
46658
  return t && this._dispatchCamerasUpdated(), t;
46559
46659
  }
46560
46660
  exportSceneState() {
46561
- return EA(this);
46661
+ return OA(this);
46562
46662
  }
46563
46663
  async importSceneState(e, t) {
46564
- return await AA(this, e, t);
46664
+ return await MA(this, e, t);
46565
46665
  }
46566
46666
  _sceneBudgets(e) {
46567
46667
  return !this._memorySpill || !this.storage ? e : {
@@ -46606,8 +46706,8 @@ var BA = class extends en {
46606
46706
  }
46607
46707
  async refitBVH(e, t) {
46608
46708
  await this.ensureSceneResident();
46609
- let { triRanges: n, ...r } = await this._sdf.refitBVH(e, t);
46610
- return this.stages.pathTracer.updateTriangleData(this._sdf.triangles, n), this.stages.pathTracer.updateBVHData(this._sdf.bvh), this.reset(!1, { motion: !0 }), r;
46709
+ let { triRanges: n, bvhRanges: r, ...i } = await this._sdf.refitBVH(e, t);
46710
+ return this.stages.pathTracer.updateTriangleData(this._sdf.triangles, n), this.stages.pathTracer.updateBVHData(this._sdf.bvh, r), this.reset(!1, { motion: !0 }), i;
46611
46711
  }
46612
46712
  refitBLASes(e, t, n) {
46613
46713
  if (this._sdf?.spilled) throw Error("refitBLASes: the scene is spilled to disk — await app.ensureSceneResident() first");
@@ -46662,7 +46762,7 @@ var BA = class extends en {
46662
46762
  requestedPx: t,
46663
46763
  allowLower: n
46664
46764
  }, Math.max(256, Math.min(bi, Math.floor(r) || 256));
46665
- let i = this.renderer.backend?.device?.limits?.maxStorageBufferBindingSize || 128 * 1024 * 1024, a = N_(this._hostMemoryGB), o = a.gb >= 8 && i >= 1024 * 1024 * 1024 ? bi : 2048, s = Si(Math.min(r, o));
46765
+ let i = this.renderer.backend?.device?.limits?.maxStorageBufferBindingSize || 128 * 1024 * 1024, a = P_(this._hostMemoryGB), o = a.gb >= 8 && i >= 1024 * 1024 * 1024 ? bi : 2048, s = Si(Math.min(r, o));
46666
46766
  if (s < Math.floor(t) && this._issues.warn(Ua.RENDER_RESERVE_CAPPED, `reserved render size ${O.n(t)}px was capped to ${O.n(s)}px by this device's limits — renders above ${O.n(s)}px will be declined` + (a.assumed && a.gb < 8 ? " (host memory unknown, 4 GB assumed: pass hostMemoryGB)" : ""), {
46667
46767
  requested: t,
46668
46768
  applied: s,
@@ -47023,7 +47123,7 @@ var BA = class extends en {
47023
47123
  let o = e ? this._readbackPass().draw(e, n, r).texture : t.textures[0], s = a.get(o).texture;
47024
47124
  return s ? (this._readbackToneMapper ??= new T(a.device, "rayzee:readback-tonemap", { input: "texture" }), this._readbackToneMapper.ensureSize(n, r), await this._readbackToneMapper.toRGBA8(s, i)) : null;
47025
47125
  } catch (e) {
47026
- return IA.warn(`renderToBuffer: tone mapping on the GPU failed, doing it on the CPU: ${e?.message ?? e}`), null;
47126
+ return RA.warn(`renderToBuffer: tone mapping on the GPU failed, doing it on the CPU: ${e?.message ?? e}`), null;
47027
47127
  } finally {
47028
47128
  this._readbackToneMapper?.release(), e && this._textureReadback?.release();
47029
47129
  }
@@ -47109,7 +47209,7 @@ var BA = class extends en {
47109
47209
  this._pathTracerEnabled = e, e || this.precompileRaster();
47110
47210
  }
47111
47211
  precompileRaster() {
47112
- return !this.renderer || !this.meshScene ? Promise.resolve() : (this._rasterPrecompile ??= this.renderer.compileAsync(this.meshScene, this.cameraManager.camera).catch((e) => IA.warn("raster fallback precompile failed", e)), this._rasterPrecompile);
47212
+ return !this.renderer || !this.meshScene ? Promise.resolve() : (this._rasterPrecompile ??= this.renderer.compileAsync(this.meshScene, this.cameraManager.camera).catch((e) => RA.warn("raster fallback precompile failed", e)), this._rasterPrecompile);
47113
47213
  }
47114
47214
  get isLoading() {
47115
47215
  return this._loadingInProgress;
@@ -47274,7 +47374,7 @@ var BA = class extends en {
47274
47374
  if (e && this.color?.hasConfig) try {
47275
47375
  t = this.color.convertTexturePixels(e);
47276
47376
  } catch (e) {
47277
- IA.warn(`environment colour conversion failed: ${e.message}`);
47377
+ RA.warn(`environment colour conversion failed: ${e.message}`);
47278
47378
  }
47279
47379
  this.stages.pathTracer?.sdfs && (await this.rebuildMaterials(), this._uploadEmissivePayload(this._sdf?.rebuildEmissiveColors?.() ?? null)), t && await this.environmentManager?.buildEnvironmentCDF?.(), e?._isPhysicalSky && await this.environmentManager.generateProceduralSkyTexture(), this.environmentManager?.refreshSun?.(), this.reset();
47280
47380
  }
@@ -47285,7 +47385,7 @@ var BA = class extends en {
47285
47385
  if (Kr((e) => this.dispatchEvent(e)), typeof navigator > "u" || !navigator.gpu) throw Error("WebGPU is not available — outside a browser, install one as navigator.gpu (for Node, the `webgpu` package)");
47286
47386
  let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
47287
47387
  if (!e) throw Error("Failed to get WebGPU adapter");
47288
- this.adapterInfo = zA(e), this.adapterInfo.isSoftware && (this._issues.warn(Ua.ADAPTER_SOFTWARE, `software GPU adapter "${this.adapterInfo.description || this.adapterInfo.vendor}" — renders are correct but orders of magnitude slower than hardware`, { ...this.adapterInfo }), IA.warn(`software GPU adapter — check app.adapterInfo.isSoftware. ${this.adapterInfo.description}`));
47388
+ this.adapterInfo = VA(e), this.adapterInfo.isSoftware && (this._issues.warn(Ua.ADAPTER_SOFTWARE, `software GPU adapter "${this.adapterInfo.description || this.adapterInfo.vendor}" — renders are correct but orders of magnitude slower than hardware`, { ...this.adapterInfo }), RA.warn(`software GPU adapter — check app.adapterInfo.isSoftware. ${this.adapterInfo.description}`));
47289
47389
  let t = e.limits, n = { maxColorAttachmentBytesPerSample: 128 };
47290
47390
  for (let e of [
47291
47391
  "maxBufferSize",
@@ -47308,9 +47408,9 @@ var BA = class extends en {
47308
47408
  alpha: !0,
47309
47409
  powerPreference: "high-performance",
47310
47410
  requiredLimits: n
47311
- }), await FA(this.renderer, this._headless), !this.renderer.backend?.isWebGPUBackend) throw Error("WebGPU backend unavailable — three.js fell back to WebGL2, which cannot run the path tracer's compute kernels. Check GPU process flags and driver support.");
47411
+ }), await LA(this.renderer, this._headless), !this.renderer.backend?.isWebGPUBackend) throw Error("WebGPU backend unavailable — three.js fell back to WebGL2, which cannot run the path tracer's compute kernels. Check GPU process flags and driver support.");
47312
47412
  let r = this.renderer.backend?.device;
47313
- r?.lost && (this._gpuDevice = r, this._deviceLostHolder = { app: this }, LA(r, this._deviceLostHolder), r.onuncapturederror = (e) => IA.error("WebGPU uncaptured error:", e.error)), le.setLTC(pr.init()), this.renderer.outputColorSpace = de, this.renderer.toneMapping = this._profile.toneMapping, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1), this.color.attachRenderer(this.renderer);
47413
+ r?.lost && (this._gpuDevice = r, this._deviceLostHolder = { app: this }, zA(r, this._deviceLostHolder), r.onuncapturederror = (e) => RA.error("WebGPU uncaptured error:", e.error)), le.setLTC(pr.init()), this.renderer.outputColorSpace = de, this.renderer.toneMapping = this._profile.toneMapping, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1), this.color.attachRenderer(this.renderer);
47314
47414
  }
47315
47415
  _initCameraManager() {
47316
47416
  this.cameraManager = new RO(this.canvas), this.timeline = new WO({
@@ -47360,12 +47460,12 @@ var BA = class extends en {
47360
47460
  }), this.iesManager = new ak(this.stages.pathTracer, {
47361
47461
  onReset: () => this.reset(),
47362
47462
  issues: this._issues
47363
- }), this._setupDenoisingManager(), this._headless || (await this._setupOverlayManager(), this.transformManager = new _A({
47463
+ }), this._setupDenoisingManager(), this._headless || (await this._setupOverlayManager(), this.transformManager = new yA({
47364
47464
  camera: this.cameraManager.camera,
47365
47465
  canvas: this.canvas,
47366
47466
  orbitControls: this.cameraManager.controls,
47367
47467
  app: this
47368
- }), this.overlayManager.register("transform", new vA(this.transformManager))), this.interactionManager.setDependencies({
47468
+ }), this.overlayManager.register("transform", new bA(this.transformManager))), this.interactionManager.setDependencies({
47369
47469
  overlayManager: this.overlayManager,
47370
47470
  transformManager: this.transformManager,
47371
47471
  appDispatch: (e) => this.dispatchEvent(e),
@@ -47447,7 +47547,7 @@ var BA = class extends en {
47447
47547
  });
47448
47548
  }
47449
47549
  _setupDenoisingManager() {
47450
- this.denoisingManager = new iA({
47550
+ this.denoisingManager = new aA({
47451
47551
  renderer: this.renderer,
47452
47552
  mainCanvas: this.canvas,
47453
47553
  stages: {
@@ -47489,7 +47589,7 @@ var BA = class extends en {
47489
47589
  this.scene.updateMatrixWorld(), this.overlayManager?.render();
47490
47590
  }
47491
47591
  async _setupOverlayManager() {
47492
- this.overlayManager = new pA(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
47592
+ this.overlayManager = new mA(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
47493
47593
  helperScene: this._sceneHelpers,
47494
47594
  meshScene: this.meshScene,
47495
47595
  pipeline: this.pipeline,
@@ -47523,15 +47623,15 @@ var BA = class extends en {
47523
47623
  };
47524
47624
  //#endregion
47525
47625
  //#region src/Headless.js
47526
- async function VA(e) {
47527
- let t = await UA(e);
47626
+ async function UA(e) {
47627
+ let t = await GA(e);
47528
47628
  try {
47529
- return await HA(t, e);
47629
+ return await WA(t, e);
47530
47630
  } finally {
47531
47631
  t.dispose();
47532
47632
  }
47533
47633
  }
47534
- async function HA(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire: r = !1, denoise: i = !1, onProgress: a = void 0 } = {}) {
47634
+ async function WA(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire: r = !1, denoise: i = !1, onProgress: a = void 0 } = {}) {
47535
47635
  let o = e.denoisingManager;
47536
47636
  i && o && !o.finalDenoise && (o.applyOIDNEnabled(!0), o._syncGBufferStages());
47537
47637
  let s = await e.renderFrames(t, {
@@ -47550,8 +47650,8 @@ async function HA(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire
47550
47650
  provenance: e.getProvenance()
47551
47651
  };
47552
47652
  }
47553
- async function UA({ canvas: e, model: t = null, width: n = 1920, height: r = 1080, strict: i = !0, profile: a = "physical", deterministic: o = !0, settings: s = null, storage: c = !1, hostMemoryGB: l = void 0 } = {}) {
47554
- let u = new BA(e ?? null, {
47653
+ async function GA({ canvas: e, model: t = null, width: n = 1920, height: r = 1080, strict: i = !0, profile: a = "physical", deterministic: o = !0, settings: s = null, storage: c = !1, hostMemoryGB: l = void 0 } = {}) {
47654
+ let u = new HA(e ?? null, {
47555
47655
  autoResize: !1,
47556
47656
  strict: i,
47557
47657
  profile: a,
@@ -47566,7 +47666,7 @@ async function UA({ canvas: e, model: t = null, width: n = 1920, height: r = 108
47566
47666
  }
47567
47667
  //#endregion
47568
47668
  //#region src/managers/VideoRenderManager.js
47569
- var WA = class {
47669
+ var KA = class {
47570
47670
  constructor(e) {
47571
47671
  this._app = e, this._cancelled = !1, this._rendering = !1;
47572
47672
  }
@@ -47670,4 +47770,4 @@ var WA = class {
47670
47770
  }
47671
47771
  };
47672
47772
  //#endregion
47673
- export { ji as AF_DEFAULTS, Ci as ASVGF_QUALITY_PRESETS, Ai as AUTO_FOCUS_MODES, mA as AnimationManager, Ui as BVH_LEAF_MARKERS, ki as CAMERA_PRESETS, Di as CAMERA_RANGES, RO as CameraManager, HO as CameraTrack, Tp as ColorManagement, Ff as DEFAULT_LUT_SIZE, Pf as DEFAULT_MAX_EV, Nf as DEFAULT_MIN_EV, di as DEFAULT_SUN_PATH, aa as DEFAULT_TEXTURE_MATRIX, _p as DEFAULT_WORKING_SPACE, VC as DOWNLOAD_POLICY, iA as DenoisingManager, YC as DownloadCache, Co as ENGINE_AREAS, Q as ENGINE_DEFAULTS, e as EngineEvents, Ga as EngineIssueError, JO as GoboManager, ak as IESManager, sa as INTERACTIVE_RENDER_CONFIG, Ua as ISSUE_CODES, Wa as ISSUE_SEVERITY, AC as InteractionManager, Ka as IssueLog, r as LEGACY_EVENT_NAMES, k as LOG_LEVELS, qO as LightManager, s as Logger, Ri as MATERIAL_DEFAULTS, $o as MATERIAL_VALUE_SOURCE, bi as MAX_RESERVABLE_RENDER_SIZE, M_ as MAX_SCENE_BYTES, C as MAX_TABLE_TRANSFORMS, la as MEMORY_CONSTANTS, R_ as MemoryLedger, wi as NRD_DEFAULTS, _i as NRD_HIT_DIST_A, vi as NRD_HIT_DIST_B, Ti as NRD_PRESET_KEYS, Ei as NRD_QUALITY_PRESETS, _ as OCIO_VIEW_BASE, pA as OverlayManager, oa as PRODUCTION_RENDER_CONFIG, BA as PathTracerApp, uC as PipelineContext, pi as RENDER_PROFILES, te as RETOUCH_DEFAULTS, j as RETOUCH_MAX_PIXELS, ee as RETOUCH_RANGES, SC as RenderPipeline, nw as RenderSettings, Ur as RenderStage, j_ as SAFE_SCENE_BYTES, yA as SCENE_STATE_VERSION, ew as SETTING_SOURCE, Oi as SKY_PRESETS, n as SR_MAX_INPUT, i as SR_SCALE, So as STORAGE_KIND, Hr as StageExecutionMode, zo as StorageManager, qi as TEXTURE_CONSTANTS, Mi as TRIANGLE_DATA_LAYOUT, WO as TimelineManager, _A as TransformManager, Hv as VERSION, u as VIEW_TRANSFORMS, Py as VRAMTracker, WA as VideoRenderManager, io as acquireLock, Kf as addAllOcioViews, Gf as addOcioView, x as addViewTransform, _f as applyMatrixRGBA8, wf as bakeLut, My as bufferBytes, Hf as buildOcioView, w as buildToneMapWGSL, QC as cachedObjectURL, xp as canvasColorSpaceFor, HA as captureHeadless, _C as clearBindingAuditFindings, sp as clearInputOverrides, D as configureAssets, Ns as configurePlatform, rf as convertColor, ff as convertEncodedRGBA8, af as convertPixelsF32, a as createLogger, ui as dayOfYearForMonth, rs as deriveAlphaMode, zA as describeAdapter, wd as displayCanvasFit, I_ as estimateSceneBytes, vf as extractMatrix, oO as extractSceneMetadata, XC as fetchFile, go as fileIdentity, wp as findNativeLinearSpace, O as fmt, ys as fromPortable, yp as getActiveColorManagement, A as getAssetConfig, gC as getBindingAuditFindings, Ps as getPlatform, v as getRegistryVersion, mi as getRenderProfile, E as getViewTransform, bf as hasColorSpace, ao as heldLockNames, _o as identityKey, Ep as isColorManaged, yf as isDataSpace, pp as isDataTexture, cf as linearToSrgb, up as listFileRules, cp as listInputOverrides, p as listViewTransforms, Af as makeCpuSampler, Mf as measureBakeError, GC as nameFromUrl, S as onRegistryChange, UA as openHeadless, RC as openStorage, Uw as openZip, aO as parseSceneMetadata, L_ as probeAddressSpace, Bw as readZipDirectory, h as removeViewTransform, VA as renderHeadless, t as renderUpscaled, fp as resolveInputSpace, vo as sameIdentity, bp as setActiveColorManagement, hC as setBindingAudit, op as setInputOverride, sf as srgbToLinear, ci as sunPosition, Ny as textureBytes, gp as textureInputSpace, li as timeForSunElevation, vs as toPortable };
47773
+ export { ji as AF_DEFAULTS, Ci as ASVGF_QUALITY_PRESETS, Ai as AUTO_FOCUS_MODES, gA as AnimationManager, Ui as BVH_LEAF_MARKERS, ki as CAMERA_PRESETS, Di as CAMERA_RANGES, RO as CameraManager, HO as CameraTrack, Tp as ColorManagement, Ff as DEFAULT_LUT_SIZE, Pf as DEFAULT_MAX_EV, Nf as DEFAULT_MIN_EV, di as DEFAULT_SUN_PATH, aa as DEFAULT_TEXTURE_MATRIX, _p as DEFAULT_WORKING_SPACE, VC as DOWNLOAD_POLICY, aA as DenoisingManager, YC as DownloadCache, Co as ENGINE_AREAS, Q as ENGINE_DEFAULTS, e as EngineEvents, Ga as EngineIssueError, JO as GoboManager, ak as IESManager, sa as INTERACTIVE_RENDER_CONFIG, Ua as ISSUE_CODES, Wa as ISSUE_SEVERITY, AC as InteractionManager, Ka as IssueLog, r as LEGACY_EVENT_NAMES, k as LOG_LEVELS, qO as LightManager, s as Logger, Ri as MATERIAL_DEFAULTS, $o as MATERIAL_VALUE_SOURCE, bi as MAX_RESERVABLE_RENDER_SIZE, N_ as MAX_SCENE_BYTES, C as MAX_TABLE_TRANSFORMS, la as MEMORY_CONSTANTS, z_ as MemoryLedger, wi as NRD_DEFAULTS, _i as NRD_HIT_DIST_A, vi as NRD_HIT_DIST_B, Ti as NRD_PRESET_KEYS, Ei as NRD_QUALITY_PRESETS, _ as OCIO_VIEW_BASE, mA as OverlayManager, oa as PRODUCTION_RENDER_CONFIG, HA as PathTracerApp, uC as PipelineContext, pi as RENDER_PROFILES, te as RETOUCH_DEFAULTS, j as RETOUCH_MAX_PIXELS, ee as RETOUCH_RANGES, SC as RenderPipeline, nw as RenderSettings, Ur as RenderStage, M_ as SAFE_SCENE_BYTES, xA as SCENE_STATE_VERSION, ew as SETTING_SOURCE, Oi as SKY_PRESETS, n as SR_MAX_INPUT, i as SR_SCALE, So as STORAGE_KIND, Hr as StageExecutionMode, zo as StorageManager, qi as TEXTURE_CONSTANTS, Mi as TRIANGLE_DATA_LAYOUT, WO as TimelineManager, yA as TransformManager, Hv as VERSION, u as VIEW_TRANSFORMS, Py as VRAMTracker, KA as VideoRenderManager, io as acquireLock, Kf as addAllOcioViews, Gf as addOcioView, x as addViewTransform, _f as applyMatrixRGBA8, wf as bakeLut, My as bufferBytes, Hf as buildOcioView, w as buildToneMapWGSL, QC as cachedObjectURL, xp as canvasColorSpaceFor, WA as captureHeadless, _C as clearBindingAuditFindings, sp as clearInputOverrides, D as configureAssets, Ns as configurePlatform, rf as convertColor, ff as convertEncodedRGBA8, af as convertPixelsF32, a as createLogger, ui as dayOfYearForMonth, rs as deriveAlphaMode, VA as describeAdapter, wd as displayCanvasFit, L_ as estimateSceneBytes, vf as extractMatrix, oO as extractSceneMetadata, XC as fetchFile, go as fileIdentity, wp as findNativeLinearSpace, O as fmt, ys as fromPortable, yp as getActiveColorManagement, A as getAssetConfig, gC as getBindingAuditFindings, Ps as getPlatform, v as getRegistryVersion, mi as getRenderProfile, E as getViewTransform, bf as hasColorSpace, ao as heldLockNames, _o as identityKey, Ep as isColorManaged, yf as isDataSpace, pp as isDataTexture, cf as linearToSrgb, up as listFileRules, cp as listInputOverrides, p as listViewTransforms, Af as makeCpuSampler, Mf as measureBakeError, GC as nameFromUrl, S as onRegistryChange, GA as openHeadless, RC as openStorage, Uw as openZip, aO as parseSceneMetadata, R_ as probeAddressSpace, Bw as readZipDirectory, h as removeViewTransform, UA as renderHeadless, t as renderUpscaled, fp as resolveInputSpace, vo as sameIdentity, bp as setActiveColorManagement, hC as setBindingAudit, op as setInputOverride, sf as srgbToLinear, ci as sunPosition, Ny as textureBytes, gp as textureInputSpace, li as timeForSunElevation, vs as toPortable };