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/{NeuralRetouch-CYgkQY8Z.js → NeuralRetouch-vkdXXyK2.js} +1 -1
- package/dist/{NeuralSuperRes-PkgDLQcD.js → NeuralSuperRes-FVqRJKQV.js} +1 -1
- package/dist/{ToneMapGPU-B6XIe3DU.js → ToneMapGPU-DKQM1pMd.js} +86 -78
- package/dist/rayzee.es.js +559 -459
- package/dist/rayzee.umd.js +67 -38
- package/package.json +1 -1
- package/src/Passes/AIUpscaler.js +58 -141
- package/src/Passes/OIDNDenoiser.js +92 -65
- package/src/PathTracerApp.js +2 -2
- package/src/Processor/BVHRefitter.js +64 -0
- package/src/Processor/SceneProcessor.js +27 -5
- package/src/Processor/ToneMapGPU.js +64 -15
- package/src/Processor/Workers/BVHRefitWorker.js +5 -2
- package/src/Stages/PathTracerStage.js +21 -4
- package/src/managers/AnimationManager.js +36 -5
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-
|
|
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-
|
|
3
|
-
import { i as ee, n as te, r as j } from "./NeuralRetouch-
|
|
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
|
|
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
|
|
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--)
|
|
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--)
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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(
|
|
26950
|
-
var
|
|
26951
|
-
function
|
|
26952
|
-
let i = e.byteLength / (
|
|
26953
|
-
return
|
|
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(
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
-
|
|
27033
|
+
r_.warn("parallel build setup failed:", e), c(e);
|
|
27016
27034
|
});
|
|
27017
27035
|
});
|
|
27018
27036
|
}
|
|
27019
|
-
async function
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
27136
|
+
function l_(e, t, n, r) {
|
|
27119
27137
|
return new Promise((i, a) => {
|
|
27120
27138
|
(async () => {
|
|
27121
|
-
let o = Ls(
|
|
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
|
-
|
|
27174
|
+
r_.warn("single worker fallback failed:", e), a(e);
|
|
27157
27175
|
});
|
|
27158
27176
|
});
|
|
27159
27177
|
}
|
|
27160
|
-
function
|
|
27161
|
-
return Is() && typeof SharedArrayBuffer < "u" && e >=
|
|
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
|
|
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
|
|
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
|
|
27187
|
-
let r =
|
|
27188
|
-
if (!Number.isFinite(r) || Math.abs(r) < 1e-20) return n.set(
|
|
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
|
|
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
|
|
27200
|
-
for (let t = 0; t < 16; t++) if (e[t] !==
|
|
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
|
|
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
|
|
27212
|
-
for (let n = 0; n < 16; n++) if (e[t + n] !==
|
|
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
|
|
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(
|
|
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] = +(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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 *
|
|
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(
|
|
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 *
|
|
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 *
|
|
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 *
|
|
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 =
|
|
27481
|
-
|
|
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 <=
|
|
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 =
|
|
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
|
-
},
|
|
27622
|
-
function
|
|
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
|
|
27637
|
-
function
|
|
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 *
|
|
27640
|
-
bvh: Math.ceil(e *
|
|
27657
|
+
triangles: e * D_,
|
|
27658
|
+
bvh: Math.ceil(e * k_) * O_,
|
|
27641
27659
|
geometry: n,
|
|
27642
|
-
placements: t *
|
|
27643
|
-
orderMaps: e *
|
|
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
|
|
27648
|
-
let i = Math.min(e,
|
|
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
|
|
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
|
-
},
|
|
27709
|
-
function
|
|
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 =
|
|
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(
|
|
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
|
|
27730
|
-
function
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
27801
|
-
function
|
|
27802
|
-
|
|
27803
|
-
for (let e of u.values())
|
|
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
|
-
|
|
27806
|
-
function
|
|
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 =
|
|
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
|
|
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) =>
|
|
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(
|
|
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.
|
|
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:
|
|
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
|
|
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
|
|
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 =
|
|
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:
|
|
29233
|
+
safeBytes: M_,
|
|
29217
29234
|
maxBytes: t,
|
|
29218
|
-
fits: r.total <=
|
|
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(
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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(_,
|
|
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(
|
|
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 &&
|
|
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
|
|
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),
|
|
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(
|
|
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
|
|
30191
|
-
|
|
30192
|
-
offset:
|
|
30193
|
-
count:
|
|
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({
|
|
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
|
|
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)
|
|
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],
|
|
30251
|
-
if (!e || !
|
|
30280
|
+
let e = this.meshes?.[t], o = n.placementRunOf(t);
|
|
30281
|
+
if (!e || !o) continue;
|
|
30252
30282
|
e.updateMatrixWorld(!0);
|
|
30253
|
-
let
|
|
30254
|
-
for (let e = 0; e <
|
|
30255
|
-
let t =
|
|
30256
|
-
n.isSet[t] && (
|
|
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:
|
|
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 ||
|
|
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
|
|
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 =
|
|
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 ||
|
|
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
|
|
30474
|
-
(!this._tlasBounds || this._tlasBounds.length <
|
|
30475
|
-
let
|
|
30476
|
-
for (let
|
|
30477
|
-
let
|
|
30478
|
-
if (
|
|
30479
|
-
let
|
|
30480
|
-
|
|
30481
|
-
} else if (
|
|
30482
|
-
let
|
|
30483
|
-
|
|
30484
|
-
let u =
|
|
30485
|
-
l[u] = Math.min(l[
|
|
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(
|
|
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.
|
|
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 =
|
|
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 =
|
|
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.
|
|
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
|
|
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(
|
|
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
|
-
|
|
43685
|
-
|
|
43686
|
-
|
|
43687
|
-
|
|
43688
|
-
|
|
43689
|
-
|
|
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.
|
|
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.
|
|
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) +
|
|
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
|
-
},
|
|
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
|
-
}),
|
|
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(${
|
|
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 & ${
|
|
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 = ${
|
|
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
|
-
`,
|
|
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(${
|
|
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 & ${
|
|
44137
|
-
let pick = select( raw, raw & ~${
|
|
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 & ${
|
|
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 & ${
|
|
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
|
-
`,
|
|
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(${
|
|
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 & ${
|
|
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
|
-
`,
|
|
44302
|
+
`, Lk = (e) => ({
|
|
44219
44303
|
binding: e,
|
|
44220
44304
|
visibility: GPUShaderStage.COMPUTE,
|
|
44221
44305
|
texture: { sampleType: "unfilterable-float" }
|
|
44222
|
-
}),
|
|
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
|
-
}),
|
|
44313
|
+
}), zk = (e, t) => ({
|
|
44230
44314
|
binding: e,
|
|
44231
44315
|
visibility: GPUShaderStage.COMPUTE,
|
|
44232
44316
|
buffer: { type: t }
|
|
44233
|
-
}),
|
|
44317
|
+
}), Bk = class {
|
|
44234
44318
|
constructor(e) {
|
|
44235
44319
|
this.device = e, this.settings = {
|
|
44236
|
-
...
|
|
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(
|
|
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 =
|
|
44431
|
+
}, n = zk(0, "uniform");
|
|
44348
44432
|
this._pipelines = {
|
|
44349
|
-
select: t("oidn-history-select",
|
|
44433
|
+
select: t("oidn-history-select", Pk, [
|
|
44350
44434
|
n,
|
|
44351
|
-
|
|
44352
|
-
|
|
44353
|
-
|
|
44354
|
-
|
|
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
|
-
|
|
44361
|
-
|
|
44444
|
+
zk(6, "read-only-storage"),
|
|
44445
|
+
zk(7, "read-only-storage")
|
|
44362
44446
|
]),
|
|
44363
|
-
blend: t("oidn-history-blend",
|
|
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(
|
|
44374
|
-
|
|
44375
|
-
|
|
44376
|
-
|
|
44377
|
-
|
|
44378
|
-
|
|
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",
|
|
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(
|
|
44390
|
-
|
|
44391
|
-
|
|
44392
|
-
|
|
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:
|
|
44480
|
+
size: Dk,
|
|
44397
44481
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
44398
|
-
}), this._growMoved(
|
|
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 /
|
|
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 ?
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
44557
|
+
function Gk() {
|
|
44474
44558
|
let { upscalerModelBaseUrl: e } = A(), t = {};
|
|
44475
|
-
for (let n in
|
|
44559
|
+
for (let n in Wk) {
|
|
44476
44560
|
t[n] = {};
|
|
44477
|
-
for (let r in
|
|
44561
|
+
for (let r in Wk[n]) t[n][r] = e + Wk[n][r];
|
|
44478
44562
|
}
|
|
44479
44563
|
return t;
|
|
44480
44564
|
}
|
|
44481
|
-
var
|
|
44565
|
+
var Kk = {
|
|
44482
44566
|
get QUALITY_PRESETS() {
|
|
44483
|
-
return
|
|
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
|
-
},
|
|
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 ||
|
|
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.
|
|
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 =
|
|
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
|
|
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:
|
|
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)
|
|
44596
|
-
let o =
|
|
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 =
|
|
44637
|
-
|
|
44638
|
-
|
|
44639
|
-
|
|
44640
|
-
|
|
44641
|
-
|
|
44642
|
-
|
|
44643
|
-
|
|
44644
|
-
|
|
44645
|
-
|
|
44646
|
-
|
|
44647
|
-
|
|
44648
|
-
width:
|
|
44649
|
-
height:
|
|
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 {
|
|
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
|
|
44668
|
-
|
|
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
|
|
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 {
|
|
44702
|
-
for (let e =
|
|
44703
|
-
|
|
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 (!
|
|
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 =
|
|
44720
|
-
let p = f.getContext("2d");
|
|
44721
|
-
|
|
44722
|
-
|
|
44723
|
-
|
|
44724
|
-
|
|
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 {
|
|
44731
|
-
for (let e = 0
|
|
44732
|
-
let t = e * 4
|
|
44733
|
-
|
|
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(
|
|
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 (!
|
|
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.
|
|
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
|
-
},
|
|
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
|
|
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
|
|
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 >
|
|
44917
|
-
let n = !this._movingHopeless && (t < 2 || e <=
|
|
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 <
|
|
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 ?
|
|
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 >
|
|
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 >
|
|
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:
|
|
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 >=
|
|
45111
|
+
if (e.frameCount >= rA) return null;
|
|
45035
45112
|
let n = this._historyInputs();
|
|
45036
|
-
return n ? t.merge(n, e.frameCount, this._historyCameraNow(), { historyScale:
|
|
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
|
|
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
|
-
|
|
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-
|
|
45180
|
+
let i = await import("./NeuralSuperRes-FVqRJKQV.js").then((e) => e.t);
|
|
45104
45181
|
this._superResModule = i;
|
|
45105
|
-
let a = r ? await import("./NeuralRetouch-
|
|
45106
|
-
if (r && !c && (
|
|
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
|
-
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
|
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
|
|
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
|
|
45461
|
+
var uA = 4096, dA = class {
|
|
45385
45462
|
constructor() {
|
|
45386
|
-
this.canvas =
|
|
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 =
|
|
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
|
-
},
|
|
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 =
|
|
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
|
|
45498
|
+
this._viewOverlay = await new dA().init({
|
|
45422
45499
|
device: e,
|
|
45423
45500
|
sizeSource: t
|
|
45424
45501
|
});
|
|
45425
45502
|
} catch (e) {
|
|
45426
|
-
|
|
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
|
|
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
|
|
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) && (
|
|
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())
|
|
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 (
|
|
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 (
|
|
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 ?
|
|
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())
|
|
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
|
-
}
|
|
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
|
|
45563
|
-
for (let
|
|
45564
|
-
let { nodeName: e, propertyName:
|
|
45565
|
-
|
|
45566
|
-
|
|
45567
|
-
|
|
45568
|
-
|
|
45569
|
-
|
|
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
|
|
45573
|
-
for (let e of
|
|
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(
|
|
45576
|
-
visibility:
|
|
45577
|
-
cameras: [...
|
|
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
|
|
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
|
-
|
|
45671
|
-
let e
|
|
45672
|
-
|
|
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:
|
|
45775
|
+
cameras: t
|
|
45676
45776
|
});
|
|
45677
|
-
let
|
|
45678
|
-
return (e) => (
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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)
|
|
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) =>
|
|
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(
|
|
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
|
-
},
|
|
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
|
-
},
|
|
45852
|
-
function
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
45898
|
-
let t = e.meshScene, n =
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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) =>
|
|
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 =
|
|
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
|
|
46151
|
+
var NA = ({ element: e, pbrtEntry: t } = {}) => ({
|
|
46052
46152
|
...e === void 0 ? {} : { element: e },
|
|
46053
46153
|
...t === void 0 ? {} : { pbrtEntry: t }
|
|
46054
|
-
}),
|
|
46055
|
-
async function
|
|
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
|
|
46068
|
-
function
|
|
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
|
|
46074
|
-
function
|
|
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 ||
|
|
46181
|
+
isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || BA.test(n)
|
|
46082
46182
|
};
|
|
46083
46183
|
}
|
|
46084
|
-
var
|
|
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
|
-
|
|
46188
|
+
PA.get(t)?.dispose();
|
|
46089
46189
|
} catch (e) {
|
|
46090
|
-
|
|
46190
|
+
RA.warn("prior canvas owner dispose failed", e);
|
|
46091
46191
|
}
|
|
46092
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
!
|
|
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) =>
|
|
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,
|
|
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
|
-
|
|
46356
|
+
RA.warn("failed to clear TSL texture singleton listeners", e);
|
|
46257
46357
|
}
|
|
46258
|
-
this.canvas &&
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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
|
|
46661
|
+
return OA(this);
|
|
46562
46662
|
}
|
|
46563
46663
|
async importSceneState(e, t) {
|
|
46564
|
-
return await
|
|
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,
|
|
46610
|
-
return this.stages.pathTracer.updateTriangleData(this._sdf.triangles, n), this.stages.pathTracer.updateBVHData(this._sdf.bvh), this.reset(!1, { motion: !0 }),
|
|
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 =
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 },
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
47527
|
-
let t = await
|
|
47626
|
+
async function UA(e) {
|
|
47627
|
+
let t = await GA(e);
|
|
47528
47628
|
try {
|
|
47529
|
-
return await
|
|
47629
|
+
return await WA(t, e);
|
|
47530
47630
|
} finally {
|
|
47531
47631
|
t.dispose();
|
|
47532
47632
|
}
|
|
47533
47633
|
}
|
|
47534
|
-
async function
|
|
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
|
|
47554
|
-
let u = new
|
|
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
|
|
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,
|
|
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 };
|