rayzee 9.3.1 → 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 +603 -462
- 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 +3 -3
- package/src/Processor/BVHRefitter.js +64 -0
- package/src/Processor/SceneProcessor.js +34 -5
- package/src/Processor/ToneMapGPU.js +64 -15
- package/src/Processor/Workers/BVHRefitWorker.js +5 -2
- package/src/Stages/PathTracerStage.js +29 -7
- package/src/managers/AnimationManager.js +88 -6
- package/src/managers/CameraManager.js +31 -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,20 +30195,40 @@ var dy = class {
|
|
|
30178
30195
|
triRecordsPerChunk: this.triangles.recordsPerChunk
|
|
30179
30196
|
});
|
|
30180
30197
|
}
|
|
30181
|
-
let i = this.instanceTable;
|
|
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
|
-
if (t
|
|
30203
|
+
if (!t) continue;
|
|
30204
|
+
if (this._updateMeshTrianglePositions(e, t), s.push(i.blasOffsetOf(e), i.blasNodeCountOf(e)), r) {
|
|
30186
30205
|
let t = r(e);
|
|
30187
30206
|
t && this._patchMeshSmoothNormals(e, t);
|
|
30188
30207
|
}
|
|
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
|
|
30212
|
+
});
|
|
30189
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
|
+
});
|
|
30190
30219
|
return new Promise((e, t) => {
|
|
30191
30220
|
this._refitWorker.onmessage = (n) => {
|
|
30192
30221
|
let r = n.data;
|
|
30193
|
-
r.type === "refitComplete" ? e({
|
|
30194
|
-
|
|
30222
|
+
r.type === "refitComplete" ? e({
|
|
30223
|
+
refitTimeMs: r.refitTimeMs,
|
|
30224
|
+
triRanges: o,
|
|
30225
|
+
bvhRanges: d
|
|
30226
|
+
}) : r.type === "error" && t(Error(r.error));
|
|
30227
|
+
}, this._refitWorker.postMessage({
|
|
30228
|
+
type: "refit",
|
|
30229
|
+
blasRanges: u ? s : null,
|
|
30230
|
+
tlasNodeCount: l
|
|
30231
|
+
});
|
|
30195
30232
|
});
|
|
30196
30233
|
}
|
|
30197
30234
|
_patchSmoothNormals(e) {
|
|
@@ -30210,7 +30247,7 @@ var dy = class {
|
|
|
30210
30247
|
let r = this._meshSource(t, "position"), i = this._meshSource(n, "normal");
|
|
30211
30248
|
if (!r) throw Error("SceneProcessor.refitBLASes: positions are required.");
|
|
30212
30249
|
let a = performance.now();
|
|
30213
|
-
this._blasRefitter ||= new
|
|
30250
|
+
this._blasRefitter ||= new Xg();
|
|
30214
30251
|
let o = this.instanceTable;
|
|
30215
30252
|
for (let t of e) {
|
|
30216
30253
|
let e = this._placementOf(t);
|
|
@@ -30236,20 +30273,22 @@ var dy = class {
|
|
|
30236
30273
|
}
|
|
30237
30274
|
updateMeshTransforms(e) {
|
|
30238
30275
|
if (!this.instanceTable || !this.bvh) throw Error("No TLAS/BLAS data available. Run buildBVH() first.");
|
|
30239
|
-
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;
|
|
30240
30279
|
for (let t of e) {
|
|
30241
|
-
let e = this.meshes?.[t],
|
|
30242
|
-
if (!e || !
|
|
30280
|
+
let e = this.meshes?.[t], o = n.placementRunOf(t);
|
|
30281
|
+
if (!e || !o) continue;
|
|
30243
30282
|
e.updateMatrixWorld(!0);
|
|
30244
|
-
let
|
|
30245
|
-
for (let e = 0; e <
|
|
30246
|
-
let t =
|
|
30247
|
-
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++);
|
|
30248
30287
|
}
|
|
30249
30288
|
}
|
|
30250
|
-
return this._refitTLAS(), {
|
|
30289
|
+
return this._refitTLAS(i), i.fill(0), {
|
|
30251
30290
|
refitTimeMs: performance.now() - t,
|
|
30252
|
-
placements:
|
|
30291
|
+
placements: a
|
|
30253
30292
|
};
|
|
30254
30293
|
}
|
|
30255
30294
|
_ownInstanceMatrices(e) {
|
|
@@ -30258,7 +30297,7 @@ var dy = class {
|
|
|
30258
30297
|
}
|
|
30259
30298
|
_writeLeafMatrix(e) {
|
|
30260
30299
|
let t = this.instanceTable.tlasLeafIndex[e];
|
|
30261
|
-
t < 0 ||
|
|
30300
|
+
t < 0 || E_.writeLeafMatrix(this.bvh.chunkFor(t), this.bvhIndexChunks.chunkFor(t), this.bvh.baseOf(t), this.instanceTable.world, e);
|
|
30262
30301
|
}
|
|
30263
30302
|
computeTLASDirtyRange() {
|
|
30264
30303
|
return {
|
|
@@ -30382,7 +30421,7 @@ var dy = class {
|
|
|
30382
30421
|
let n = new Float64Array(t * 6);
|
|
30383
30422
|
e.writeWorldAABBs(n);
|
|
30384
30423
|
let { tlasData: r, nodeCount: i } = await this._runTLASWorker(n, t);
|
|
30385
|
-
return
|
|
30424
|
+
return E_.fillLeaves(r, i, e), r;
|
|
30386
30425
|
} catch (e) {
|
|
30387
30426
|
this._tlasWorkerFailed = !0, ay.warn(`TLAS worker unavailable (${e.message}); building on the main thread`);
|
|
30388
30427
|
}
|
|
@@ -30405,6 +30444,7 @@ var dy = class {
|
|
|
30405
30444
|
});
|
|
30406
30445
|
}
|
|
30407
30446
|
_setBVHData(e) {
|
|
30447
|
+
this._tlasLeafBoxesOf = null;
|
|
30408
30448
|
let t = e ? e instanceof Qa ? e : Qa.adopt([e], e.length / 16, 16, e.length / 16) : null;
|
|
30409
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;
|
|
30410
30450
|
}
|
|
@@ -30413,7 +30453,7 @@ var dy = class {
|
|
|
30413
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;
|
|
30414
30454
|
}
|
|
30415
30455
|
_updateMeshTrianglePositions(e, t) {
|
|
30416
|
-
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);
|
|
30417
30457
|
for (let e = 0; e < p; e++) {
|
|
30418
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];
|
|
30419
30459
|
if (!h) {
|
|
@@ -30442,7 +30482,7 @@ var dy = class {
|
|
|
30442
30482
|
this._patchNormalsRange(t, n.triOffsetOf(e), n.triCountOf(e), n.matrixWorldOf(e), n.bvhToOriginalOf(e));
|
|
30443
30483
|
}
|
|
30444
30484
|
_patchNormalsRange(e, t, n, r, i) {
|
|
30445
|
-
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 = [
|
|
30446
30486
|
a,
|
|
30447
30487
|
o,
|
|
30448
30488
|
s
|
|
@@ -30460,22 +30500,23 @@ var dy = class {
|
|
|
30460
30500
|
}
|
|
30461
30501
|
}
|
|
30462
30502
|
}
|
|
30463
|
-
_refitTLAS() {
|
|
30464
|
-
let
|
|
30465
|
-
(!this._tlasBounds || this._tlasBounds.length <
|
|
30466
|
-
let
|
|
30467
|
-
for (let
|
|
30468
|
-
let
|
|
30469
|
-
if (
|
|
30470
|
-
let
|
|
30471
|
-
|
|
30472
|
-
} else if (
|
|
30473
|
-
let
|
|
30474
|
-
|
|
30475
|
-
let u =
|
|
30476
|
-
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]);
|
|
30477
30517
|
}
|
|
30478
30518
|
}
|
|
30519
|
+
this._tlasLeafBoxesOf = n;
|
|
30479
30520
|
}
|
|
30480
30521
|
scheduleBackgroundRebuild(e, t) {
|
|
30481
30522
|
if (!this.instanceTable || !this.triangles) return;
|
|
@@ -30525,7 +30566,7 @@ var dy = class {
|
|
|
30525
30566
|
let n = this.instanceTable.entryAt(e);
|
|
30526
30567
|
if (!n || !this.instanceTable.isOwner(e)) continue;
|
|
30527
30568
|
let i = this._pendingRebuilds.get(e);
|
|
30528
|
-
i && i.terminate(), r(e, n, Ls(
|
|
30569
|
+
i && i.terminate(), r(e, n, Ls($g));
|
|
30529
30570
|
}
|
|
30530
30571
|
}
|
|
30531
30572
|
_swapBLAS(e, t, n, r) {
|
|
@@ -31154,15 +31195,22 @@ var vy = class {
|
|
|
31154
31195
|
_updateStorageBuffer(e, t) {
|
|
31155
31196
|
e && (e.array.set(t), e.clearUpdateRanges(), e.needsUpdate = !0);
|
|
31156
31197
|
}
|
|
31157
|
-
updateTriangleData(e) {
|
|
31158
|
-
e?.chunks?.length > 1 ? this._triangleRecords = e : e && (this._triangleFlat = e.chunks ? e.chunks[0] : e), this._uploadTriangles(0, this._triangleRecordCount);
|
|
31198
|
+
updateTriangleData(e, t) {
|
|
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);
|
|
31159
31200
|
}
|
|
31160
|
-
updateBVHData(e) {
|
|
31201
|
+
updateBVHData(e, t) {
|
|
31161
31202
|
if (this._bvhRecords) {
|
|
31162
|
-
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);
|
|
31163
31204
|
return;
|
|
31164
31205
|
}
|
|
31165
|
-
|
|
31206
|
+
let n = e?.chunks ? e.chunks[0] : e;
|
|
31207
|
+
if (!t) {
|
|
31208
|
+
this._updateStorageBuffer(this.bvhStorageAttr, n);
|
|
31209
|
+
return;
|
|
31210
|
+
}
|
|
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);
|
|
31166
31214
|
}
|
|
31167
31215
|
updateBufferRanges(e, t) {
|
|
31168
31216
|
if (this.triangleGeoAttr && e.length > 0) {
|
|
@@ -33887,7 +33935,7 @@ var Zx = a("wavefront"), Qx = 256, $x = [
|
|
|
33887
33935
|
}
|
|
33888
33936
|
_computePathBudget() {
|
|
33889
33937
|
if (this._pathBudgetOverride > 0) return this._pathBudgetOverride;
|
|
33890
|
-
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);
|
|
33891
33939
|
return s = Math.max(262144, s), s;
|
|
33892
33940
|
}
|
|
33893
33941
|
_updateChunkLayout() {
|
|
@@ -42278,7 +42326,7 @@ var yO = class extends Mn {
|
|
|
42278
42326
|
this.camera = new yO(60, t / n || 1, .01, 1e3), this.camera.position.set(0, 0, 5), this.controls = new Dr(this.camera, e), this.controls.screenSpacePanning = !0, this.controls.zoomToCursor = !0, this.controls.saveState(), this._reportedOrthoHeight = null, this._reportOrthoHeight = this._reportOrthoHeight.bind(this), this.controls.addEventListener("change", this._reportOrthoHeight), this.walkControls = new FO(this.camera, e, this.controls), this.interactionManager = null, this.cameras = [this.camera], this.currentCameraIndex = 0, this._userCameraCounter = 0, this.autoFocusMode = ji.SMOOTHING_FACTOR ? "auto" : "manual", this.afScreenPoint = {
|
|
42279
42327
|
x: .5,
|
|
42280
42328
|
y: .5
|
|
42281
|
-
}, this.afSmoothingFactor = ji.SMOOTHING_FACTOR, this._lastValidFocusDistance = null, this._smoothedFocusDistance = null, this._afPointDirty = !1, this._afSuspended = !1, this._defaultCameraState = null, this._onResize = null, this._onReset = null, this._getSettings = null, this._applySettings = null;
|
|
42329
|
+
}, this.afSmoothingFactor = ji.SMOOTHING_FACTOR, this._lastValidFocusDistance = null, this._smoothedFocusDistance = null, this._afPointDirty = !1, this._afSuspended = !1, this._afPick = null, this._defaultCameraState = null, this._onResize = null, this._onReset = null, this._getSettings = null, this._applySettings = null;
|
|
42282
42330
|
}
|
|
42283
42331
|
setCameras(e) {
|
|
42284
42332
|
this.cameras = e, this._userCameraCounter = 0, this.resetAutoFocus();
|
|
@@ -42571,8 +42619,8 @@ var yO = class extends Mn {
|
|
|
42571
42619
|
this._afSuspended && (this._afSuspended = !1, this._smoothedFocusDistance = null);
|
|
42572
42620
|
let l = a;
|
|
42573
42621
|
if (l?.isReady && l.renderMode?.value === 1 && l.frameCount > 0 && !l.isComplete) return;
|
|
42574
|
-
let u = this.
|
|
42575
|
-
if (u) d = OC(u
|
|
42622
|
+
let u = this._pickFocusPoint(l.resetCount), d;
|
|
42623
|
+
if (u) d = OC(u, this.camera), this._lastValidFocusDistance = d;
|
|
42576
42624
|
else if (this._lastValidFocusDistance !== null) d = this._lastValidFocusDistance;
|
|
42577
42625
|
else {
|
|
42578
42626
|
let e = this.controls ? OC(this.controls.target, this.camera) : 0;
|
|
@@ -42593,6 +42641,22 @@ var yO = class extends Mn {
|
|
|
42593
42641
|
f ? c?.() : n > ji.RESET_THRESHOLD && s?.();
|
|
42594
42642
|
}
|
|
42595
42643
|
}
|
|
42644
|
+
_pickFocusPoint(e) {
|
|
42645
|
+
let t = this.camera, { x: n, y: r } = this.afScreenPoint, i = this._afPick ??= {
|
|
42646
|
+
point: new ur(),
|
|
42647
|
+
hit: !1,
|
|
42648
|
+
resetCount: NaN,
|
|
42649
|
+
x: NaN,
|
|
42650
|
+
y: NaN,
|
|
42651
|
+
view: new yn(),
|
|
42652
|
+
projection: new yn()
|
|
42653
|
+
};
|
|
42654
|
+
if (this._afPointDirty || e !== i.resetCount || n !== i.x || r !== i.y || !i.view.equals(t.matrixWorld) || !i.projection.equals(t.projectionMatrix)) {
|
|
42655
|
+
let a = this.interactionManager.pickSurface(n * 2 - 1, 1 - r * 2);
|
|
42656
|
+
i.hit = !!a, a && i.point.copy(a.point), i.resetCount = e, i.x = n, i.y = r, i.view.copy(t.matrixWorld), i.projection.copy(t.projectionMatrix);
|
|
42657
|
+
}
|
|
42658
|
+
return i.hit ? i.point : null;
|
|
42659
|
+
}
|
|
42596
42660
|
setInteractionManager(e) {
|
|
42597
42661
|
this.interactionManager = e;
|
|
42598
42662
|
}
|
|
@@ -43433,7 +43497,18 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43433
43497
|
// survives the denoise.
|
|
43434
43498
|
textureStore( dst, vec2<u32>( px, py ), vec4<f32>( src[ si ].xyz / scaleBuf[ 0 ], inColor[ si ].w ) );
|
|
43435
43499
|
}
|
|
43436
|
-
`, 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 {
|
|
43437
43512
|
constructor(e, t = {}) {
|
|
43438
43513
|
if (super(), !e) throw Error("OIDNDenoiser requires a renderer");
|
|
43439
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 = {
|
|
@@ -43443,7 +43518,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43443
43518
|
}, this._gpuInputBufferSize = {
|
|
43444
43519
|
width: 0,
|
|
43445
43520
|
height: 0
|
|
43446
|
-
}, 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 = {
|
|
43447
43522
|
width: 0,
|
|
43448
43523
|
height: 0
|
|
43449
43524
|
}, this.config = {
|
|
@@ -43578,45 +43653,13 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43578
43653
|
if (!r?.color) return sk.warn("GPU textures not ready yet"), !1;
|
|
43579
43654
|
let i = this.gpuDevice;
|
|
43580
43655
|
if (!i) return sk.warn("gpuDevice not available"), !1;
|
|
43581
|
-
this._ensureGPUInputBuffers(t, n)
|
|
43582
|
-
let a = i.createCommandEncoder({ label: "oidn-tex-to-buf" }), o = t * 16, s = this._gpuInputPaddedRowBytes, c = s > o, l = this._gpuInputPadBuffer, u = (e, r) => {
|
|
43583
|
-
if (!c) a.copyTextureToBuffer({
|
|
43584
|
-
texture: e,
|
|
43585
|
-
mipLevel: 0
|
|
43586
|
-
}, {
|
|
43587
|
-
buffer: r,
|
|
43588
|
-
offset: 0,
|
|
43589
|
-
bytesPerRow: o,
|
|
43590
|
-
rowsPerImage: n
|
|
43591
|
-
}, {
|
|
43592
|
-
width: t,
|
|
43593
|
-
height: n,
|
|
43594
|
-
depthOrArrayLayers: 1
|
|
43595
|
-
});
|
|
43596
|
-
else {
|
|
43597
|
-
a.copyTextureToBuffer({
|
|
43598
|
-
texture: e,
|
|
43599
|
-
mipLevel: 0
|
|
43600
|
-
}, {
|
|
43601
|
-
buffer: l,
|
|
43602
|
-
offset: 0,
|
|
43603
|
-
bytesPerRow: s,
|
|
43604
|
-
rowsPerImage: n
|
|
43605
|
-
}, {
|
|
43606
|
-
width: t,
|
|
43607
|
-
height: n,
|
|
43608
|
-
depthOrArrayLayers: 1
|
|
43609
|
-
});
|
|
43610
|
-
for (let e = 0; e < n; e++) a.copyBufferToBuffer(l, e * s, r, e * o, o);
|
|
43611
|
-
}
|
|
43612
|
-
};
|
|
43613
|
-
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, {
|
|
43614
43657
|
x: 0,
|
|
43615
43658
|
y: 0,
|
|
43616
43659
|
width: t,
|
|
43617
43660
|
height: n
|
|
43618
43661
|
}, !1);
|
|
43619
|
-
let
|
|
43662
|
+
let a = {
|
|
43620
43663
|
color: {
|
|
43621
43664
|
data: this._gpuInputBuffers.color,
|
|
43622
43665
|
width: t,
|
|
@@ -43633,7 +43676,41 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43633
43676
|
height: n
|
|
43634
43677
|
}
|
|
43635
43678
|
};
|
|
43636
|
-
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()]);
|
|
43637
43714
|
}
|
|
43638
43715
|
_ensureGPUInputBuffers(e, t) {
|
|
43639
43716
|
let { width: n, height: r } = this._gpuInputBufferSize;
|
|
@@ -43656,19 +43733,51 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43656
43733
|
width: e,
|
|
43657
43734
|
height: t
|
|
43658
43735
|
};
|
|
43659
|
-
|
|
43660
|
-
|
|
43661
|
-
|
|
43662
|
-
|
|
43663
|
-
|
|
43664
|
-
|
|
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;
|
|
43665
43774
|
}
|
|
43666
43775
|
_destroyGPUInputBuffers() {
|
|
43667
|
-
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 = {
|
|
43668
43777
|
color: null,
|
|
43669
43778
|
albedo: null,
|
|
43670
43779
|
normal: null
|
|
43671
|
-
}, this.
|
|
43780
|
+
}, this._packParams = null, this._gpuInputBufferSize = {
|
|
43672
43781
|
width: 0,
|
|
43673
43782
|
height: 0
|
|
43674
43783
|
};
|
|
@@ -43814,7 +43923,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43814
43923
|
}
|
|
43815
43924
|
gpuBytes() {
|
|
43816
43925
|
let { color: e, albedo: t, normal: n } = this._gpuInputBuffers, r = this._outGPUTexture ? this._outTexSize.width * this._outTexSize.height * 8 : 0;
|
|
43817
|
-
return (e?.size ?? 0) + (t?.size ?? 0) + (n?.size ?? 0) +
|
|
43926
|
+
return (e?.size ?? 0) + (t?.size ?? 0) + (n?.size ?? 0) + r;
|
|
43818
43927
|
}
|
|
43819
43928
|
_ensureOutputTexture(e, t, n) {
|
|
43820
43929
|
if (this._outGPUTexture && this._outTexSize.width === t && this._outTexSize.height === n) return;
|
|
@@ -43968,7 +44077,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43968
44077
|
dispose() {
|
|
43969
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");
|
|
43970
44079
|
}
|
|
43971
|
-
},
|
|
44080
|
+
}, Tk = Object.freeze({
|
|
43972
44081
|
maxLength: 8,
|
|
43973
44082
|
smoothLength: 2,
|
|
43974
44083
|
roughStart: .45,
|
|
@@ -43976,7 +44085,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
43976
44085
|
depthTolerance: .05,
|
|
43977
44086
|
normalTolerance: .8,
|
|
43978
44087
|
movedLength: 2
|
|
43979
|
-
}),
|
|
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 + `
|
|
43980
44089
|
@group(0) @binding(1) var geoCur: texture_2d<f32>;
|
|
43981
44090
|
@group(0) @binding(2) var geoPrev: texture_2d<f32>;
|
|
43982
44091
|
@group(0) @binding(3) var<storage, read_write> picked: array<i32>;
|
|
@@ -44002,7 +44111,7 @@ fn movedIndex( leaf: u32 ) -> i32 {
|
|
|
44002
44111
|
|
|
44003
44112
|
}
|
|
44004
44113
|
|
|
44005
|
-
@compute @workgroup_size(${
|
|
44114
|
+
@compute @workgroup_size(${Ek}, ${Ek})
|
|
44006
44115
|
fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
44007
44116
|
|
|
44008
44117
|
if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
|
|
@@ -44017,7 +44126,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44017
44126
|
let size = vec2<f32>( P.size );
|
|
44018
44127
|
let uv = ( vec2<f32>( gid.xy ) + 0.5 ) / size;
|
|
44019
44128
|
// Depth is along the ray: from the camera, or from its image plane when orthographic.
|
|
44020
|
-
let ortho = ( P.flags & ${
|
|
44129
|
+
let ortho = ( P.flags & ${jk}u ) != 0u;
|
|
44021
44130
|
let ndc = vec2<f32>( uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0 );
|
|
44022
44131
|
var origin = P.camWorld[ 3 ].xyz;
|
|
44023
44132
|
var dir: vec3<f32>;
|
|
@@ -44041,7 +44150,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44041
44150
|
let toPrev = movedToPrev[ u32( m ) ];
|
|
44042
44151
|
wp = ( toPrev * vec4<f32>( wp, 1.0 ) ).xyz;
|
|
44043
44152
|
n = normalize( ( toPrev * vec4<f32>( n, 0.0 ) ).xyz );
|
|
44044
|
-
movedFlag = ${
|
|
44153
|
+
movedFlag = ${Mk};
|
|
44045
44154
|
|
|
44046
44155
|
}
|
|
44047
44156
|
|
|
@@ -44078,7 +44187,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44078
44187
|
if ( pick >= 0 ) { atomicAdd( &copies[ u32( pick ) ], 1u ); }
|
|
44079
44188
|
|
|
44080
44189
|
}
|
|
44081
|
-
`,
|
|
44190
|
+
`, Fk = Nk + `
|
|
44082
44191
|
@group(0) @binding(1) var curColor: texture_2d<f32>;
|
|
44083
44192
|
@group(0) @binding(2) var curAlbedo: texture_2d<f32>;
|
|
44084
44193
|
@group(0) @binding(3) var curNormal: texture_2d<f32>;
|
|
@@ -44092,7 +44201,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44092
44201
|
@group(0) @binding(11) var outAlbedo: texture_storage_2d<rgba32float, write>;
|
|
44093
44202
|
@group(0) @binding(12) var outNormal: texture_storage_2d<rgba32float, write>;
|
|
44094
44203
|
|
|
44095
|
-
@compute @workgroup_size(${
|
|
44204
|
+
@compute @workgroup_size(${Ek}, ${Ek})
|
|
44096
44205
|
fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
44097
44206
|
|
|
44098
44207
|
if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
|
|
@@ -44108,8 +44217,8 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44108
44217
|
var ha = ca.xyz;
|
|
44109
44218
|
var hn = cn.xyz;
|
|
44110
44219
|
let raw = picked[ gid.y * P.size.x + gid.x ];
|
|
44111
|
-
let movedPx = raw >= 0 && ( raw & ${
|
|
44112
|
-
let pick = select( raw, raw & ~${
|
|
44220
|
+
let movedPx = raw >= 0 && ( raw & ${Mk} ) != 0;
|
|
44221
|
+
let pick = select( raw, raw & ~${Mk}, raw >= 0 );
|
|
44113
44222
|
|
|
44114
44223
|
if ( pick >= 0 ) {
|
|
44115
44224
|
|
|
@@ -44123,7 +44232,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44123
44232
|
ha = a.xyz;
|
|
44124
44233
|
hn = textureLoad( histNormal, q, 0 ).xyz;
|
|
44125
44234
|
len = a.w;
|
|
44126
|
-
if ( ( P.flags & ${
|
|
44235
|
+
if ( ( P.flags & ${Ak}u ) != 0u ) { len = len / f32( max( copies[ u32( pick ) ], 1u ) ); }
|
|
44127
44236
|
|
|
44128
44237
|
}
|
|
44129
44238
|
|
|
@@ -44137,11 +44246,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44137
44246
|
|
|
44138
44247
|
textureStore( outColor, p, vec4<f32>( mix( hc, cur.xyz, t ), cur.w ) );
|
|
44139
44248
|
textureStore( outAlbedo, p, vec4<f32>( mix( ha, ca.xyz, t ), newLen ) );
|
|
44140
|
-
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 );
|
|
44141
44250
|
textureStore( outNormal, p, vec4<f32>( n, cn.w ) );
|
|
44142
44251
|
|
|
44143
44252
|
}
|
|
44144
|
-
`,
|
|
44253
|
+
`, Ik = Nk + `
|
|
44145
44254
|
@group(0) @binding(1) var accColor: texture_2d<f32>;
|
|
44146
44255
|
@group(0) @binding(2) var accAlbedo: texture_2d<f32>;
|
|
44147
44256
|
@group(0) @binding(3) var accNormal: texture_2d<f32>;
|
|
@@ -44152,7 +44261,7 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44152
44261
|
@group(0) @binding(8) var outAlbedo: texture_storage_2d<rgba32float, write>;
|
|
44153
44262
|
@group(0) @binding(9) var outNormal: texture_storage_2d<rgba32float, write>;
|
|
44154
44263
|
|
|
44155
|
-
@compute @workgroup_size(${
|
|
44264
|
+
@compute @workgroup_size(${Ek}, ${Ek})
|
|
44156
44265
|
fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
44157
44266
|
|
|
44158
44267
|
if ( gid.x >= P.size.x || gid.y >= P.size.y ) { return; }
|
|
@@ -44186,32 +44295,32 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44186
44295
|
let t = P.samples / max( k + P.samples, 1e-6 );
|
|
44187
44296
|
textureStore( outColor, p, vec4<f32>( mix( hc, ac.xyz, t ), ac.w ) );
|
|
44188
44297
|
textureStore( outAlbedo, p, vec4<f32>( mix( ha, aa.xyz, t ), min( k + P.samples, P.maxLength ) ) );
|
|
44189
|
-
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 );
|
|
44190
44299
|
textureStore( outNormal, p, vec4<f32>( n, an.w ) );
|
|
44191
44300
|
|
|
44192
44301
|
}
|
|
44193
|
-
`,
|
|
44302
|
+
`, Lk = (e) => ({
|
|
44194
44303
|
binding: e,
|
|
44195
44304
|
visibility: GPUShaderStage.COMPUTE,
|
|
44196
44305
|
texture: { sampleType: "unfilterable-float" }
|
|
44197
|
-
}),
|
|
44306
|
+
}), Rk = (e) => ({
|
|
44198
44307
|
binding: e,
|
|
44199
44308
|
visibility: GPUShaderStage.COMPUTE,
|
|
44200
44309
|
storageTexture: {
|
|
44201
44310
|
access: "write-only",
|
|
44202
44311
|
format: "rgba32float"
|
|
44203
44312
|
}
|
|
44204
|
-
}),
|
|
44313
|
+
}), zk = (e, t) => ({
|
|
44205
44314
|
binding: e,
|
|
44206
44315
|
visibility: GPUShaderStage.COMPUTE,
|
|
44207
44316
|
buffer: { type: t }
|
|
44208
|
-
}),
|
|
44317
|
+
}), Bk = class {
|
|
44209
44318
|
constructor(e) {
|
|
44210
44319
|
this.device = e, this.settings = {
|
|
44211
|
-
...
|
|
44320
|
+
...Tk,
|
|
44212
44321
|
cleanAux: !1,
|
|
44213
44322
|
splitCopies: !0
|
|
44214
|
-
}, 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);
|
|
44215
44324
|
}
|
|
44216
44325
|
get textures() {
|
|
44217
44326
|
return this.valid ? this._sets[this._current] : null;
|
|
@@ -44319,23 +44428,23 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44319
44428
|
}),
|
|
44320
44429
|
layout: i
|
|
44321
44430
|
};
|
|
44322
|
-
}, n =
|
|
44431
|
+
}, n = zk(0, "uniform");
|
|
44323
44432
|
this._pipelines = {
|
|
44324
|
-
select: t("oidn-history-select",
|
|
44433
|
+
select: t("oidn-history-select", Pk, [
|
|
44325
44434
|
n,
|
|
44326
|
-
|
|
44327
|
-
|
|
44328
|
-
|
|
44329
|
-
|
|
44435
|
+
Lk(1),
|
|
44436
|
+
Lk(2),
|
|
44437
|
+
zk(3, "storage"),
|
|
44438
|
+
zk(4, "storage"),
|
|
44330
44439
|
{
|
|
44331
44440
|
binding: 5,
|
|
44332
44441
|
visibility: GPUShaderStage.COMPUTE,
|
|
44333
44442
|
texture: { sampleType: "uint" }
|
|
44334
44443
|
},
|
|
44335
|
-
|
|
44336
|
-
|
|
44444
|
+
zk(6, "read-only-storage"),
|
|
44445
|
+
zk(7, "read-only-storage")
|
|
44337
44446
|
]),
|
|
44338
|
-
blend: t("oidn-history-blend",
|
|
44447
|
+
blend: t("oidn-history-blend", Fk, [
|
|
44339
44448
|
n,
|
|
44340
44449
|
...[
|
|
44341
44450
|
1,
|
|
@@ -44345,14 +44454,14 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44345
44454
|
5,
|
|
44346
44455
|
6,
|
|
44347
44456
|
7
|
|
44348
|
-
].map(
|
|
44349
|
-
|
|
44350
|
-
|
|
44351
|
-
|
|
44352
|
-
|
|
44353
|
-
|
|
44457
|
+
].map(Lk),
|
|
44458
|
+
zk(8, "read-only-storage"),
|
|
44459
|
+
zk(9, "read-only-storage"),
|
|
44460
|
+
Rk(10),
|
|
44461
|
+
Rk(11),
|
|
44462
|
+
Rk(12)
|
|
44354
44463
|
]),
|
|
44355
|
-
merge: t("oidn-history-merge",
|
|
44464
|
+
merge: t("oidn-history-merge", Ik, [
|
|
44356
44465
|
n,
|
|
44357
44466
|
...[
|
|
44358
44467
|
1,
|
|
@@ -44361,16 +44470,16 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44361
44470
|
4,
|
|
44362
44471
|
5,
|
|
44363
44472
|
6
|
|
44364
|
-
].map(
|
|
44365
|
-
|
|
44366
|
-
|
|
44367
|
-
|
|
44473
|
+
].map(Lk),
|
|
44474
|
+
Rk(7),
|
|
44475
|
+
Rk(8),
|
|
44476
|
+
Rk(9)
|
|
44368
44477
|
])
|
|
44369
44478
|
}, this._paramsBuffer = e.createBuffer({
|
|
44370
44479
|
label: "oidn-history-params",
|
|
44371
|
-
size:
|
|
44480
|
+
size: Dk,
|
|
44372
44481
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
44373
|
-
}), this._growMoved(
|
|
44482
|
+
}), this._growMoved(Ok);
|
|
44374
44483
|
}
|
|
44375
44484
|
_growMoved(e) {
|
|
44376
44485
|
this._movedLeaves?.destroy(), this._movedToPrev?.destroy();
|
|
@@ -44396,11 +44505,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44396
44505
|
a.setPipeline(t), a.setBindGroup(0, this.device.createBindGroup({
|
|
44397
44506
|
layout: n,
|
|
44398
44507
|
entries: i
|
|
44399
|
-
})), a.dispatchWorkgroups(Math.ceil(this.width /
|
|
44508
|
+
})), a.dispatchWorkgroups(Math.ceil(this.width / Ek), Math.ceil(this.height / Ek)), a.end();
|
|
44400
44509
|
}
|
|
44401
44510
|
_writeParams(e, t, n, r) {
|
|
44402
44511
|
let i = this.settings, a = this._paramU32, o = this._paramF32;
|
|
44403
|
-
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);
|
|
44404
44513
|
}
|
|
44405
44514
|
_rememberCamera(e) {
|
|
44406
44515
|
this._prevViewProj.set(e.viewProj), this._prevCamPos[0] = e.world[12], this._prevCamPos[1] = e.world[13], this._prevCamPos[2] = e.world[14];
|
|
@@ -44410,11 +44519,11 @@ fn main( @builtin(global_invocation_id) gid: vec3<u32> ) {
|
|
|
44410
44519
|
_releaseTextures() {
|
|
44411
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;
|
|
44412
44521
|
}
|
|
44413
|
-
}, 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" });
|
|
44414
|
-
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) {
|
|
44415
44524
|
let t;
|
|
44416
44525
|
try {
|
|
44417
|
-
if (t =
|
|
44526
|
+
if (t = Hk && (self.URL || self.webkitURL).createObjectURL(Hk), !t) throw "";
|
|
44418
44527
|
let n = new Worker(t, {
|
|
44419
44528
|
type: "module",
|
|
44420
44529
|
name: e?.name
|
|
@@ -44423,7 +44532,7 @@ function Vk(e) {
|
|
|
44423
44532
|
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
44424
44533
|
}), n;
|
|
44425
44534
|
} catch {
|
|
44426
|
-
return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(
|
|
44535
|
+
return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(Vk), {
|
|
44427
44536
|
type: "module",
|
|
44428
44537
|
name: e?.name
|
|
44429
44538
|
});
|
|
@@ -44431,7 +44540,7 @@ function Vk(e) {
|
|
|
44431
44540
|
}
|
|
44432
44541
|
//#endregion
|
|
44433
44542
|
//#region src/Passes/AIUpscaler.js
|
|
44434
|
-
var
|
|
44543
|
+
var Wk = {
|
|
44435
44544
|
fast: {
|
|
44436
44545
|
2: "2x-spanx2-ch48.onnx",
|
|
44437
44546
|
4: "4xNomos8k_span_otf_strong_fp32_opset17.onnx"
|
|
@@ -44445,17 +44554,17 @@ var Hk = (e) => Y_(e) ? ((e) => e > 1 ? 1 : e < 0 ? 0 : e) : ((e) => e ** +X_),
|
|
|
44445
44554
|
4: "4xNomos2_hq_mosr_fp32.onnx"
|
|
44446
44555
|
}
|
|
44447
44556
|
};
|
|
44448
|
-
function
|
|
44557
|
+
function Gk() {
|
|
44449
44558
|
let { upscalerModelBaseUrl: e } = A(), t = {};
|
|
44450
|
-
for (let n in
|
|
44559
|
+
for (let n in Wk) {
|
|
44451
44560
|
t[n] = {};
|
|
44452
|
-
for (let r in
|
|
44561
|
+
for (let r in Wk[n]) t[n][r] = e + Wk[n][r];
|
|
44453
44562
|
}
|
|
44454
44563
|
return t;
|
|
44455
44564
|
}
|
|
44456
|
-
var
|
|
44565
|
+
var Kk = {
|
|
44457
44566
|
get QUALITY_PRESETS() {
|
|
44458
|
-
return
|
|
44567
|
+
return Gk();
|
|
44459
44568
|
},
|
|
44460
44569
|
TILE_SIZE: 512,
|
|
44461
44570
|
TILE_OVERLAP: 16,
|
|
@@ -44466,17 +44575,17 @@ var Gk = {
|
|
|
44466
44575
|
}],
|
|
44467
44576
|
graphOptimizationLevel: "all"
|
|
44468
44577
|
}
|
|
44469
|
-
},
|
|
44578
|
+
}, qk = class extends en {
|
|
44470
44579
|
constructor(e, t, n = {}) {
|
|
44471
44580
|
if (super(), !e || !t) throw Error("AIUpscaler requires output canvas and renderer");
|
|
44472
|
-
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 = {
|
|
44473
44582
|
isUpscaling: !1,
|
|
44474
44583
|
isLoading: !1,
|
|
44475
44584
|
abortController: null
|
|
44476
|
-
}, 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;
|
|
44477
44586
|
}
|
|
44478
44587
|
async _ensureSession() {
|
|
44479
|
-
let e =
|
|
44588
|
+
let e = Kk.QUALITY_PRESETS[this.quality];
|
|
44480
44589
|
if (!e) throw Error(`Unknown quality preset: ${this.quality}`);
|
|
44481
44590
|
let t = e[this.scaleFactor];
|
|
44482
44591
|
if (!t) throw Error(`No model for ${this.quality}/${this.scaleFactor}x`);
|
|
@@ -44486,14 +44595,14 @@ var Gk = {
|
|
|
44486
44595
|
message: `Loading ${this.scaleFactor}x upscale model...`
|
|
44487
44596
|
});
|
|
44488
44597
|
try {
|
|
44489
|
-
this._worker ||= new
|
|
44598
|
+
this._worker ||= new Uk(), await new Promise((e, n) => {
|
|
44490
44599
|
let r = (t) => {
|
|
44491
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)));
|
|
44492
44601
|
}, { ortRuntimeUrl: i, ortWasmPaths: a, cacheNamespace: o, storage: s } = A();
|
|
44493
44602
|
this._worker.addEventListener("message", r), this._worker.postMessage({
|
|
44494
44603
|
type: "load",
|
|
44495
44604
|
url: t,
|
|
44496
|
-
sessionOptions:
|
|
44605
|
+
sessionOptions: Kk.SESSION_OPTIONS,
|
|
44497
44606
|
ortRuntimeUrl: i,
|
|
44498
44607
|
ortWasmPaths: a,
|
|
44499
44608
|
cacheNamespace: o,
|
|
@@ -44567,8 +44676,8 @@ var Gk = {
|
|
|
44567
44676
|
willReadFrequently: !0,
|
|
44568
44677
|
alpha: !0
|
|
44569
44678
|
});
|
|
44570
|
-
this._cacheUpscaledAlpha(t, n * i, r * i)
|
|
44571
|
-
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;
|
|
44572
44681
|
for (let o = 0; o < u; o++) for (let u = 0; u < l; u++) {
|
|
44573
44682
|
if (e.aborted) throw new DOMException("Aborted", "AbortError");
|
|
44574
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);
|
|
@@ -44608,46 +44717,39 @@ var Gk = {
|
|
|
44608
44717
|
async _captureSourceHDR() {
|
|
44609
44718
|
let e = this.getGPUTextures();
|
|
44610
44719
|
if (!e?.color) throw Error("No GPU color texture available for HDR capture");
|
|
44611
|
-
let t =
|
|
44612
|
-
|
|
44613
|
-
|
|
44614
|
-
|
|
44615
|
-
|
|
44616
|
-
|
|
44617
|
-
|
|
44618
|
-
|
|
44619
|
-
|
|
44620
|
-
|
|
44621
|
-
|
|
44622
|
-
|
|
44623
|
-
width:
|
|
44624
|
-
height:
|
|
44625
|
-
depthOrArrayLayers: 1
|
|
44626
|
-
}), t.queue.submit([c.finish()]), await s.mapAsync(GPUMapMode.READ);
|
|
44627
|
-
let l = new Float32Array(s.getMappedRange()), u = r * 4, d = a / 4, f = new Float32Array(r * i * 4);
|
|
44628
|
-
for (let e = 0; e < i; e++) {
|
|
44629
|
-
let t = e * d, n = e * u;
|
|
44630
|
-
f.set(l.subarray(t, t + u), n);
|
|
44631
|
-
}
|
|
44632
|
-
return s.unmap(), {
|
|
44633
|
-
data: f,
|
|
44634
|
-
width: r,
|
|
44635
|
-
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,
|
|
44636
44734
|
isHDR: !0
|
|
44637
44735
|
};
|
|
44638
44736
|
}
|
|
44639
44737
|
_extractTile(e, t, n, r, i) {
|
|
44640
|
-
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;
|
|
44641
44748
|
for (let e = 0; e < i; e++) for (let i = 0; i < r; i++) {
|
|
44642
|
-
let
|
|
44643
|
-
|
|
44644
|
-
let e = this._hdrToneMapFn, t = this._hdrExposure, n = this._hdrSaturation, r = a[u] * t, i = a[u + 1] * t, o = a[u + 2] * t;
|
|
44645
|
-
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);
|
|
44646
|
-
let s = this._hdrEncode;
|
|
44647
|
-
l[d] = s(this._tmOut[0]), l[c + d] = s(this._tmOut[1]), l[2 * c + d] = s(this._tmOut[2]);
|
|
44648
|
-
} 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;
|
|
44649
44751
|
}
|
|
44650
|
-
return
|
|
44752
|
+
return s;
|
|
44651
44753
|
}
|
|
44652
44754
|
async _inferTile(e, t, n) {
|
|
44653
44755
|
let r = ++this._tileId;
|
|
@@ -44673,41 +44775,41 @@ var Gk = {
|
|
|
44673
44775
|
return a;
|
|
44674
44776
|
}
|
|
44675
44777
|
_cacheUpscaledAlpha(e, t, n) {
|
|
44676
|
-
let {
|
|
44677
|
-
for (let e =
|
|
44678
|
-
|
|
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;
|
|
44679
44781
|
break;
|
|
44680
44782
|
}
|
|
44681
|
-
if (!
|
|
44783
|
+
if (!d) {
|
|
44682
44784
|
this._upscaledAlpha = null, this._upscaledAlphaWidth = 0;
|
|
44683
44785
|
return;
|
|
44684
44786
|
}
|
|
44685
|
-
let l = document.createElement("canvas");
|
|
44686
|
-
l.width = i, l.height = a;
|
|
44687
|
-
let u = l.getContext("2d"), d = u.createImageData(i, a);
|
|
44688
|
-
for (let e = 0, t = i * a; e < t; e++) {
|
|
44689
|
-
let t = o ? Math.min(Math.max(r[e * 4 + 3] * 255, 0), 255) | 0 : r[e * 4 + 3];
|
|
44690
|
-
d.data[e * 4] = t, d.data[e * 4 + 1] = t, d.data[e * 4 + 2] = t, d.data[e * 4 + 3] = 255;
|
|
44691
|
-
}
|
|
44692
|
-
u.putImageData(d, 0, 0);
|
|
44693
44787
|
let f = document.createElement("canvas");
|
|
44694
|
-
f.width =
|
|
44695
|
-
let p = f.getContext("2d");
|
|
44696
|
-
|
|
44697
|
-
|
|
44698
|
-
|
|
44699
|
-
|
|
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;
|
|
44700
44802
|
}
|
|
44701
44803
|
_createBackup(e) {
|
|
44702
44804
|
this._backupCanvas = document.createElement("canvas"), this._backupCanvas.width = e.width, this._backupCanvas.height = e.height;
|
|
44703
44805
|
let t = this._backupCanvas.getContext("2d");
|
|
44704
44806
|
if (e.isHDR) {
|
|
44705
|
-
let {
|
|
44706
|
-
for (let e = 0
|
|
44707
|
-
let t = e * 4
|
|
44708
|
-
|
|
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;
|
|
44709
44811
|
}
|
|
44710
|
-
t.putImageData(
|
|
44812
|
+
t.putImageData(o, 0, 0);
|
|
44711
44813
|
} else t.putImageData(e, 0, 0);
|
|
44712
44814
|
}
|
|
44713
44815
|
_restoreBackup() {
|
|
@@ -44717,7 +44819,7 @@ var Gk = {
|
|
|
44717
44819
|
this.hdr = !!e;
|
|
44718
44820
|
}
|
|
44719
44821
|
setQuality(e) {
|
|
44720
|
-
if (!
|
|
44822
|
+
if (!Kk.QUALITY_PRESETS[e]) {
|
|
44721
44823
|
console.warn(`AIUpscaler: Invalid quality "${e}", must be fast/balanced/quality`);
|
|
44722
44824
|
return;
|
|
44723
44825
|
}
|
|
@@ -44738,9 +44840,9 @@ var Gk = {
|
|
|
44738
44840
|
this._pendingWorkerHandlers.clear();
|
|
44739
44841
|
}
|
|
44740
44842
|
async dispose() {
|
|
44741
|
-
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");
|
|
44742
44844
|
}
|
|
44743
|
-
},
|
|
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 {
|
|
44744
44846
|
constructor({ renderer: e, mainCanvas: t, stages: n, pipeline: r, getExposure: i, getSaturation: a, issues: o = null }) {
|
|
44745
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 = {
|
|
44746
44848
|
world: null,
|
|
@@ -44773,7 +44875,7 @@ var Gk = {
|
|
|
44773
44875
|
}
|
|
44774
44876
|
setupDenoiser() {
|
|
44775
44877
|
let t = this._stages.pathTracer;
|
|
44776
|
-
this.denoiser = new
|
|
44878
|
+
this.denoiser = new wk(this.renderer, {
|
|
44777
44879
|
...Q,
|
|
44778
44880
|
backendParams: () => ({
|
|
44779
44881
|
device: this.renderer.backend.device,
|
|
@@ -44812,7 +44914,7 @@ var Gk = {
|
|
|
44812
44914
|
setupUpscaler() {
|
|
44813
44915
|
if (!this.upscalerCanvas) return;
|
|
44814
44916
|
let t = this._stages.pathTracer;
|
|
44815
|
-
this.upscaler = new
|
|
44917
|
+
this.upscaler = new qk(this.upscalerCanvas, this.renderer, {
|
|
44816
44918
|
scaleFactor: Q.upscalerScale || 2,
|
|
44817
44919
|
quality: Q.upscalerQuality || "fast",
|
|
44818
44920
|
getSourceCanvas: () => this.renderer.domElement,
|
|
@@ -44888,8 +44990,8 @@ var Gk = {
|
|
|
44888
44990
|
get holdsWhileMoving() {
|
|
44889
44991
|
if (!this._stages.pathTracer?.viewIsChanging || !this.continuousDenoise || this._cadenceSuspended || !this.denoiser?.enabled || this._movingHopeless) return !1;
|
|
44890
44992
|
let e = this.movingCostMs, t = this._movingDenoiseMs.length;
|
|
44891
|
-
e >
|
|
44892
|
-
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);
|
|
44893
44995
|
return this._holdWhileMoving = (this._holdWhileMoving === null || this._holdWhileMoving) && n, this._holdWhileMoving;
|
|
44894
44996
|
}
|
|
44895
44997
|
skipsTrace() {
|
|
@@ -44906,7 +45008,7 @@ var Gk = {
|
|
|
44906
45008
|
this.pipeline?.context?.removeTexture("oidn:output"), this.denoiser?.invalidateOutput();
|
|
44907
45009
|
}
|
|
44908
45010
|
_checkHeldFrameHealthy() {
|
|
44909
|
-
!this.denoiser?.hasOutput || this._failedRefreshes <
|
|
45011
|
+
!this.denoiser?.hasOutput || this._failedRefreshes < nA || this._unpublishOutput();
|
|
44910
45012
|
}
|
|
44911
45013
|
tickContinuousDenoise(e) {
|
|
44912
45014
|
let t = this.denoiser;
|
|
@@ -44916,12 +45018,12 @@ var Gk = {
|
|
|
44916
45018
|
if (!n) this._holdWhileMoving = null, this._movingDenoiseMs.length = 0;
|
|
44917
45019
|
else if (!this.holdsWhileMoving) return !1;
|
|
44918
45020
|
if (t.state.isDenoising || t.state.isLoading || !n && e <= this._lastCadenceSamples) return !1;
|
|
44919
|
-
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);
|
|
44920
45022
|
if (r - this._lastCadenceAt < a) return !1;
|
|
44921
|
-
this._lastCadenceAt = r, this._lastCadenceSamples = e, t.lastDenoiseMs >
|
|
45023
|
+
this._lastCadenceAt = r, this._lastCadenceSamples = e, t.lastDenoiseMs > Yk && (this._cadenceDowngraded = !0);
|
|
44922
45024
|
let o = this._cadenceDowngraded ? this.previewQuality() : this._finalQuality;
|
|
44923
45025
|
return t.quality !== o && t.updateQuality(o), t.start({ continuous: !0 }).then((e) => {
|
|
44924
|
-
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());
|
|
44925
45027
|
}), !0;
|
|
44926
45028
|
}
|
|
44927
45029
|
previewQuality() {
|
|
@@ -44963,7 +45065,7 @@ var Gk = {
|
|
|
44963
45065
|
r && (this._ensureHistory().merge(r, t.frameCount, this._historyCameraNow(), {
|
|
44964
45066
|
commit: !0,
|
|
44965
45067
|
keepHistory: !this._historyDirty && !n,
|
|
44966
|
-
historyScale:
|
|
45068
|
+
historyScale: iA(t.frameCount)
|
|
44967
45069
|
}), this._historyDirty = !1);
|
|
44968
45070
|
}
|
|
44969
45071
|
afterReset() {
|
|
@@ -45006,9 +45108,9 @@ var Gk = {
|
|
|
45006
45108
|
let e = this._stages.pathTracer, t = this._history;
|
|
45007
45109
|
if (!t?.valid || this._historyDirty || !this.historyActive || e.isComplete || e.resetCount !== this._knownResetCount || t.width !== this._lastRenderWidth || t.height !== this._lastRenderHeight) return null;
|
|
45008
45110
|
if (e.frameCount <= 1) return t.textures;
|
|
45009
|
-
if (e.frameCount >=
|
|
45111
|
+
if (e.frameCount >= rA) return null;
|
|
45010
45112
|
let n = this._historyInputs();
|
|
45011
|
-
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;
|
|
45012
45114
|
}
|
|
45013
45115
|
_historyInputs() {
|
|
45014
45116
|
let e = this._stages.pathTracer, t = this.pipeline?.context, n = this.renderer?.backend;
|
|
@@ -45033,7 +45135,7 @@ var Gk = {
|
|
|
45033
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;
|
|
45034
45136
|
}
|
|
45035
45137
|
_ensureHistory() {
|
|
45036
|
-
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;
|
|
45037
45139
|
}
|
|
45038
45140
|
_releaseHistory() {
|
|
45039
45141
|
this._history?.dispose(), this._history = null, this._historyDirty = !0, this._movedPlacements.clear();
|
|
@@ -45070,15 +45172,15 @@ var Gk = {
|
|
|
45070
45172
|
return;
|
|
45071
45173
|
}
|
|
45072
45174
|
if (!this.pipeline?.context?.getTexture("oidn:output")) {
|
|
45073
|
-
|
|
45175
|
+
Jk.warn("neural pass skipped: no denoised picture — it needs OIDN");
|
|
45074
45176
|
return;
|
|
45075
45177
|
}
|
|
45076
45178
|
this._neuralPostBusy = !0, this.dispatchEvent({ type: e.UPSCALING_START });
|
|
45077
45179
|
try {
|
|
45078
|
-
let i = await import("./NeuralSuperRes-
|
|
45180
|
+
let i = await import("./NeuralSuperRes-FVqRJKQV.js").then((e) => e.t);
|
|
45079
45181
|
this._superResModule = i;
|
|
45080
|
-
let a = r ? await import("./NeuralRetouch-
|
|
45081
|
-
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;
|
|
45082
45184
|
let l = {
|
|
45083
45185
|
exposure: this._getEffectiveExposure(),
|
|
45084
45186
|
toneMapping: this._getToneMapping(),
|
|
@@ -45113,7 +45215,7 @@ var Gk = {
|
|
|
45113
45215
|
height: d.height
|
|
45114
45216
|
});
|
|
45115
45217
|
} catch (e) {
|
|
45116
|
-
|
|
45218
|
+
Jk.warn("neural pass failed", e);
|
|
45117
45219
|
} finally {
|
|
45118
45220
|
this._neuralPostBusy = !1, this.dispatchEvent({ type: e.UPSCALING_END });
|
|
45119
45221
|
}
|
|
@@ -45279,7 +45381,7 @@ var Gk = {
|
|
|
45279
45381
|
let t = Ci[e];
|
|
45280
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));
|
|
45281
45383
|
}
|
|
45282
|
-
},
|
|
45384
|
+
}, oA = class {
|
|
45283
45385
|
constructor() {
|
|
45284
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;
|
|
45285
45387
|
}
|
|
@@ -45303,7 +45405,7 @@ var Gk = {
|
|
|
45303
45405
|
dispose() {
|
|
45304
45406
|
this.visible = !1;
|
|
45305
45407
|
}
|
|
45306
|
-
},
|
|
45408
|
+
}, sA = class {
|
|
45307
45409
|
constructor(e, t) {
|
|
45308
45410
|
this.layer = "scene", this._enabled = !0, this._scene = e, this._camera = t, this._build([]);
|
|
45309
45411
|
}
|
|
@@ -45341,11 +45443,11 @@ var Gk = {
|
|
|
45341
45443
|
this._enabled = !1, this._outlineNode?.dispose(), this._material?.dispose(), this._quad = null;
|
|
45342
45444
|
}
|
|
45343
45445
|
};
|
|
45344
|
-
function
|
|
45446
|
+
function cA(e = !1) {
|
|
45345
45447
|
let t = document.createElement("canvas");
|
|
45346
45448
|
return t.style.cssText = "position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;" + (e ? "display:none;" : ""), t;
|
|
45347
45449
|
}
|
|
45348
|
-
function
|
|
45450
|
+
function lA(e, t = Infinity) {
|
|
45349
45451
|
let n = e?.getBoundingClientRect();
|
|
45350
45452
|
if (!n || n.width === 0 || n.height === 0) return null;
|
|
45351
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);
|
|
@@ -45356,9 +45458,9 @@ function cA(e, t = Infinity) {
|
|
|
45356
45458
|
}
|
|
45357
45459
|
//#endregion
|
|
45358
45460
|
//#region src/managers/helpers/ViewOverlayRenderer.js
|
|
45359
|
-
var
|
|
45461
|
+
var uA = 4096, dA = class {
|
|
45360
45462
|
constructor() {
|
|
45361
|
-
this.canvas =
|
|
45463
|
+
this.canvas = cA(!0), this._visible = !1, this.renderer = null, this._sizeSource = null;
|
|
45362
45464
|
}
|
|
45363
45465
|
async init({ device: e, sizeSource: t }) {
|
|
45364
45466
|
this._sizeSource = t;
|
|
@@ -45375,7 +45477,7 @@ var lA = 4096, uA = class {
|
|
|
45375
45477
|
}
|
|
45376
45478
|
syncSize() {
|
|
45377
45479
|
if (!this.renderer) return;
|
|
45378
|
-
let e =
|
|
45480
|
+
let e = lA(this._sizeSource, uA);
|
|
45379
45481
|
!e || e.width === this.canvas.width && e.height === this.canvas.height || this.renderer.setSize(e.width, e.height, !1);
|
|
45380
45482
|
}
|
|
45381
45483
|
begin() {
|
|
@@ -45387,18 +45489,18 @@ var lA = 4096, uA = class {
|
|
|
45387
45489
|
dispose() {
|
|
45388
45490
|
ei(this.renderer), this.renderer = null, this.canvas.parentElement?.removeChild(this.canvas);
|
|
45389
45491
|
}
|
|
45390
|
-
},
|
|
45492
|
+
}, fA = a("overlay"), pA = (e, t) => e.visible && e.layer === t && e.render, mA = class {
|
|
45391
45493
|
constructor(e) {
|
|
45392
|
-
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;
|
|
45393
45495
|
}
|
|
45394
45496
|
async initViewRenderer({ device: e, sizeSource: t }) {
|
|
45395
45497
|
if (!(!e || !t)) try {
|
|
45396
|
-
this._viewOverlay = await new
|
|
45498
|
+
this._viewOverlay = await new dA().init({
|
|
45397
45499
|
device: e,
|
|
45398
45500
|
sizeSource: t
|
|
45399
45501
|
});
|
|
45400
45502
|
} catch (e) {
|
|
45401
|
-
|
|
45503
|
+
fA.error("overlay surface unavailable — light gizmos, transform gizmo and outlines are disabled", e), this._viewOverlay = null;
|
|
45402
45504
|
}
|
|
45403
45505
|
}
|
|
45404
45506
|
gpuResources() {
|
|
@@ -45418,11 +45520,11 @@ var lA = 4096, uA = class {
|
|
|
45418
45520
|
}
|
|
45419
45521
|
setupDefaultHelpers({ helperScene: t, meshScene: n, pipeline: r, denoisingManager: i, app: a, renderWidth: o, renderHeight: s }) {
|
|
45420
45522
|
this.setHelperScene(t);
|
|
45421
|
-
let c = new
|
|
45523
|
+
let c = new oA();
|
|
45422
45524
|
this.register("tiles", c), c.setRenderSize(o || 1, s || 1), a.addEventListener(e.RESOLUTION_CHANGED, (e) => {
|
|
45423
45525
|
c.setRenderSize(e.width, e.height);
|
|
45424
45526
|
}), r.eventBus.on("pipeline:reset", () => c.hide()), this._wireDenoiserTileEvents(c, i);
|
|
45425
|
-
let l = new
|
|
45527
|
+
let l = new sA(n, this.camera);
|
|
45426
45528
|
this.register("outline", l);
|
|
45427
45529
|
}
|
|
45428
45530
|
_wireDenoiserTileEvents(e, t) {
|
|
@@ -45434,7 +45536,7 @@ var lA = 4096, uA = class {
|
|
|
45434
45536
|
}));
|
|
45435
45537
|
}
|
|
45436
45538
|
register(e, t) {
|
|
45437
|
-
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);
|
|
45438
45540
|
}
|
|
45439
45541
|
unregister(e) {
|
|
45440
45542
|
let t = this._helpers.get(e);
|
|
@@ -45472,16 +45574,16 @@ var lA = 4096, uA = class {
|
|
|
45472
45574
|
}
|
|
45473
45575
|
_renderSceneLayer(e) {
|
|
45474
45576
|
this._helperScene?.render(e, this.camera);
|
|
45475
|
-
for (let t of this._helpers.values())
|
|
45577
|
+
for (let t of this._helpers.values()) pA(t, "scene") && t.render(e, this.camera);
|
|
45476
45578
|
}
|
|
45477
45579
|
_hasVisibleSceneOverlay() {
|
|
45478
45580
|
if (this._helperScene?.isDrawing) return !0;
|
|
45479
|
-
for (let e of this._helpers.values()) if (
|
|
45581
|
+
for (let e of this._helpers.values()) if (pA(e, "scene")) return !0;
|
|
45480
45582
|
return !1;
|
|
45481
45583
|
}
|
|
45482
45584
|
refreshHUD() {
|
|
45483
45585
|
let e = this._hudCanvas, t = this._hudCtx, n = !1;
|
|
45484
|
-
for (let e of this._helpers.values()) if (
|
|
45586
|
+
for (let e of this._helpers.values()) if (pA(e, "hud")) {
|
|
45485
45587
|
n = !0;
|
|
45486
45588
|
break;
|
|
45487
45589
|
}
|
|
@@ -45490,10 +45592,10 @@ var lA = 4096, uA = class {
|
|
|
45490
45592
|
return;
|
|
45491
45593
|
}
|
|
45492
45594
|
e.style.display !== "" && (e.style.display = "");
|
|
45493
|
-
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;
|
|
45494
45596
|
if (a) {
|
|
45495
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);
|
|
45496
|
-
for (let e of this._helpers.values())
|
|
45598
|
+
for (let e of this._helpers.values()) pA(e, "hud") && e.render(t, r, i);
|
|
45497
45599
|
t.restore(), e.style.display !== "" && (e.style.display = "");
|
|
45498
45600
|
}
|
|
45499
45601
|
}
|
|
@@ -45501,9 +45603,21 @@ var lA = 4096, uA = class {
|
|
|
45501
45603
|
for (let e of this._helpers.values()) e.dispose?.();
|
|
45502
45604
|
this._helpers.clear(), this._viewOverlay?.dispose(), this._viewOverlay = null, this._hudCanvas.parentElement && this._hudCanvas.parentElement.removeChild(this._hudCanvas);
|
|
45503
45605
|
}
|
|
45504
|
-
}
|
|
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 {
|
|
45505
45619
|
constructor() {
|
|
45506
|
-
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.wakeCallback = null, this.applyPoseCallback = null;
|
|
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;
|
|
45507
45621
|
}
|
|
45508
45622
|
init(e, t, n, r) {
|
|
45509
45623
|
if (this.dispose(), !r || r.length === 0) return;
|
|
@@ -45525,7 +45639,7 @@ var lA = 4096, uA = class {
|
|
|
45525
45639
|
indices: r
|
|
45526
45640
|
}), o += i;
|
|
45527
45641
|
}
|
|
45528
|
-
this._skinnedCache = [], this._meshPositions = [];
|
|
45642
|
+
this._skinnedCache = [], this._meshPositions = [], this._lastMeshWorld = this._rigid ? null : new Float64Array(n.length * 16).fill(NaN), this._lastMorphWeights = [];
|
|
45529
45643
|
let s = n.filter((e) => e.isSkinnedMesh).length;
|
|
45530
45644
|
console.debug(`[AnimationManager] Init: ${r.length} clips, ${n.length} meshes (${s} skinned), ${o} triangles, ${this._rigid ? "rigid" : "deforming"}`);
|
|
45531
45645
|
}
|
|
@@ -45534,22 +45648,28 @@ var lA = 4096, uA = class {
|
|
|
45534
45648
|
if (t.traverse?.((e) => {
|
|
45535
45649
|
n.has(e.name) || n.set(e.name, e), n.set(e.uuid, e);
|
|
45536
45650
|
}), this._plans = e.map((e) => {
|
|
45537
|
-
let
|
|
45538
|
-
for (let
|
|
45539
|
-
let { nodeName: e, propertyName:
|
|
45540
|
-
|
|
45541
|
-
|
|
45542
|
-
|
|
45543
|
-
|
|
45544
|
-
|
|
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);
|
|
45545
45663
|
break;
|
|
45546
45664
|
}
|
|
45547
|
-
let
|
|
45548
|
-
for (let e of
|
|
45665
|
+
let s = /* @__PURE__ */ new Set();
|
|
45666
|
+
for (let e of r) e.traverse((e) => e.isCamera && s.add(e));
|
|
45549
45667
|
return {
|
|
45550
|
-
meshes: Int32Array.from(
|
|
45551
|
-
visibility:
|
|
45552
|
-
cameras: [...
|
|
45668
|
+
meshes: Int32Array.from(o),
|
|
45669
|
+
visibility: i,
|
|
45670
|
+
cameras: [...s],
|
|
45671
|
+
nodes: a ? null : r,
|
|
45672
|
+
roots: a ? null : hA(r, t)
|
|
45553
45673
|
};
|
|
45554
45674
|
}), this._allPlan = null, !this._rigid) return;
|
|
45555
45675
|
this._slotOf = new Int32Array(this._meshes.length).fill(-1);
|
|
@@ -45561,12 +45681,14 @@ var lA = 4096, uA = class {
|
|
|
45561
45681
|
if (!this._plans) return null;
|
|
45562
45682
|
if (e >= 0) return this._plans[e] ?? null;
|
|
45563
45683
|
if (!this._allPlan) {
|
|
45564
|
-
let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = !1;
|
|
45565
|
-
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;
|
|
45566
45686
|
this._allPlan = {
|
|
45567
45687
|
meshes: Int32Array.from(e),
|
|
45568
45688
|
visibility: n,
|
|
45569
|
-
cameras: [...t]
|
|
45689
|
+
cameras: [...t],
|
|
45690
|
+
nodes: r,
|
|
45691
|
+
roots: r ? hA(r, this._mixerRoot) : null
|
|
45570
45692
|
};
|
|
45571
45693
|
}
|
|
45572
45694
|
return this._allPlan;
|
|
@@ -45642,13 +45764,32 @@ var lA = 4096, uA = class {
|
|
|
45642
45764
|
return r && r.length === n ? r : e[t] = new Float32Array(n);
|
|
45643
45765
|
}
|
|
45644
45766
|
_poseReader() {
|
|
45645
|
-
|
|
45646
|
-
let e
|
|
45647
|
-
|
|
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?.({
|
|
45648
45773
|
meshIndices: [],
|
|
45649
45774
|
visibilityChanged: !1,
|
|
45650
|
-
cameras:
|
|
45651
|
-
})
|
|
45775
|
+
cameras: t
|
|
45776
|
+
});
|
|
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);
|
|
45779
|
+
}
|
|
45780
|
+
_poseChanged(e) {
|
|
45781
|
+
let t = this._meshes[e], n = this._lastMeshWorld, r = t.matrixWorld.elements, i = e * 16, a = !1;
|
|
45782
|
+
for (let e = 0; e < 16; e++) if (n[i + e] !== r[e]) {
|
|
45783
|
+
for (let e = 0; e < 16; e++) n[i + e] = r[e];
|
|
45784
|
+
a = !0;
|
|
45785
|
+
break;
|
|
45786
|
+
}
|
|
45787
|
+
let o = t.morphTargetInfluences;
|
|
45788
|
+
if (o?.length) {
|
|
45789
|
+
let t = this._lastMorphWeights[e];
|
|
45790
|
+
(!t || t.length !== o.length || t.some((e, t) => e !== o[t])) && (this._lastMorphWeights[e] = Float64Array.from(o), a = !0);
|
|
45791
|
+
}
|
|
45792
|
+
return a;
|
|
45652
45793
|
}
|
|
45653
45794
|
_computeMeshPositions(e) {
|
|
45654
45795
|
let t = this._tempVec, n = this._meshes[e], { count: r, uniqueVerts: i, indices: a } = this._meshTriRanges[e], o = this._scratch(this._skinnedCache, e, i * 3), s = this._scratch(this._meshPositions, e, r * 9), c = n.matrixWorld;
|
|
@@ -45677,21 +45818,21 @@ var lA = 4096, uA = class {
|
|
|
45677
45818
|
}), this._clipsCache;
|
|
45678
45819
|
}
|
|
45679
45820
|
dispose() {
|
|
45680
|
-
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;
|
|
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;
|
|
45681
45822
|
}
|
|
45682
|
-
},
|
|
45823
|
+
}, _A = new ur(0, 0, -1), vA = (e) => {
|
|
45683
45824
|
for (; e.parent;) e = e.parent;
|
|
45684
45825
|
return e.isScene ? e : null;
|
|
45685
|
-
},
|
|
45826
|
+
}, yA = class {
|
|
45686
45827
|
constructor({ camera: e, canvas: t, orbitControls: n, app: r }) {
|
|
45687
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);
|
|
45688
45829
|
}
|
|
45689
45830
|
setMeshData(e) {
|
|
45690
45831
|
this._meshes = e;
|
|
45691
|
-
for (let e of this._moved)
|
|
45832
|
+
for (let e of this._moved) vA(e) || this._moved.delete(e);
|
|
45692
45833
|
}
|
|
45693
45834
|
get movedObjects() {
|
|
45694
|
-
return [...this._moved].filter((e) =>
|
|
45835
|
+
return [...this._moved].filter((e) => vA(e));
|
|
45695
45836
|
}
|
|
45696
45837
|
noteMoved(e) {
|
|
45697
45838
|
e && !e.isLight && this._moved.add(e);
|
|
@@ -45752,7 +45893,7 @@ var lA = 4096, uA = class {
|
|
|
45752
45893
|
}
|
|
45753
45894
|
_syncLightAim(e) {
|
|
45754
45895
|
let t = this._tempForward.copy(e.target.position).sub(e.position), n = t.length();
|
|
45755
|
-
n > 1e-4 ? (e.quaternion.setFromUnitVectors(
|
|
45896
|
+
n > 1e-4 ? (e.quaternion.setFromUnitVectors(_A, t.normalize()), this._lightTargetDistance = n) : this._lightTargetDistance = 1;
|
|
45756
45897
|
}
|
|
45757
45898
|
_recomputeAndRefit() {
|
|
45758
45899
|
if (!this._meshes || this._refitInFlight || !this._attached) return;
|
|
@@ -45788,7 +45929,7 @@ var lA = 4096, uA = class {
|
|
|
45788
45929
|
dispose() {
|
|
45789
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;
|
|
45790
45931
|
}
|
|
45791
|
-
},
|
|
45932
|
+
}, bA = class {
|
|
45792
45933
|
constructor(e) {
|
|
45793
45934
|
this.layer = "scene", this._transformManager = e, this._enabled = !0;
|
|
45794
45935
|
}
|
|
@@ -45807,8 +45948,8 @@ var lA = 4096, uA = class {
|
|
|
45807
45948
|
dispose() {
|
|
45808
45949
|
this._enabled = !1;
|
|
45809
45950
|
}
|
|
45810
|
-
},
|
|
45811
|
-
function
|
|
45951
|
+
}, xA = 1, SA = (e) => typeof e == "string" && /^https?:\/\//.test(e);
|
|
45952
|
+
function CA(e, t) {
|
|
45812
45953
|
let n = [];
|
|
45813
45954
|
for (; e && e !== t;) {
|
|
45814
45955
|
let t = e.parent;
|
|
@@ -45817,12 +45958,12 @@ function xA(e, t) {
|
|
|
45817
45958
|
}
|
|
45818
45959
|
return e === t ? n : null;
|
|
45819
45960
|
}
|
|
45820
|
-
function
|
|
45961
|
+
function wA(e, t) {
|
|
45821
45962
|
let n = e;
|
|
45822
45963
|
for (let e of t) if (n = n?.children[e], !n) return null;
|
|
45823
45964
|
return n;
|
|
45824
45965
|
}
|
|
45825
|
-
function
|
|
45966
|
+
function TA(e) {
|
|
45826
45967
|
return {
|
|
45827
45968
|
key: e.assetLoader?.sceneSourceKey ?? null,
|
|
45828
45969
|
name: e.sceneModel?.name ?? null,
|
|
@@ -45830,7 +45971,7 @@ function CA(e) {
|
|
|
45830
45971
|
materials: e.stages.pathTracer?.materialData.materialCount ?? 0
|
|
45831
45972
|
};
|
|
45832
45973
|
}
|
|
45833
|
-
function
|
|
45974
|
+
function EA(e) {
|
|
45834
45975
|
let t = /* @__PURE__ */ new Map();
|
|
45835
45976
|
for (let n of e.sceneMeshes) {
|
|
45836
45977
|
let e = n.userData?.materialIndex;
|
|
@@ -45838,7 +45979,7 @@ function wA(e) {
|
|
|
45838
45979
|
}
|
|
45839
45980
|
return t;
|
|
45840
45981
|
}
|
|
45841
|
-
function
|
|
45982
|
+
function DA(e) {
|
|
45842
45983
|
if (!e) return null;
|
|
45843
45984
|
let t = e.status(), n = t.activeView, r = t.config?.id ?? n?.configId ?? null;
|
|
45844
45985
|
return {
|
|
@@ -45853,15 +45994,15 @@ function TA(e) {
|
|
|
45853
45994
|
context: t.context ?? null
|
|
45854
45995
|
};
|
|
45855
45996
|
}
|
|
45856
|
-
function
|
|
45857
|
-
let t = e.meshScene, n =
|
|
45997
|
+
function OA(e) {
|
|
45998
|
+
let t = e.meshScene, n = EA(e), r = [];
|
|
45858
45999
|
return t.traverse((e) => {
|
|
45859
|
-
e !== t && e.visible === !1 && r.push(
|
|
46000
|
+
e !== t && e.visible === !1 && r.push(CA(e, t));
|
|
45860
46001
|
}), {
|
|
45861
46002
|
v: 1,
|
|
45862
46003
|
engine: Hv,
|
|
45863
46004
|
savedAt: Date.now(),
|
|
45864
|
-
scene:
|
|
46005
|
+
scene: TA(e),
|
|
45865
46006
|
appended: t.children.filter((t) => t !== e.sceneModel && t.userData?.__rayzeeSceneObject).map((e) => ({
|
|
45866
46007
|
name: e.userData.__rayzeeName ?? e.name,
|
|
45867
46008
|
url: e.userData.__rayzeeSourceUrl ?? null,
|
|
@@ -45869,7 +46010,7 @@ function EA(e) {
|
|
|
45869
46010
|
})),
|
|
45870
46011
|
settings: e.settings.serialize(),
|
|
45871
46012
|
environment: e.environmentManager?.serialize() ?? null,
|
|
45872
|
-
color:
|
|
46013
|
+
color: DA(e.color),
|
|
45873
46014
|
lights: e.lightManager.serialize(),
|
|
45874
46015
|
cameras: e.cameraManager.serialize(),
|
|
45875
46016
|
timeline: e.timeline?.serialize() ?? null,
|
|
@@ -45879,7 +46020,7 @@ function EA(e) {
|
|
|
45879
46020
|
})),
|
|
45880
46021
|
hidden: r,
|
|
45881
46022
|
moved: (e.transformManager?.movedObjects ?? []).map((e) => ({
|
|
45882
|
-
path:
|
|
46023
|
+
path: CA(e, t),
|
|
45883
46024
|
name: e.name,
|
|
45884
46025
|
position: e.position.toArray(),
|
|
45885
46026
|
quaternion: e.quaternion.toArray(),
|
|
@@ -45887,15 +46028,15 @@ function EA(e) {
|
|
|
45887
46028
|
})).filter((e) => e.path)
|
|
45888
46029
|
};
|
|
45889
46030
|
}
|
|
45890
|
-
function
|
|
46031
|
+
function kA(e, t, n) {
|
|
45891
46032
|
let r = e[t];
|
|
45892
46033
|
r?.copy && (n?.isColor || n?.isVector2 || n?.isVector3) ? r.copy(n) : e[t] = n, e.needsUpdate = !0;
|
|
45893
46034
|
}
|
|
45894
|
-
async function
|
|
46035
|
+
async function AA(e, t, n, r) {
|
|
45895
46036
|
if (!t) return;
|
|
45896
46037
|
let i = e.environmentManager;
|
|
45897
46038
|
if (t.hdri && t.hdri !== i.hdriSource) {
|
|
45898
|
-
let i =
|
|
46039
|
+
let i = SA(t.hdri) ? t.hdri : await n({
|
|
45899
46040
|
kind: "environment",
|
|
45900
46041
|
source: t.hdri
|
|
45901
46042
|
});
|
|
@@ -45907,7 +46048,7 @@ async function OA(e, t, n, r) {
|
|
|
45907
46048
|
}
|
|
45908
46049
|
await i.restore(t);
|
|
45909
46050
|
}
|
|
45910
|
-
async function
|
|
46051
|
+
async function jA(e, t, n, r) {
|
|
45911
46052
|
let i = e.color;
|
|
45912
46053
|
if (!t || !i) return;
|
|
45913
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;
|
|
@@ -45932,7 +46073,7 @@ async function kA(e, t, n, r) {
|
|
|
45932
46073
|
r("color", e.message, { config: t.config?.id ?? null });
|
|
45933
46074
|
}
|
|
45934
46075
|
}
|
|
45935
|
-
async function
|
|
46076
|
+
async function MA(e, t, { resolve: n = async () => null } = {}) {
|
|
45936
46077
|
if (t?.v !== 1) throw Error(`scene state version ${t?.v} is not 1`);
|
|
45937
46078
|
let r = [], i = (e, t, n = {}) => r.push({
|
|
45938
46079
|
section: e,
|
|
@@ -45953,11 +46094,11 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
|
|
|
45953
46094
|
i("appended", e.message, { name: n.name });
|
|
45954
46095
|
}
|
|
45955
46096
|
}
|
|
45956
|
-
let a =
|
|
46097
|
+
let a = TA(e), o = t.scene ?? {}, s = o.meshes === a.meshes && o.materials === a.materials;
|
|
45957
46098
|
s || i("scene", "the loaded scene is not the one saved: objects and materials left as loaded", {
|
|
45958
46099
|
saved: o,
|
|
45959
46100
|
now: a
|
|
45960
|
-
}), await
|
|
46101
|
+
}), await AA(e, t.environment, n, i), await jA(e, t.color, n, i);
|
|
45961
46102
|
let c = e.settings.restore(t.settings);
|
|
45962
46103
|
c.length && i("settings", "not settings in this engine", { keys: c });
|
|
45963
46104
|
let l = e.lightManager.restore(t.lights);
|
|
@@ -45966,7 +46107,7 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
|
|
|
45966
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 });
|
|
45967
46108
|
}
|
|
45968
46109
|
if (s) {
|
|
45969
|
-
let n =
|
|
46110
|
+
let n = EA(e);
|
|
45970
46111
|
for (let r of t.materials ?? []) {
|
|
45971
46112
|
let t = n.get(r.index);
|
|
45972
46113
|
if (!t || (t.name ?? "") !== r.name) {
|
|
@@ -45978,16 +46119,16 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
|
|
|
45978
46119
|
}
|
|
45979
46120
|
for (let [n, i] of Object.entries(r.props)) {
|
|
45980
46121
|
let a = ys(i);
|
|
45981
|
-
|
|
46122
|
+
kA(t, n, a), e.setMaterialProperty(r.index, n, a);
|
|
45982
46123
|
}
|
|
45983
46124
|
}
|
|
45984
|
-
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));
|
|
45985
46126
|
r.traverse((e) => {
|
|
45986
46127
|
e !== r && !e.isLight && (e.visible = !a.has(e));
|
|
45987
46128
|
}), e.updateAllMeshVisibility();
|
|
45988
46129
|
let o = [];
|
|
45989
46130
|
for (let n of t.moved ?? []) {
|
|
45990
|
-
let t =
|
|
46131
|
+
let t = wA(r, n.path);
|
|
45991
46132
|
if (!t || t.name !== n.name) {
|
|
45992
46133
|
i("moved", "no such object", { name: n.name });
|
|
45993
46134
|
continue;
|
|
@@ -46007,11 +46148,11 @@ async function AA(e, t, { resolve: n = async () => null } = {}) {
|
|
|
46007
46148
|
let { mismatched: u } = e.cameraManager.restore(t.cameras);
|
|
46008
46149
|
return u.length && i("cameras", "model cameras changed", { names: u }), e._dispatchCamerasUpdated(), e.timeline?.restore(t.timeline), e.reset(), { skipped: r };
|
|
46009
46150
|
}
|
|
46010
|
-
var
|
|
46151
|
+
var NA = ({ element: e, pbrtEntry: t } = {}) => ({
|
|
46011
46152
|
...e === void 0 ? {} : { element: e },
|
|
46012
46153
|
...t === void 0 ? {} : { pbrtEntry: t }
|
|
46013
|
-
}),
|
|
46014
|
-
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) {
|
|
46015
46156
|
if (!t || typeof self < "u") return e.init();
|
|
46016
46157
|
globalThis.self = {
|
|
46017
46158
|
requestAnimationFrame: () => 0,
|
|
@@ -46023,32 +46164,32 @@ async function FA(e, t) {
|
|
|
46023
46164
|
delete globalThis.self;
|
|
46024
46165
|
}
|
|
46025
46166
|
}
|
|
46026
|
-
var
|
|
46027
|
-
function
|
|
46167
|
+
var RA = a("engine");
|
|
46168
|
+
function zA(e, t) {
|
|
46028
46169
|
e.lost.then((e) => {
|
|
46029
46170
|
t.app && t.app._handleDeviceLost(e);
|
|
46030
46171
|
});
|
|
46031
46172
|
}
|
|
46032
|
-
var
|
|
46033
|
-
function
|
|
46173
|
+
var BA = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
|
|
46174
|
+
function VA(e) {
|
|
46034
46175
|
let t = e.info ?? {}, n = `${t.vendor ?? ""} ${t.architecture ?? ""} ${t.device ?? ""} ${t.description ?? ""}`;
|
|
46035
46176
|
return {
|
|
46036
46177
|
vendor: t.vendor ?? "",
|
|
46037
46178
|
architecture: t.architecture ?? "",
|
|
46038
46179
|
device: t.device ?? "",
|
|
46039
46180
|
description: t.description ?? "",
|
|
46040
|
-
isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 ||
|
|
46181
|
+
isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || BA.test(n)
|
|
46041
46182
|
};
|
|
46042
46183
|
}
|
|
46043
|
-
var
|
|
46184
|
+
var HA = class extends en {
|
|
46044
46185
|
constructor(t, n = {}) {
|
|
46045
46186
|
super(), this._headless = n.headless === !0 || !t, t ??= vO();
|
|
46046
46187
|
try {
|
|
46047
|
-
|
|
46188
|
+
PA.get(t)?.dispose();
|
|
46048
46189
|
} catch (e) {
|
|
46049
|
-
|
|
46190
|
+
RA.warn("prior canvas owner dispose failed", e);
|
|
46050
46191
|
}
|
|
46051
|
-
|
|
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({
|
|
46052
46193
|
strict: n.strict === !0,
|
|
46053
46194
|
onIssue: (t) => this.dispatchEvent({
|
|
46054
46195
|
type: e.ISSUE,
|
|
@@ -46059,7 +46200,7 @@ var BA = class extends en {
|
|
|
46059
46200
|
environmentRotation: this._profile.environmentRotation,
|
|
46060
46201
|
saturation: this._profile.saturation,
|
|
46061
46202
|
dofMode: this._profile.dofMode
|
|
46062
|
-
}, { 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;
|
|
46063
46204
|
}
|
|
46064
46205
|
_addTrackedListener(e, t, n) {
|
|
46065
46206
|
e && (e.addEventListener(t, n), this._trackedListeners.push({
|
|
@@ -46072,13 +46213,13 @@ var BA = class extends en {
|
|
|
46072
46213
|
for (let { target: e, type: t, handler: n } of this._trackedListeners) try {
|
|
46073
46214
|
e.removeEventListener(t, n);
|
|
46074
46215
|
} catch (e) {
|
|
46075
|
-
|
|
46216
|
+
RA.warn("failed to remove listener", t, e);
|
|
46076
46217
|
}
|
|
46077
46218
|
this._trackedListeners.length = 0;
|
|
46078
46219
|
}
|
|
46079
46220
|
async init() {
|
|
46080
46221
|
let e = this._initStorage();
|
|
46081
|
-
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;
|
|
46082
46223
|
}
|
|
46083
46224
|
async _initStorage() {
|
|
46084
46225
|
let t = this._storageOption ?? (this._issues.strict && !d("storage") ? !1 : A().storage);
|
|
@@ -46114,7 +46255,7 @@ var BA = class extends en {
|
|
|
46114
46255
|
});
|
|
46115
46256
|
}
|
|
46116
46257
|
addEventListener(e, t) {
|
|
46117
|
-
!
|
|
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);
|
|
46118
46259
|
}
|
|
46119
46260
|
animate() {
|
|
46120
46261
|
if (this._headless) throw Error("a headless app has no render loop — drive it with renderFrames() or renderUntilComplete()");
|
|
@@ -46125,7 +46266,7 @@ var BA = class extends en {
|
|
|
46125
46266
|
}
|
|
46126
46267
|
if (this.timeline.update(), this.cameraManager.updateControls(), this._applyPendingRenderScale(), this.animationManager?.isPlaying && !this._animRefitInFlight) {
|
|
46127
46268
|
let e = this.animationManager.update();
|
|
46128
|
-
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(() => {
|
|
46129
46270
|
this._animRefitInFlight = !1;
|
|
46130
46271
|
}));
|
|
46131
46272
|
}
|
|
@@ -46182,7 +46323,7 @@ var BA = class extends en {
|
|
|
46182
46323
|
this.animationManagerId &&= (cancelAnimationFrame(this.animationManagerId), null);
|
|
46183
46324
|
}
|
|
46184
46325
|
_handleDeviceLost(t) {
|
|
46185
|
-
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({
|
|
46186
46327
|
type: e.DEVICE_LOST,
|
|
46187
46328
|
reason: t?.reason,
|
|
46188
46329
|
message: t?.message
|
|
@@ -46212,9 +46353,9 @@ var BA = class extends en {
|
|
|
46212
46353
|
let e = ht().value, t = Ne().value;
|
|
46213
46354
|
e?._listeners?.dispose && (e._listeners.dispose.length = 0), t?._listeners?.dispose && (t._listeners.dispose.length = 0);
|
|
46214
46355
|
} catch (e) {
|
|
46215
|
-
|
|
46356
|
+
RA.warn("failed to clear TSL texture singleton listeners", e);
|
|
46216
46357
|
}
|
|
46217
|
-
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;
|
|
46218
46359
|
}
|
|
46219
46360
|
}
|
|
46220
46361
|
unloadScene() {
|
|
@@ -46279,7 +46420,7 @@ var BA = class extends en {
|
|
|
46279
46420
|
url: t,
|
|
46280
46421
|
filename: r,
|
|
46281
46422
|
cacheKey: n.cacheKey ?? null,
|
|
46282
|
-
...
|
|
46423
|
+
...NA(n)
|
|
46283
46424
|
});
|
|
46284
46425
|
return;
|
|
46285
46426
|
}
|
|
@@ -46301,7 +46442,7 @@ var BA = class extends en {
|
|
|
46301
46442
|
kind: "local-file",
|
|
46302
46443
|
file: e,
|
|
46303
46444
|
key: e.sample ? _o(e) : null,
|
|
46304
|
-
...
|
|
46445
|
+
...NA(n)
|
|
46305
46446
|
};
|
|
46306
46447
|
}), this._sceneSourceFile = t;
|
|
46307
46448
|
return;
|
|
@@ -46517,10 +46658,10 @@ var BA = class extends en {
|
|
|
46517
46658
|
return t && this._dispatchCamerasUpdated(), t;
|
|
46518
46659
|
}
|
|
46519
46660
|
exportSceneState() {
|
|
46520
|
-
return
|
|
46661
|
+
return OA(this);
|
|
46521
46662
|
}
|
|
46522
46663
|
async importSceneState(e, t) {
|
|
46523
|
-
return await
|
|
46664
|
+
return await MA(this, e, t);
|
|
46524
46665
|
}
|
|
46525
46666
|
_sceneBudgets(e) {
|
|
46526
46667
|
return !this._memorySpill || !this.storage ? e : {
|
|
@@ -46565,8 +46706,8 @@ var BA = class extends en {
|
|
|
46565
46706
|
}
|
|
46566
46707
|
async refitBVH(e, t) {
|
|
46567
46708
|
await this.ensureSceneResident();
|
|
46568
|
-
let n = await this._sdf.refitBVH(e, t);
|
|
46569
|
-
return this.stages.pathTracer.updateTriangleData(this._sdf.triangles), 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;
|
|
46570
46711
|
}
|
|
46571
46712
|
refitBLASes(e, t, n) {
|
|
46572
46713
|
if (this._sdf?.spilled) throw Error("refitBLASes: the scene is spilled to disk — await app.ensureSceneResident() first");
|
|
@@ -46621,7 +46762,7 @@ var BA = class extends en {
|
|
|
46621
46762
|
requestedPx: t,
|
|
46622
46763
|
allowLower: n
|
|
46623
46764
|
}, Math.max(256, Math.min(bi, Math.floor(r) || 256));
|
|
46624
|
-
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));
|
|
46625
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)" : ""), {
|
|
46626
46767
|
requested: t,
|
|
46627
46768
|
applied: s,
|
|
@@ -46982,7 +47123,7 @@ var BA = class extends en {
|
|
|
46982
47123
|
let o = e ? this._readbackPass().draw(e, n, r).texture : t.textures[0], s = a.get(o).texture;
|
|
46983
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;
|
|
46984
47125
|
} catch (e) {
|
|
46985
|
-
return
|
|
47126
|
+
return RA.warn(`renderToBuffer: tone mapping on the GPU failed, doing it on the CPU: ${e?.message ?? e}`), null;
|
|
46986
47127
|
} finally {
|
|
46987
47128
|
this._readbackToneMapper?.release(), e && this._textureReadback?.release();
|
|
46988
47129
|
}
|
|
@@ -47068,7 +47209,7 @@ var BA = class extends en {
|
|
|
47068
47209
|
this._pathTracerEnabled = e, e || this.precompileRaster();
|
|
47069
47210
|
}
|
|
47070
47211
|
precompileRaster() {
|
|
47071
|
-
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);
|
|
47072
47213
|
}
|
|
47073
47214
|
get isLoading() {
|
|
47074
47215
|
return this._loadingInProgress;
|
|
@@ -47233,7 +47374,7 @@ var BA = class extends en {
|
|
|
47233
47374
|
if (e && this.color?.hasConfig) try {
|
|
47234
47375
|
t = this.color.convertTexturePixels(e);
|
|
47235
47376
|
} catch (e) {
|
|
47236
|
-
|
|
47377
|
+
RA.warn(`environment colour conversion failed: ${e.message}`);
|
|
47237
47378
|
}
|
|
47238
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();
|
|
47239
47380
|
}
|
|
@@ -47244,7 +47385,7 @@ var BA = class extends en {
|
|
|
47244
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)");
|
|
47245
47386
|
let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
|
|
47246
47387
|
if (!e) throw Error("Failed to get WebGPU adapter");
|
|
47247
|
-
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}`));
|
|
47248
47389
|
let t = e.limits, n = { maxColorAttachmentBytesPerSample: 128 };
|
|
47249
47390
|
for (let e of [
|
|
47250
47391
|
"maxBufferSize",
|
|
@@ -47267,9 +47408,9 @@ var BA = class extends en {
|
|
|
47267
47408
|
alpha: !0,
|
|
47268
47409
|
powerPreference: "high-performance",
|
|
47269
47410
|
requiredLimits: n
|
|
47270
|
-
}), 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.");
|
|
47271
47412
|
let r = this.renderer.backend?.device;
|
|
47272
|
-
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);
|
|
47273
47414
|
}
|
|
47274
47415
|
_initCameraManager() {
|
|
47275
47416
|
this.cameraManager = new RO(this.canvas), this.timeline = new WO({
|
|
@@ -47319,12 +47460,12 @@ var BA = class extends en {
|
|
|
47319
47460
|
}), this.iesManager = new ak(this.stages.pathTracer, {
|
|
47320
47461
|
onReset: () => this.reset(),
|
|
47321
47462
|
issues: this._issues
|
|
47322
|
-
}), this._setupDenoisingManager(), this._headless || (await this._setupOverlayManager(), this.transformManager = new
|
|
47463
|
+
}), this._setupDenoisingManager(), this._headless || (await this._setupOverlayManager(), this.transformManager = new yA({
|
|
47323
47464
|
camera: this.cameraManager.camera,
|
|
47324
47465
|
canvas: this.canvas,
|
|
47325
47466
|
orbitControls: this.cameraManager.controls,
|
|
47326
47467
|
app: this
|
|
47327
|
-
}), this.overlayManager.register("transform", new
|
|
47468
|
+
}), this.overlayManager.register("transform", new bA(this.transformManager))), this.interactionManager.setDependencies({
|
|
47328
47469
|
overlayManager: this.overlayManager,
|
|
47329
47470
|
transformManager: this.transformManager,
|
|
47330
47471
|
appDispatch: (e) => this.dispatchEvent(e),
|
|
@@ -47406,7 +47547,7 @@ var BA = class extends en {
|
|
|
47406
47547
|
});
|
|
47407
47548
|
}
|
|
47408
47549
|
_setupDenoisingManager() {
|
|
47409
|
-
this.denoisingManager = new
|
|
47550
|
+
this.denoisingManager = new aA({
|
|
47410
47551
|
renderer: this.renderer,
|
|
47411
47552
|
mainCanvas: this.canvas,
|
|
47412
47553
|
stages: {
|
|
@@ -47448,7 +47589,7 @@ var BA = class extends en {
|
|
|
47448
47589
|
this.scene.updateMatrixWorld(), this.overlayManager?.render();
|
|
47449
47590
|
}
|
|
47450
47591
|
async _setupOverlayManager() {
|
|
47451
|
-
this.overlayManager = new
|
|
47592
|
+
this.overlayManager = new mA(this.cameraManager.camera), this.overlayManager.setupDefaultHelpers({
|
|
47452
47593
|
helperScene: this._sceneHelpers,
|
|
47453
47594
|
meshScene: this.meshScene,
|
|
47454
47595
|
pipeline: this.pipeline,
|
|
@@ -47482,15 +47623,15 @@ var BA = class extends en {
|
|
|
47482
47623
|
};
|
|
47483
47624
|
//#endregion
|
|
47484
47625
|
//#region src/Headless.js
|
|
47485
|
-
async function
|
|
47486
|
-
let t = await
|
|
47626
|
+
async function UA(e) {
|
|
47627
|
+
let t = await GA(e);
|
|
47487
47628
|
try {
|
|
47488
|
-
return await
|
|
47629
|
+
return await WA(t, e);
|
|
47489
47630
|
} finally {
|
|
47490
47631
|
t.dispose();
|
|
47491
47632
|
}
|
|
47492
47633
|
}
|
|
47493
|
-
async function
|
|
47634
|
+
async function WA(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire: r = !1, denoise: i = !1, onProgress: a = void 0 } = {}) {
|
|
47494
47635
|
let o = e.denoisingManager;
|
|
47495
47636
|
i && o && !o.finalDenoise && (o.applyOIDNEnabled(!0), o._syncGBufferStages());
|
|
47496
47637
|
let s = await e.renderFrames(t, {
|
|
@@ -47509,8 +47650,8 @@ async function HA(e, { samples: t = 64, colorSpace: n = "srgb", allowEarlyRetire
|
|
|
47509
47650
|
provenance: e.getProvenance()
|
|
47510
47651
|
};
|
|
47511
47652
|
}
|
|
47512
|
-
async function
|
|
47513
|
-
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, {
|
|
47514
47655
|
autoResize: !1,
|
|
47515
47656
|
strict: i,
|
|
47516
47657
|
profile: a,
|
|
@@ -47525,7 +47666,7 @@ async function UA({ canvas: e, model: t = null, width: n = 1920, height: r = 108
|
|
|
47525
47666
|
}
|
|
47526
47667
|
//#endregion
|
|
47527
47668
|
//#region src/managers/VideoRenderManager.js
|
|
47528
|
-
var
|
|
47669
|
+
var KA = class {
|
|
47529
47670
|
constructor(e) {
|
|
47530
47671
|
this._app = e, this._cancelled = !1, this._rendering = !1;
|
|
47531
47672
|
}
|
|
@@ -47629,4 +47770,4 @@ var WA = class {
|
|
|
47629
47770
|
}
|
|
47630
47771
|
};
|
|
47631
47772
|
//#endregion
|
|
47632
|
-
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 };
|