rayzee 9.4.2 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +223 -21
  2. package/dist/ActiveColor-YvuQq44O.js +13 -0
  3. package/dist/ArchiveImporter-xuUJiklP.js +4301 -0
  4. package/dist/AssetConfig-DSEntE65.js +30 -0
  5. package/dist/BidirectionalIntegrator-C5PKjJoT.js +934 -0
  6. package/dist/ColorManagement-CheBCPaW.js +1488 -0
  7. package/dist/EngineDefaults-DH3bI5t-.js +844 -0
  8. package/dist/EngineEvents-Ci8dVWCP.js +73 -0
  9. package/dist/EngineIssues-CIZnXHsF.js +72 -0
  10. package/dist/FileFormats-sPGJeCRc.js +102 -0
  11. package/dist/Logger-BnHghprG.js +97 -0
  12. package/dist/{NeuralRetouch-vkdXXyK2.js → NeuralRetouch-CW11yLZ_.js} +8 -6
  13. package/dist/{NeuralSuperRes-FVqRJKQV.js → NeuralSuperRes-BekaecYg.js} +55 -120
  14. package/dist/PathTracer-Ccl9KOuF.js +29729 -0
  15. package/dist/PhysicalSky-Dv2PMFGW.js +1219 -0
  16. package/dist/RayzeeRenderer-BQxnzCTD.js +3542 -0
  17. package/dist/SolarLimb-ken-JbDK.js +721 -0
  18. package/dist/ToneMapGPU-BHi5JzIq.js +177 -0
  19. package/dist/ViewTransforms-D0rTLBsX.js +255 -0
  20. package/dist/WorkingMatrix-C6y233hT.js +27 -0
  21. package/dist/ZipReader-gDSWr0I5.js +98 -0
  22. package/dist/addons/archives.es.js +3 -0
  23. package/dist/addons/bidirectional.es.js +2 -0
  24. package/dist/addons/color.es.js +3 -0
  25. package/dist/addons/formats.es.js +2 -0
  26. package/dist/addons/physical-sky.es.js +2 -0
  27. package/dist/addons/storage.es.js +3 -0
  28. package/dist/archiveFormats-BZw7TiDp.js +75 -0
  29. package/dist/identity-DrQsGT2o.js +39 -0
  30. package/dist/openStorage-DwcBRUj7.js +820 -0
  31. package/dist/rayzee-core.es.js +12 -0
  32. package/dist/rayzee.es.js +2266 -44079
  33. package/dist/rayzee.umd.js +485 -473
  34. package/dist/sceneCachePolicy-BmwYOYDu.js +183 -0
  35. package/dist/shared-BGBcSxBQ.js +17 -0
  36. package/package.json +23 -2
  37. package/src/Color/ActiveColor.js +34 -0
  38. package/src/Color/BasicColor.js +147 -0
  39. package/src/Color/ColorManagement.js +7 -31
  40. package/src/EngineDefaults.js +22 -8
  41. package/src/EngineEvents.js +2 -0
  42. package/src/EngineIssues.js +1 -0
  43. package/src/PathTracerApp.js +617 -4016
  44. package/src/Pipeline/PipelineContext.js +0 -4
  45. package/src/Platform.js +36 -0
  46. package/src/Processor/ArchiveCache.js +1 -1
  47. package/src/Processor/ArchiveImporter.js +1259 -0
  48. package/src/Processor/AssetLoader.js +322 -1746
  49. package/src/Processor/AtmosphereModel.js +1 -2
  50. package/src/Processor/BVHBuilder.js +4 -95
  51. package/src/Processor/EnvironmentExactTable.js +187 -0
  52. package/src/Processor/EquirectHDRInfo.js +30 -223
  53. package/src/Processor/FileFormats.js +116 -0
  54. package/src/Processor/GLTFDecoders.js +85 -0
  55. package/src/Processor/GLTFDiffuseTransmission.js +63 -0
  56. package/src/Processor/GeometryExtractor.js +12 -1
  57. package/src/Processor/IESParser.js +47 -35
  58. package/src/Processor/KernelManager.js +35 -2
  59. package/src/Processor/MaterialPacking.js +8 -7
  60. package/src/Processor/PBRT/PBRTMaterials.js +129 -41
  61. package/src/Processor/PBRT/PBRTParser.js +30 -17
  62. package/src/Processor/PBRT/PBRTSceneBuilder.js +548 -37
  63. package/src/Processor/PBRT/PBRTTextureBake.js +154 -0
  64. package/src/Processor/PBRT/PFM.js +59 -0
  65. package/src/Processor/PackedRayBuffer.js +116 -9
  66. package/src/Processor/ParallelBVHBuilder.js +3 -6
  67. package/src/Processor/PhysicalSky.js +5 -4
  68. package/src/Processor/PlatformImageLoader.js +50 -6
  69. package/src/Processor/QueueManager.js +12 -3
  70. package/src/Processor/ReinsertionOptimizer.js +2 -2
  71. package/src/Processor/SceneProcessor.js +15 -55
  72. package/src/Processor/ShaderBuilder.js +6 -16
  73. package/src/Processor/SolarLimb.js +3 -0
  74. package/src/Processor/TextureCreator.js +1 -1
  75. package/src/Processor/Workers/BVHSubtreeWorker.js +1 -34
  76. package/src/Processor/Workers/BVHWorker.js +5 -18
  77. package/src/Processor/Workers/CDFWorker.js +6 -183
  78. package/src/Processor/archiveFormats.js +7 -0
  79. package/src/Processor/utils.js +2 -1
  80. package/src/RayzeeRenderer.js +3902 -0
  81. package/src/RenderSettings.js +49 -41
  82. package/src/Stages/ASVGF.js +5 -7
  83. package/src/Stages/AutoExposure.js +3 -12
  84. package/src/Stages/Compositor.js +8 -23
  85. package/src/Stages/NRD.js +9 -2
  86. package/src/Stages/NormalDepth.js +9 -6
  87. package/src/Stages/PathTracer.js +254 -38
  88. package/src/Stages/PathTracerStage.js +11 -16
  89. package/src/Storage/BLASCache.js +1 -1
  90. package/src/Storage/CDFCache.js +18 -17
  91. package/src/Storage/DownloadCache.js +1 -1
  92. package/src/Storage/SceneGraphCodec.js +46 -3
  93. package/src/Storage/SpillStore.js +1 -1
  94. package/src/Storage/StorageManager.js +2 -4
  95. package/src/Storage/areas.js +4 -0
  96. package/src/TSL/BVHTraversal.js +62 -24
  97. package/src/TSL/Bidirectional.js +204 -0
  98. package/src/TSL/BidirectionalLamps.js +132 -0
  99. package/src/TSL/Clearcoat.js +15 -6
  100. package/src/TSL/Common.js +19 -14
  101. package/src/TSL/ConnectKernel.js +147 -0
  102. package/src/TSL/Debugger.js +1 -1
  103. package/src/TSL/Displacement.js +4 -3
  104. package/src/TSL/EmissiveSampling.js +64 -17
  105. package/src/TSL/Environment.js +77 -106
  106. package/src/TSL/EnvironmentCDF.js +85 -39
  107. package/src/TSL/ExtendKernel.js +8 -3
  108. package/src/TSL/FinalWriteKernel.js +4 -4
  109. package/src/TSL/GenerateKernel.js +18 -4
  110. package/src/TSL/HitFacet.js +35 -5
  111. package/src/TSL/LightBVHSampling.js +40 -9
  112. package/src/TSL/LightGenerateKernel.js +293 -0
  113. package/src/TSL/LightGuide.js +198 -0
  114. package/src/TSL/LightSplatKernel.js +165 -0
  115. package/src/TSL/LightsCore.js +13 -38
  116. package/src/TSL/LightsDirect.js +28 -29
  117. package/src/TSL/LightsIndirect.js +3 -1
  118. package/src/TSL/LightsSampling.js +90 -38
  119. package/src/TSL/MaterialEvaluation.js +113 -31
  120. package/src/TSL/MaterialProperties.js +44 -17
  121. package/src/TSL/MaterialTransmission.js +52 -47
  122. package/src/TSL/MergeKernel.js +218 -0
  123. package/src/TSL/PathTracerCore.js +65 -29
  124. package/src/TSL/Random.js +4 -0
  125. package/src/TSL/SceneResources.js +51 -0
  126. package/src/TSL/ShadeKernel.js +881 -103
  127. package/src/TSL/Struct.js +10 -0
  128. package/src/TSL/Sun.js +1 -1
  129. package/src/TSL/TextureSampling.js +65 -60
  130. package/src/addons/archives.js +14 -0
  131. package/src/addons/bidirectional.js +13 -0
  132. package/src/addons/color.js +32 -0
  133. package/src/addons/formats.js +16 -0
  134. package/src/addons/physicalSky.js +14 -0
  135. package/src/addons/storage.js +19 -0
  136. package/src/core.js +35 -0
  137. package/src/index.js +3 -1
  138. package/src/integrators/BidirectionalIntegrator.js +832 -0
  139. package/src/managers/EnvironmentManager.js +85 -33
  140. package/src/managers/MaterialDataManager.js +42 -0
  141. package/src/managers/UniformManager.js +0 -1
  142. package/dist/ToneMapGPU-DKQM1pMd.js +0 -552
  143. package/dist/rolldown-runtime-CAFD8bLK.js +0 -11
  144. package/src/Processor/TreeletOptimizer.js +0 -574
@@ -0,0 +1,3542 @@
1
+ import { dt as e } from "./SolarLimb-ken-JbDK.js";
2
+ import { Mt as t, Nt as n, St as r, _t as i, ct as a, ft as o, gt as s, n as c, ot as l, st as u, vt as d, xt as f, yt as ee } from "./PathTracer-Ccl9KOuF.js";
3
+ import { n as p, t as m } from "./EngineEvents-Ci8dVWCP.js";
4
+ import { _ as h, d as te, f as ne, g, l as re, m as ie, o as ae, p as _, r as oe, u as se } from "./sceneCachePolicy-BmwYOYDu.js";
5
+ import { A as ce, P as le, k as ue, l as de, o as fe, p as v, q as pe, v as me, y, z as he } from "./EngineDefaults-DH3bI5t-.js";
6
+ import { i as b, r as ge } from "./Logger-BnHghprG.js";
7
+ import { i as _e, n as x, t as ve } from "./EngineIssues-CIZnXHsF.js";
8
+ import { n as ye, r as be } from "./shared-BGBcSxBQ.js";
9
+ import { a as xe } from "./WorkingMatrix-C6y233hT.js";
10
+ import { i as S, r as Se, t as C } from "./ActiveColor-YvuQq44O.js";
11
+ import { n as w, r as Ce } from "./AssetConfig-DSEntE65.js";
12
+ import { c as we, f as Te, l as T, p as Ee, u as De } from "./ViewTransforms-D0rTLBsX.js";
13
+ import { n as Oe, r as E } from "./identity-DrQsGT2o.js";
14
+ import { t as ke } from "./ToneMapGPU-BHi5JzIq.js";
15
+ import { n as Ae } from "./archiveFormats-BZw7TiDp.js";
16
+ import { LinearSRGBColorSpace as je, MeshBasicNodeMaterial as Me, NodeMaterial as Ne, QuadMesh as D, RectAreaLightNode as Pe, SRGBColorSpace as Fe, TextureNode as Ie, WebGPURenderer as Le } from "three/webgpu";
17
+ import { Fn as Re, If as ze, cubeTexture as Be, dot as Ve, float as O, int as k, ivec2 as He, mix as A, screenCoordinate as Ue, select as j, storage as We, texture as Ge, uint as Ke, uniform as M, uv as N, vec3 as P, vec4 as qe } from "three/tsl";
18
+ import { Box3 as Je, BufferGeometry as Ye, CircleGeometry as Xe, Color as Ze, DataTexture as Qe, DirectionalLight as $e, DirectionalLightHelper as et, EquirectangularReflectionMapping as tt, EventDispatcher as F, FloatType as nt, LinearFilter as rt, LinearSRGBColorSpace as it, LoaderUtils as I, LoadingManager as at, MathUtils as L, Mesh as ot, MeshPhysicalMaterial as st, NearestFilter as ct, NoBlending as lt, NoToneMapping as ut, Object3D as R, OrthographicCamera as dt, PerspectiveCamera as ft, PointLight as pt, PointLightHelper as mt, REVISION as ht, RGBAFormat as gt, RectAreaLight as z, RenderTarget as _t, SRGBColorSpace as B, Scene as vt, SpotLight as yt, SpotLightHelper as bt, TextureLoader as xt, UnsignedByteType as St, Vector2 as Ct, Vector3 as V } from "three";
19
+ import { RectAreaLightTexturesLib as wt } from "three/addons/lights/RectAreaLightTexturesLib.js";
20
+ import { RectAreaLightHelper as Tt } from "three/addons/helpers/RectAreaLightHelper.js";
21
+ import { GLTFLoader as Et } from "three/addons/loaders/GLTFLoader.js";
22
+ import { HDRLoader as Dt } from "three/addons/loaders/HDRLoader.js";
23
+ import { createMeshesFromMultiMaterialMesh as Ot } from "three/addons/utils/SceneUtils.js";
24
+ import { clone as kt } from "three/addons/utils/SkeletonUtils.js";
25
+ //#region src/SceneHelpers.js
26
+ var At = class {
27
+ constructor() {
28
+ this.scene = new vt(), this._helpers = /* @__PURE__ */ new Map(), this.visible = !1;
29
+ }
30
+ add(e) {
31
+ if (this._helpers.has(e.uuid)) return this._helpers.get(e.uuid);
32
+ let t = this._createHelper(e);
33
+ return t ? (this._helpers.set(e.uuid, t), this.scene.add(t), t) : null;
34
+ }
35
+ remove(e) {
36
+ let t = this._helpers.get(e.uuid);
37
+ t && (t.dispose(), this.scene.remove(t), this._helpers.delete(e.uuid));
38
+ }
39
+ has(e) {
40
+ return this._helpers.has(e.uuid);
41
+ }
42
+ get isDrawing() {
43
+ return this.visible && this._helpers.size > 0;
44
+ }
45
+ update() {
46
+ for (let e of this._helpers.values()) e.update?.();
47
+ }
48
+ sync(e) {
49
+ let t = new Set(e.map((e) => e.uuid));
50
+ for (let [e, n] of this._helpers) t.has(e) || (n.dispose(), this.scene.remove(n), this._helpers.delete(e));
51
+ for (let t of e) this.add(t);
52
+ }
53
+ clear() {
54
+ for (let e of this._helpers.values()) e.dispose(), this.scene.remove(e);
55
+ this._helpers.clear();
56
+ }
57
+ render(e, t) {
58
+ if (!this.isDrawing) return;
59
+ let n = e.autoClear;
60
+ e.autoClear = !1, e.clearDepth(), e.setRenderTarget(null), e.render(this.scene, t), e.autoClear = n;
61
+ }
62
+ dispose() {
63
+ this.clear();
64
+ }
65
+ _createHelper(e) {
66
+ return e.isRectAreaLight ? new Tt(e) : e.isPointLight ? new mt(e, .5) : e.isSpotLight ? new bt(e) : e.isDirectionalLight ? new et(e, .5) : null;
67
+ }
68
+ }, jt = class extends t {
69
+ constructor(t, r = {}) {
70
+ super("Compositor", {
71
+ ...r,
72
+ executionMode: n.ALWAYS
73
+ }), this.renderer = t, this._lightSources = [...r.displaySources ?? [], "pathtracer:color"], this.saturation = M(r.saturation ?? 1), this._transparentBackground = M(0, "int"), this._pathTracer = r.pathTracer ?? null, this._convergenceOverlay = !1, this._debugMaterial = null, this._debugQuad = null, this._debugTexNode = null, this._debugM2Attr = null, this._debugMaskAttr = null, this._debugExposureComp = M(1), this._sourceTexNode = new Ie();
74
+ let i = this._sourceTexNode.sample(N()), a = A(P(Ve(i.xyz, e)), i.xyz, this.saturation), o = j(this._transparentBackground, i.w, 1);
75
+ this.compositorMaterial = new Me(), this.compositorMaterial.colorNode = qe(a, o), this.compositorMaterial.blending = lt, this.compositorQuad = new D(this.compositorMaterial);
76
+ }
77
+ resolveLightTexture(e) {
78
+ return this.resolveLightSource(e)?.texture ?? null;
79
+ }
80
+ resolveLightSource(e) {
81
+ for (let t of this._lightSources) {
82
+ let n = e.getTexture(t);
83
+ if (n) return {
84
+ key: t,
85
+ texture: n
86
+ };
87
+ }
88
+ return null;
89
+ }
90
+ _ensureDebugMaterial() {
91
+ let t = this._pathTracer?.getConvergenceDebugSource?.();
92
+ if (!t) return !1;
93
+ if (this._debugMaterial && this._debugM2Attr === t.m2 && this._debugMaskAttr === t.frozenMask) return !0;
94
+ this._debugMaterial?.dispose(), this._debugTexNode?.dispose(), this._debugM2Attr = t.m2, this._debugMaskAttr = t.frozenMask, this._debugTexNode = new Ie();
95
+ let n = Re(() => {
96
+ let n = Ve(this._debugTexNode.sample(N()).toVar().xyz, e).toVar(), r = t.renderWidth, i = t.renderHeight, a = k(N().x.mul(O(r))).min(r.sub(k(1))).max(k(0)), o = Ke(k(N().y.mul(O(i))).min(i.sub(k(1))).max(k(0)).mul(r).add(a)).toVar(), s = We(t.m2, "float").toReadOnly().element(o).toVar(), c = We(t.frozenMask, "uint").toReadOnly().element(o).toVar(), l = s.sub(n.mul(n)).max(O(0)).div(O(t.frame).add(1)).sqrt().toVar(), u = t.usePixelFreeze.greaterThan(k(0)), d = j(n.lessThan(O(1)), n.sqrt(), n).toVar(), f = j(u, l.div(n.add(O(1e-4))), l.div(d.add(O(1e-4)))).toVar(), ee = j(u, t.pixelFreezeThreshold, t.noiseThreshold).toVar(), p = f.div(ee.max(O(1e-6))).toVar(), m = P(n.div(n.add(O(1))).sqrt().mul(.55)).toVar(), h = m.toVar(), te = O(t.frame).greaterThanEqual(O(t.adaptiveMinSamples));
97
+ return ze(p.greaterThanEqual(O(1)).or(te.not()), () => {
98
+ let e = A(P(1, .8, .1), P(1, .1, .05), p.sub(1).div(3).clamp(0, 1));
99
+ h.assign(A(m, e, .85));
100
+ }), ze(c.equal(Ke(1)).and(u), () => {
101
+ h.assign(A(m, P(.1, .45, 1), .55));
102
+ }), h;
103
+ });
104
+ return this._debugMaterial = new Me(), this._debugMaterial.colorNode = qe(n().pow(2.2).mul(this._debugExposureComp), 1), this._debugMaterial.blending = lt, this._debugQuad = new D(this._debugMaterial), !0;
105
+ }
106
+ render(e) {
107
+ if (!this.enabled) return;
108
+ if (this._convergenceOverlay && this._ensureDebugMaterial()) {
109
+ let t = e.getTexture("pathtracer:color");
110
+ if (t) {
111
+ this._debugTexNode.value = t;
112
+ let e = this.renderer.toneMapping !== ut;
113
+ this._debugExposureComp.value = e ? 1 / Math.max(this.renderer.toneMappingExposure, 1e-4) : 1, this.renderer.setRenderTarget(null), this._debugQuad.render(this.renderer);
114
+ return;
115
+ }
116
+ }
117
+ let t = this.resolveLightTexture(e);
118
+ t && (this._sourceTexNode.value = t, this.renderer.setRenderTarget(null), this.compositorQuad.render(this.renderer));
119
+ }
120
+ setConvergenceOverlay(e) {
121
+ this._convergenceOverlay = !!e;
122
+ }
123
+ setSaturation(e) {
124
+ this.saturation.value = e;
125
+ }
126
+ setTransparentBackground(e) {
127
+ this._transparentBackground.value = +!!e;
128
+ }
129
+ dispose() {
130
+ this._sourceTexNode?.dispose(), this.compositorMaterial?.dispose(), this._debugTexNode?.dispose(), this._debugMaterial?.dispose(), this.compositorQuad = null, this._debugQuad = null, this._debugMaterial = null, this._debugTexNode = null, this._pathTracer = null;
131
+ }
132
+ }, Mt = class {
133
+ constructor() {
134
+ this.textures = /* @__PURE__ */ new Map(), this.renderTargets = /* @__PURE__ */ new Map(), this.uniforms = /* @__PURE__ */ new Map(), this.state = {
135
+ frame: 0,
136
+ accumulatedFrames: 0,
137
+ renderMode: 0,
138
+ interactionMode: !1,
139
+ isComplete: !1,
140
+ tileInfo: null,
141
+ currentTile: 0,
142
+ totalTiles: 0,
143
+ cameraChanged: !1,
144
+ cameraMoving: !1,
145
+ width: 0,
146
+ height: 0,
147
+ time: 0,
148
+ deltaTime: 0
149
+ }, this._stateChangeCallbacks = /* @__PURE__ */ new Map();
150
+ }
151
+ setTexture(e, t) {
152
+ this.textures.set(e, t);
153
+ }
154
+ getTexture(e) {
155
+ return this.textures.get(e);
156
+ }
157
+ hasTexture(e) {
158
+ return this.textures.has(e);
159
+ }
160
+ removeTexture(e) {
161
+ this.textures.delete(e);
162
+ }
163
+ getTextureNames() {
164
+ return Array.from(this.textures.keys());
165
+ }
166
+ clearTextures() {
167
+ this.textures.clear();
168
+ }
169
+ setRenderTarget(e, t) {
170
+ this.renderTargets.set(e, t);
171
+ }
172
+ getRenderTarget(e) {
173
+ return this.renderTargets.get(e);
174
+ }
175
+ hasRenderTarget(e) {
176
+ return this.renderTargets.has(e);
177
+ }
178
+ removeRenderTarget(e) {
179
+ this.renderTargets.delete(e);
180
+ }
181
+ getRenderTargetNames() {
182
+ return Array.from(this.renderTargets.keys());
183
+ }
184
+ clearRenderTargets() {
185
+ this.renderTargets.clear();
186
+ }
187
+ setUniform(e, t) {
188
+ this.uniforms.has(e) ? this.uniforms.get(e).value = t : this.uniforms.set(e, { value: t });
189
+ }
190
+ getUniform(e) {
191
+ return this.uniforms.get(e);
192
+ }
193
+ getUniformValue(e) {
194
+ return this.uniforms.get(e)?.value;
195
+ }
196
+ hasUniform(e) {
197
+ return this.uniforms.has(e);
198
+ }
199
+ removeUniform(e) {
200
+ this.uniforms.delete(e);
201
+ }
202
+ getUniformNames() {
203
+ return Array.from(this.uniforms.keys());
204
+ }
205
+ clearUniforms() {
206
+ this.uniforms.clear();
207
+ }
208
+ setState(e, t) {
209
+ let n = this.state[e], r = n !== t;
210
+ return r && (this.state[e] = t, this._notifyStateChange(e, t, n)), r;
211
+ }
212
+ getState(e) {
213
+ return this.state[e];
214
+ }
215
+ getAllState() {
216
+ return this.state;
217
+ }
218
+ setStates(e) {
219
+ let t = [];
220
+ for (let [n, r] of Object.entries(e)) this.setState(n, r) && t.push(n);
221
+ return t;
222
+ }
223
+ hasState(e) {
224
+ return e in this.state;
225
+ }
226
+ watchState(e, t) {
227
+ this._stateChangeCallbacks.has(e) || this._stateChangeCallbacks.set(e, []), this._stateChangeCallbacks.get(e).push(t);
228
+ }
229
+ unwatchState(e, t) {
230
+ if (!this._stateChangeCallbacks.has(e)) return;
231
+ let n = this._stateChangeCallbacks.get(e), r = n.indexOf(t);
232
+ r > -1 && n.splice(r, 1);
233
+ }
234
+ _notifyStateChange(e, t, n) {
235
+ if (!this._stateChangeCallbacks.has(e)) return;
236
+ let r = this._stateChangeCallbacks.get(e);
237
+ for (let i of r) try {
238
+ i(t, n);
239
+ } catch (t) {
240
+ console.error(`Error in state change callback for '${e}':`, t);
241
+ }
242
+ }
243
+ reset() {
244
+ this.state.frame = 0, this.state.accumulatedFrames = 0, this.state.isComplete = !1, this.state.cameraChanged = !0, this.state.currentTile = 0;
245
+ }
246
+ incrementFrame() {
247
+ return this.state.frame++, this.state.accumulatedFrames++, this.state.frame;
248
+ }
249
+ dispose() {
250
+ this.textures.clear(), this.renderTargets.clear(), this.uniforms.clear(), this._stateChangeCallbacks.clear(), this.state = {};
251
+ }
252
+ }, Nt = class extends F {
253
+ constructor() {
254
+ super(), this._onceCallbacks = /* @__PURE__ */ new Map();
255
+ }
256
+ on(e, t) {
257
+ this.addEventListener(e, t);
258
+ }
259
+ once(e, t) {
260
+ let n = (r) => {
261
+ t(r), this.off(e, n), this._onceCallbacks.delete(t);
262
+ };
263
+ this._onceCallbacks.set(t, n), this.on(e, n);
264
+ }
265
+ off(e, t) {
266
+ let n = this._onceCallbacks.get(t);
267
+ n ? (this.removeEventListener(e, n), this._onceCallbacks.delete(t)) : this.removeEventListener(e, t);
268
+ }
269
+ emit(e, t) {
270
+ t && typeof t == "object" && t.type ? this.dispatchEvent(t) : this.dispatchEvent({
271
+ type: e,
272
+ ...t
273
+ });
274
+ }
275
+ removeAllListeners(e) {
276
+ if (e) {
277
+ for (let [t, n] of this._onceCallbacks.entries()) this.hasEventListener(e, n) && (this.removeEventListener(e, n), this._onceCallbacks.delete(t));
278
+ this._listeners && this._listeners[e] && delete this._listeners[e];
279
+ } else this._onceCallbacks.clear(), this._listeners &&= {};
280
+ }
281
+ listenerCount(e) {
282
+ return !this._listeners || !this._listeners[e] ? 0 : this._listeners[e].length;
283
+ }
284
+ clear() {
285
+ this.removeAllListeners();
286
+ }
287
+ eventNames() {
288
+ return this._listeners ? Object.keys(this._listeners) : [];
289
+ }
290
+ }, Pt = !1, H = [], Ft = /* @__PURE__ */ new WeakMap();
291
+ function It(e) {
292
+ Pt = !!e;
293
+ }
294
+ function Lt() {
295
+ return H.slice();
296
+ }
297
+ function Rt() {
298
+ H.length = 0;
299
+ }
300
+ function zt(e) {
301
+ let t = [];
302
+ for (let n of Object.keys(e)) e[n]?.isTextureNode === !0 && t.push(n);
303
+ return t;
304
+ }
305
+ var Bt = (e) => !e || !e.image || !(e.image.width > 0);
306
+ function Vt(e, t, n) {
307
+ if (!Pt) {
308
+ n();
309
+ return;
310
+ }
311
+ let r = Ft.get(e);
312
+ if (r || (r = {
313
+ phase: "pending",
314
+ unboundAtCompile: []
315
+ }, Ft.set(e, r)), r.phase !== "pending") {
316
+ n(), r.phase === "watch" && Ht(e, r);
317
+ return;
318
+ }
319
+ let i = Object.prototype.hasOwnProperty.call(t, "compute"), a = t.compute;
320
+ t.compute = function(...t) {
321
+ return r.phase === "pending" && (r.unboundAtCompile = zt(e).filter((t) => Bt(e[t].value)), r.phase = r.unboundAtCompile.length < 2 ? "done" : "watch"), a.apply(this, t);
322
+ };
323
+ try {
324
+ n();
325
+ } finally {
326
+ i ? t.compute = a : delete t.compute;
327
+ }
328
+ }
329
+ function Ht(e, t) {
330
+ let n = [];
331
+ for (let r of t.unboundAtCompile) {
332
+ let t = e[r]?.value;
333
+ if (Bt(t)) return;
334
+ t.isStorageTexture !== !0 && n.push(r);
335
+ }
336
+ t.phase = "done", n.length !== 0 && H.push({
337
+ stage: e.name,
338
+ nodes: n,
339
+ unboundAtCompile: t.unboundAtCompile.slice(),
340
+ message: `${e.name}: ${n.join(", ")} ${n.length === 1 ? "was" : "were"} still holding EmptyTexture when the stage first dispatched, alongside ${t.unboundAtCompile.length - n.length} other unbound node(s), and later received a non-storage texture. Two nodes unbound at compile time can share one GPU binding and then both resolve to whichever is assigned last. Assign these before the first dispatch.`
341
+ });
342
+ }
343
+ //#endregion
344
+ //#region src/Pipeline/RenderPipeline.js
345
+ var Ut = class {
346
+ _reportStageFailure(e, t, n) {
347
+ console.error(`[Pipeline] Error in stage '${e}' (${t}):`, n);
348
+ let r = `${e}:${t}`;
349
+ this._reportedStageFailures.has(r) || (this._reportedStageFailures.add(r), this._issues?.record(x.STAGE_RENDER_FAILED, `stage "${e}" threw during ${t} — the frame is incomplete`, {
350
+ stage: e,
351
+ phase: t,
352
+ cause: String(n?.message ?? n)
353
+ }));
354
+ }
355
+ constructor(e, t, n, { issues: r = null } = {}) {
356
+ this.renderer = e, this._issues = r, this._reportedStageFailures = /* @__PURE__ */ new Set(), this.width = t, this.height = n, this.stages = [], this.context = new Mt(), this.eventBus = new Nt(), this.context.setState("width", t), this.context.setState("height", n), this.stats = {
357
+ enabled: !1,
358
+ logSkipped: !1,
359
+ timings: /* @__PURE__ */ new Map(),
360
+ frameCount: 0
361
+ };
362
+ }
363
+ addStage(e) {
364
+ this.stages.push(e), e.initialize(this.context, this.eventBus), this.stats.enabled && console.log(`[Pipeline] Added stage: ${e.name}`);
365
+ }
366
+ getStage(e) {
367
+ return this.stages.find((t) => t.name === e);
368
+ }
369
+ removeStage(e) {
370
+ let t = this.stages.findIndex((t) => t.name === e);
371
+ if (t > -1) {
372
+ let e = this.stages[t];
373
+ return this.stages.splice(t, 1), e.dispose && e.dispose(), this.stats.timings.delete(e.name), !0;
374
+ }
375
+ return !1;
376
+ }
377
+ setStageEnabled(e, t) {
378
+ let n = this.getStage(e);
379
+ n && (t ? n.enable() : n.disable());
380
+ }
381
+ render(e = null) {
382
+ let t = this.stats.enabled ? performance.now() : 0;
383
+ for (let t of this.stages) {
384
+ if (!t.shouldExecuteThisFrame(this.context)) {
385
+ this.stats.enabled && this.stats.logSkipped && console.log(`[Pipeline] Skipped stage '${t.name}' (executionMode: ${t.executionMode})`);
386
+ continue;
387
+ }
388
+ try {
389
+ let n = this.stats.enabled ? performance.now() : 0;
390
+ if (Vt(t, this.renderer, () => t.render(this.context, e)), this.stats.enabled) {
391
+ let e = performance.now() - n;
392
+ this.stats.timings.has(t.name) || this.stats.timings.set(t.name, []);
393
+ let r = this.stats.timings.get(t.name);
394
+ r.push(e), r.length > 60 && r.shift();
395
+ }
396
+ } catch (e) {
397
+ this._reportStageFailure(t.name, "render", e);
398
+ }
399
+ }
400
+ if (this.context.incrementFrame(), this.eventBus.emit("frame:complete", {
401
+ frame: this.context.getState("frame"),
402
+ accumulatedFrames: this.context.getState("accumulatedFrames")
403
+ }), this.stats.enabled) {
404
+ let e = performance.now() - t;
405
+ this.stats.timings.has("_total") || this.stats.timings.set("_total", []);
406
+ let n = this.stats.timings.get("_total");
407
+ n.push(e), n.length > 60 && n.shift(), this.stats.frameCount++;
408
+ }
409
+ }
410
+ reset() {
411
+ this.eventBus.emit("pipeline:reset");
412
+ for (let e of this.stages) if (e.reset) try {
413
+ e.reset();
414
+ } catch (t) {
415
+ this._reportStageFailure(e.name, "reset", t);
416
+ }
417
+ this.context.reset(), this.stats.enabled && (this.stats.timings.clear(), this.stats.frameCount = 0);
418
+ }
419
+ setSize(e, t) {
420
+ this.width = e, this.height = t, this.context.setState("width", e), this.context.setState("height", t), this.eventBus.emit("pipeline:resize", {
421
+ width: e,
422
+ height: t
423
+ });
424
+ for (let n of this.stages) if (n.setSize) try {
425
+ n.setSize(e, t);
426
+ } catch (e) {
427
+ console.error(`[Pipeline] Error resizing stage '${n.name}':`, e);
428
+ }
429
+ }
430
+ dispose() {
431
+ for (let e of this.stages) if (e.dispose) try {
432
+ e.dispose();
433
+ } catch (t) {
434
+ console.error(`[Pipeline] Error disposing stage '${e.name}':`, t);
435
+ }
436
+ this.stages = [], this.context.dispose(), this.eventBus.clear(), this.stats.timings.clear();
437
+ }
438
+ setStatsEnabled(e) {
439
+ this.stats.enabled = e, e || (this.stats.timings.clear(), this.stats.frameCount = 0);
440
+ }
441
+ getStats() {
442
+ if (!this.stats.enabled) return null;
443
+ let e = {
444
+ frameCount: this.stats.frameCount,
445
+ stages: {},
446
+ total: 0
447
+ };
448
+ for (let [t, n] of this.stats.timings.entries()) {
449
+ if (n.length === 0) continue;
450
+ let r = n.reduce((e, t) => e + t, 0) / n.length, i = Math.min(...n), a = Math.max(...n);
451
+ t === "_total" ? (e.total = r, e.totalMin = i, e.totalMax = a) : e.stages[t] = {
452
+ avg: r,
453
+ min: i,
454
+ max: a
455
+ };
456
+ }
457
+ return e;
458
+ }
459
+ logStats() {
460
+ let e = this.getStats();
461
+ if (!e) {
462
+ console.log("[Pipeline] Stats not enabled");
463
+ return;
464
+ }
465
+ console.group("[Pipeline] Performance Stats"), console.log(`Frames: ${e.frameCount}`), e.totalMin === void 0 ? console.log("Total: no frames recorded yet (pipeline.render() has not run since stats were enabled — the path tracer may have converged and stopped its animation loop)") : console.log(`Total: ${e.total.toFixed(2)}ms (min: ${e.totalMin.toFixed(2)}ms, max: ${e.totalMax.toFixed(2)}ms)`);
466
+ for (let [t, n] of Object.entries(e.stages)) console.log(` ${t}: ${n.avg.toFixed(2)}ms (min: ${n.min.toFixed(2)}ms, max: ${n.max.toFixed(2)}ms)`);
467
+ console.groupEnd();
468
+ }
469
+ getInfo() {
470
+ return {
471
+ stageCount: this.stages.length,
472
+ enabledStages: this.stages.filter((e) => e.enabled).length,
473
+ stages: this.stages.map((e) => ({
474
+ name: e.name,
475
+ enabled: e.enabled
476
+ })),
477
+ contextState: this.context.getAllState(),
478
+ textures: this.context.getTextureNames(),
479
+ renderTargets: this.context.getRenderTargetNames(),
480
+ uniforms: this.context.getUniformNames(),
481
+ events: this.eventBus.eventNames()
482
+ };
483
+ }
484
+ logInfo() {
485
+ let e = this.getInfo();
486
+ console.group("[Pipeline] Info"), console.log("Stages:", e.stages), console.log("Context Textures:", e.textures), console.log("Context Render Targets:", e.renderTargets), console.log("Context Uniforms:", e.uniforms), console.log("Event Types:", e.events), console.log("State:", e.contextState), console.groupEnd();
487
+ }
488
+ }, Wt = ge("engine"), Gt = class {
489
+ constructor() {
490
+ this.timeElapsed = 0, this.lastResetTime = performance.now(), this.renderCompleteDispatched = !1, this.budgetOverrun = !1, this._budgetHeldWarned = !1;
491
+ }
492
+ updateTime() {
493
+ this.timeElapsed = (performance.now() - this.lastResetTime) / 1e3;
494
+ }
495
+ isTimeLimitReached(e, t, n) {
496
+ return t !== "time" || !(n > 0) || this.timeElapsed < n ? !1 : e?.frameCount > 0 ? (this.budgetOverrun = !0, !0) : (this._budgetHeldWarned || (this._budgetHeldWarned = !0, Wt.warn(`render time limit (${n}s) expired before the first sample landed — holding the deadline open to avoid capturing an empty frame`)), !1);
497
+ }
498
+ isLimitReached(e, t, n) {
499
+ return e ? this.isTimeLimitReached(e, t, n) ? !0 : this.stopCondition(e) !== null : !1;
500
+ }
501
+ stopCondition(e) {
502
+ return this.budgetOverrun ? "timeLimit" : e ? e.frameCount >= e.completionThreshold ? "samples" : e._isConvergedComplete?.() ? "converged" : null : null;
503
+ }
504
+ markComplete() {
505
+ return this.renderCompleteDispatched ? !1 : (this.renderCompleteDispatched = !0, !0);
506
+ }
507
+ reset() {
508
+ this.timeElapsed = 0, this.lastResetTime = performance.now(), this.renderCompleteDispatched = !1, this.budgetOverrun = !1, this._budgetHeldWarned = !1;
509
+ }
510
+ resumeFromPause() {
511
+ this.renderCompleteDispatched = !1, this.lastResetTime = performance.now() - this.timeElapsed * 1e3;
512
+ }
513
+ }, Kt = class {
514
+ constructor(e) {
515
+ this.renderer = e, this.target = null, this.material = new Ne(), this.material.name = "rayzee:texture-readback", this.quad = new D(this.material), this._node = null, this._source = null;
516
+ }
517
+ _ensureTarget(e, t) {
518
+ this.target && this.target.width === e && this.target.height === t || (this.target?.dispose(), this.target = new _t(e, t, {
519
+ type: nt,
520
+ format: gt,
521
+ depthBuffer: !1,
522
+ minFilter: ct,
523
+ magFilter: ct
524
+ }));
525
+ }
526
+ async read(e, t, n) {
527
+ try {
528
+ return await this.renderer.readRenderTargetPixelsAsync(this.draw(e, t, n), 0, 0, t, n);
529
+ } finally {
530
+ this.release();
531
+ }
532
+ }
533
+ draw(e, t, n) {
534
+ this._ensureTarget(t, n), this._source !== e && (this._node = Ge(e).load(He(Ue.xy)), this.material.outputNode = this._node, this.material.needsUpdate = !0, this._source = e);
535
+ let r = this.renderer.getRenderTarget();
536
+ return this.renderer.setRenderTarget(this.target), this.quad.render(this.renderer), this.renderer.setRenderTarget(r), this.target;
537
+ }
538
+ release() {
539
+ this.target?.dispose(), this.target = null;
540
+ }
541
+ dispose() {
542
+ this.target?.dispose(), this.material.dispose(), this.target = null, this._source = null, this._node = null;
543
+ }
544
+ }, qt = 864e5, U = Object.freeze({
545
+ IMMUTABLE: "immutable",
546
+ REVALIDATE: "revalidate",
547
+ NETWORK: "network"
548
+ }), W = (e, t) => ({
549
+ loaded: e,
550
+ total: t,
551
+ lengthComputable: t > 0 && e <= t
552
+ }), G = (e, t) => e.headers?.get?.(t) ?? null, Jt = (e) => e.reason ?? new DOMException("aborted", "AbortError");
553
+ function K(e) {
554
+ try {
555
+ let t = new URL(e, globalThis.location?.href ?? "http://localhost/").pathname;
556
+ return decodeURIComponent(t.split("/").pop()) || "download";
557
+ } catch {
558
+ return "download";
559
+ }
560
+ }
561
+ async function Yt(e, { onProgress: t, signal: n }) {
562
+ let r = Number(G(e, "content-length")) || 0, i = G(e, "content-type") ?? "";
563
+ if (!e.body) return new Blob([await e.arrayBuffer()], { type: i });
564
+ let a = e.body.getReader(), o = [], s = 0;
565
+ for (;;) {
566
+ if (n?.aborted) throw a.cancel().catch(() => {}), Jt(n);
567
+ let { done: e, value: i } = await a.read();
568
+ if (e) break;
569
+ o.push(i), s += i.length, t?.(W(s, r));
570
+ }
571
+ return new Blob(o, { type: i });
572
+ }
573
+ var q = (e, t, n) => new File([e], t, {
574
+ type: n || e.type,
575
+ lastModified: e.lastModified ?? Date.now()
576
+ }), Xt = () => {}, J = class {
577
+ constructor(e) {
578
+ this._storage = e, this._revalidating = /* @__PURE__ */ new Set();
579
+ }
580
+ get _area() {
581
+ return this._storage?.area(be.DOWNLOADS) ?? null;
582
+ }
583
+ async fetch(e, { key: t = e, name: n = K(e), policy: r = U.REVALIDATE, maxAgeMs: i = qt, onProgress: a = null, signal: o = null, fetchOptions: s = {} } = {}) {
584
+ let c = this._area;
585
+ if (c && r !== U.NETWORK) {
586
+ let o = await c.open(t);
587
+ if (o) {
588
+ let c = await o.file("data");
589
+ if (c) return r === U.REVALIDATE && Date.now() - (o.extra.checkedAt ?? 0) >= i && this._revalidate(e, t, n, o.extra, s), a?.(W(c.size, c.size)), {
590
+ file: q(c, n, o.extra.contentType),
591
+ release: () => o.release(),
592
+ fromCache: !0
593
+ };
594
+ o.release();
595
+ }
596
+ }
597
+ return this._download(e, t, n, {
598
+ onProgress: a,
599
+ signal: o,
600
+ fetchOptions: s,
601
+ cache: !!c
602
+ });
603
+ }
604
+ async has(e) {
605
+ return await this._area?.has(e) === !0;
606
+ }
607
+ async _download(e, t, n, { onProgress: r, signal: i, fetchOptions: a, cache: o }) {
608
+ if (i?.aborted) throw Jt(i);
609
+ let s = await fetch(e, {
610
+ ...a,
611
+ signal: i
612
+ });
613
+ if (!s.ok) throw Error(`HTTP ${s.status} fetching ${e}`);
614
+ let c = Number(G(s, "content-length")) || 0, l = {
615
+ url: e,
616
+ contentType: G(s, "content-type") ?? "",
617
+ lastModified: G(s, "last-modified"),
618
+ contentLength: c || null,
619
+ checkedAt: Date.now()
620
+ }, u = o && s.body ? await this._area.create(t, {
621
+ label: n,
622
+ expectedBytes: c
623
+ }) : null;
624
+ if (!u) return {
625
+ file: q(await Yt(s, {
626
+ onProgress: r,
627
+ signal: i
628
+ }), n, l.contentType),
629
+ release: Xt,
630
+ fromCache: !1
631
+ };
632
+ try {
633
+ await u.writeStream("data", s.body, {
634
+ signal: i,
635
+ onProgress: (e) => r?.(W(e, c))
636
+ }), await u.commit(l);
637
+ } catch (o) {
638
+ if (await u.abort(), o?.name !== "QuotaExceededError") throw o;
639
+ return this._download(e, t, n, {
640
+ onProgress: r,
641
+ signal: i,
642
+ fetchOptions: a,
643
+ cache: !1
644
+ });
645
+ }
646
+ let d = await this._area.open(t, { wait: !0 }), f = d && await d.file("data");
647
+ if (!f) throw d?.release(), Error(`storage: ${n} vanished right after it was saved`);
648
+ return {
649
+ file: q(f, n, l.contentType),
650
+ release: () => d.release(),
651
+ fromCache: !1
652
+ };
653
+ }
654
+ async _revalidate(e, t, n, r, i) {
655
+ if (this._revalidating.has(t)) return;
656
+ this._revalidating.add(t);
657
+ let a = !1;
658
+ try {
659
+ let t = new Headers(i?.headers);
660
+ t.set("Range", "bytes=0-0");
661
+ let n = await fetch(e, {
662
+ ...i,
663
+ headers: t
664
+ });
665
+ if (n.body?.cancel().catch(() => {}), n.ok) {
666
+ let e = G(n, "last-modified"), t = n.status === 206 ? Number(G(n, "content-range")?.match(/\/(\d+)$/)?.[1]) || null : Number(G(n, "content-length")) || null;
667
+ a = !!(e && r.lastModified && e !== r.lastModified || t && r.contentLength && t !== r.contentLength);
668
+ }
669
+ } catch {}
670
+ try {
671
+ if (a) {
672
+ let { release: r } = await this._download(e, t, n, {
673
+ fetchOptions: i,
674
+ cache: !0
675
+ });
676
+ r();
677
+ } else await this._area.patchMeta(t, { extra: {
678
+ ...r,
679
+ checkedAt: Date.now()
680
+ } });
681
+ } catch {} finally {
682
+ this._revalidating.delete(t);
683
+ }
684
+ }
685
+ };
686
+ function Zt(e, t, n) {
687
+ return new J(t).fetch(e, n);
688
+ }
689
+ function Qt() {
690
+ return new J(ye(w().cacheNamespace));
691
+ }
692
+ async function $t(e, { downloads: t = Qt(), ...n } = {}) {
693
+ if (!t._storage || !/^https?:/i.test(e)) return {
694
+ url: e,
695
+ release: Xt,
696
+ cached: !1
697
+ };
698
+ let { file: r, release: i } = await t.fetch(e, n), a = URL.createObjectURL(r);
699
+ return {
700
+ url: a,
701
+ cached: !0,
702
+ release: () => {
703
+ URL.revokeObjectURL(a), i();
704
+ }
705
+ };
706
+ }
707
+ //#endregion
708
+ //#region src/RenderSettings.js
709
+ var en = {
710
+ maxBounces: {
711
+ uniform: "maxBounces",
712
+ reset: !0
713
+ },
714
+ transmissiveBounces: {
715
+ uniform: "transmissiveBounces",
716
+ reset: !0
717
+ },
718
+ maxSubsurfaceSteps: {
719
+ uniform: "maxSubsurfaceSteps",
720
+ reset: !0
721
+ },
722
+ maxTransparentBounces: {
723
+ uniform: "maxTransparentBounces",
724
+ reset: !0
725
+ },
726
+ environmentIntensity: {
727
+ uniform: "environmentIntensity",
728
+ reset: !0
729
+ },
730
+ backgroundIntensity: {
731
+ uniform: "backgroundIntensity",
732
+ reset: !0
733
+ },
734
+ backgroundBlurriness: {
735
+ uniform: "backgroundBlurriness",
736
+ reset: !0
737
+ },
738
+ backgroundBlurSamples: {
739
+ uniform: "backgroundBlurSamples",
740
+ reset: !0
741
+ },
742
+ showBackground: {
743
+ uniform: "showBackground",
744
+ reset: !0
745
+ },
746
+ enableEnvironment: {
747
+ uniform: "enableEnvironment",
748
+ reset: !0
749
+ },
750
+ groundProjectionEnabled: {
751
+ uniform: "groundProjectionEnabled",
752
+ reset: !0
753
+ },
754
+ groundProjectionRadius: {
755
+ uniform: "groundProjectionRadius",
756
+ reset: !0
757
+ },
758
+ groundProjectionHeight: {
759
+ uniform: "groundProjectionHeight",
760
+ reset: !0
761
+ },
762
+ groundProjectionLevel: {
763
+ uniform: "groundProjectionLevel",
764
+ reset: !0
765
+ },
766
+ enableGroundCatcher: {
767
+ uniform: "enableGroundCatcher",
768
+ reset: !0
769
+ },
770
+ groundCatcherHeight: {
771
+ uniform: "groundCatcherHeight",
772
+ reset: !0
773
+ },
774
+ globalIlluminationIntensity: {
775
+ uniform: "globalIlluminationIntensity",
776
+ reset: !0
777
+ },
778
+ panoramaLevelHorizon: {
779
+ uniform: "panoLevelHorizon",
780
+ reset: !0
781
+ },
782
+ enableDOF: {
783
+ uniform: "enableDOF",
784
+ reset: !0
785
+ },
786
+ focusDistance: {
787
+ uniform: "focusDistance",
788
+ reset: !1
789
+ },
790
+ focalLength: {
791
+ uniform: "focalLength",
792
+ reset: !0
793
+ },
794
+ aperture: {
795
+ uniform: "aperture",
796
+ reset: !0
797
+ },
798
+ apertureScale: {
799
+ uniform: "apertureScale",
800
+ reset: !0
801
+ },
802
+ anamorphicRatio: {
803
+ uniform: "anamorphicRatio",
804
+ reset: !0
805
+ },
806
+ unitsPerMetre: {
807
+ uniform: "unitsPerMetre",
808
+ reset: !0
809
+ },
810
+ dofMode: {
811
+ handler: "handleDofMode",
812
+ reset: !0
813
+ },
814
+ dofBlur: {
815
+ uniform: "dofBlur",
816
+ reset: !0
817
+ },
818
+ samplingTechnique: {
819
+ uniform: "samplingTechnique",
820
+ reset: !0
821
+ },
822
+ fireflyThreshold: {
823
+ uniform: "fireflyThreshold",
824
+ reset: !0
825
+ },
826
+ shadowTerminatorOffset: {
827
+ uniform: "shadowTerminatorOffset",
828
+ reset: !0
829
+ },
830
+ enableAlphaShadows: {
831
+ uniform: "enableAlphaShadows",
832
+ reset: !0
833
+ },
834
+ useAdaptiveSampling: {
835
+ uniform: "useAdaptiveSampling",
836
+ reset: !0
837
+ },
838
+ noiseThreshold: {
839
+ uniform: "noiseThreshold",
840
+ reset: !0
841
+ },
842
+ adaptiveMinSamples: {
843
+ uniform: "adaptiveMinSamples",
844
+ reset: !0
845
+ },
846
+ adaptiveStopFraction: {
847
+ uniform: "adaptiveStopFraction",
848
+ reset: !0
849
+ },
850
+ usePixelFreeze: {
851
+ uniform: "usePixelFreeze",
852
+ reset: !0
853
+ },
854
+ pixelFreezeThreshold: {
855
+ uniform: "pixelFreezeThreshold",
856
+ reset: !0
857
+ },
858
+ pixelFreezeStability: {
859
+ uniform: "pixelFreezeStability",
860
+ reset: !0
861
+ },
862
+ convergenceOverlay: {
863
+ handler: "handleConvergenceOverlay",
864
+ reset: !1
865
+ },
866
+ enableEmissiveTriangleSampling: {
867
+ uniform: "enableEmissiveTriangleSampling",
868
+ reset: !0
869
+ },
870
+ emissiveBoost: {
871
+ uniform: "emissiveBoost",
872
+ reset: !0
873
+ },
874
+ visMode: {
875
+ uniform: "visMode",
876
+ reset: !0
877
+ },
878
+ debugVisScale: {
879
+ uniform: "debugVisScale",
880
+ reset: !0
881
+ },
882
+ cameraProjection: {
883
+ handler: "handleCameraProjection",
884
+ reset: !0
885
+ },
886
+ panoramaLonRange: {
887
+ handler: "handlePanoramaLonRange",
888
+ reset: !0
889
+ },
890
+ panoramaLatRange: {
891
+ handler: "handlePanoramaLatRange",
892
+ reset: !0
893
+ },
894
+ interactionModeEnabled: {
895
+ handler: "handleInteractionModeEnabled",
896
+ reset: !1
897
+ },
898
+ maxSamples: {
899
+ handler: "handleMaxSamples",
900
+ reset: !1
901
+ },
902
+ transparentBackground: { handler: "handleTransparentBackground" },
903
+ backgroundColor: {
904
+ handler: "handleBackgroundColor",
905
+ reset: !0
906
+ },
907
+ exposure: { handler: "handleExposure" },
908
+ saturation: { handler: "handleSaturation" },
909
+ renderLimitMode: { handler: "handleRenderLimitMode" },
910
+ renderTimeLimit: {
911
+ handler: "handleRenderTimeLimit",
912
+ reset: !1
913
+ },
914
+ renderMode: { handler: "handleRenderMode" },
915
+ integrator: {
916
+ handler: "handleIntegrator",
917
+ reset: !0
918
+ },
919
+ environmentRotation: { handler: "handleEnvironmentRotation" }
920
+ }, Y = Object.freeze({
921
+ DEFAULT: "default",
922
+ HOST: "host",
923
+ SCENE_METADATA: "scene-metadata",
924
+ MODE_PRESET: "mode-preset"
925
+ }), tn = {
926
+ bounces: "maxBounces",
927
+ debugMode: "visMode"
928
+ }, nn = class extends F {
929
+ constructor(e = v, { issues: t = null } = {}) {
930
+ super(), this._issues = t, this._defaults = e, this._routes = new Map(Object.entries(en)), this._values = /* @__PURE__ */ new Map(), this._sources = /* @__PURE__ */ new Map(), this._pathTracer = null, this._resetCallback = null, this._handlers = {}, this._initDefaults(e);
931
+ }
932
+ bind(e) {
933
+ this._pathTracer = e.stages.pathTracer, this._resetCallback = e.resetCallback, this._handlers = this._buildHandlers(e);
934
+ }
935
+ define(e, { apply: t, reset: n = !0 }) {
936
+ if (this._routes.has(e)) throw Error(`setting "${e}" is already defined`);
937
+ this._routes.set(e, {
938
+ apply: t,
939
+ reset: n
940
+ }), !this._values.has(e) && e in this._defaults && (this._values.set(e, this._defaults[e]), this._sources.set(e, Y.DEFAULT));
941
+ }
942
+ _buildHandlers({ stages: e, resetCallback: t, reconcileCompletion: n, applyExposure: r, onCameraProjection: i }) {
943
+ let a = new Ct(), o = (t, n) => {
944
+ a.set(n?.[0] ?? 0, n?.[1] ?? 0).multiplyScalar(L.DEG2RAD), e.pathTracer?.setUniform(t, a);
945
+ };
946
+ return {
947
+ handleCameraProjection: (t) => {
948
+ e.pathTracer?.setUniform("cameraProjection", de[t] ?? de.perspective), i?.(t);
949
+ },
950
+ handleDofMode: (t) => e.pathTracer?.setUniform("dofMode", +(t === "look")),
951
+ handlePanoramaLonRange: (e) => o("panoLonRange", e),
952
+ handlePanoramaLatRange: (e) => o("panoLatRange", e),
953
+ handleTransparentBackground: (t) => {
954
+ e.pathTracer?.setUniform("transparentBackground", t), e.compositor?.setTransparentBackground(t);
955
+ },
956
+ handleBackgroundColor: (t) => {
957
+ let n = t?.isColor ? t : new Ze(t);
958
+ e.pathTracer?.setUniform("backgroundColor", n);
959
+ },
960
+ handleExposure: (e) => {
961
+ r?.(e);
962
+ },
963
+ handleSaturation: (t) => {
964
+ e.compositor?.setSaturation(t);
965
+ },
966
+ handleConvergenceOverlay: (n) => {
967
+ e.pathTracer?.setUniform("convergenceOverlay", n), e.compositor?.setConvergenceOverlay(n), n && !this.get("useAdaptiveSampling") && t?.();
968
+ },
969
+ handleRenderLimitMode: (t) => {
970
+ e.pathTracer?.setRenderLimitMode?.(t), n?.();
971
+ },
972
+ handleMaxSamples: (t) => {
973
+ e.pathTracer?.setUniform("maxSamples", t), e.pathTracer?.updateCompletionThreshold(), n?.();
974
+ },
975
+ handleRenderTimeLimit: () => {
976
+ n?.();
977
+ },
978
+ handleRenderMode: (t) => {
979
+ e.pathTracer?.setUniform("renderMode", parseInt(t));
980
+ },
981
+ handleIntegrator: (t) => {
982
+ e.pathTracer?.setIntegrator?.(t);
983
+ },
984
+ handleEnvironmentRotation: (t) => {
985
+ e.pathTracer?.environment.setEnvironmentRotation(t);
986
+ },
987
+ handleInteractionModeEnabled: (t) => {
988
+ e.pathTracer?.setInteractionModeEnabled(t);
989
+ }
990
+ };
991
+ }
992
+ set(e, t, { reset: n, silent: r, source: i = Y.HOST } = {}) {
993
+ let a = this._applyOne(e, t, i);
994
+ a?.route && ((n === void 0 ? a.route.reset ?? !0 : n) && this._resetCallback?.(), r || this.dispatchEvent({
995
+ type: m.SETTING_CHANGED,
996
+ key: e,
997
+ value: t,
998
+ prev: a.prev
999
+ }));
1000
+ }
1001
+ setMany(e, { silent: t, reset: n, source: r = Y.HOST } = {}) {
1002
+ let i = !1;
1003
+ for (let [n, a] of Object.entries(e)) {
1004
+ let e = this._applyOne(n, a, r);
1005
+ e?.route && ((e.route.reset ?? !0) && (i = !0), t || this.dispatchEvent({
1006
+ type: m.SETTING_CHANGED,
1007
+ key: n,
1008
+ value: a,
1009
+ prev: e.prev
1010
+ }));
1011
+ }
1012
+ (n === void 0 ? i : n) && this._resetCallback?.();
1013
+ }
1014
+ _applyOne(e, t, n) {
1015
+ let r = this._values.get(e);
1016
+ if (r === t) return null;
1017
+ this._values.set(e, t), this._sources.set(e, n);
1018
+ let i = this._routes.get(e);
1019
+ return i ? (this._applyRoute(i, t, r), {
1020
+ route: i,
1021
+ prev: r
1022
+ }) : (this._reportUnknownKey(e), {
1023
+ route: null,
1024
+ prev: r
1025
+ });
1026
+ }
1027
+ _reportUnknownKey(e) {
1028
+ this._issues?.record(x.SETTING_UNKNOWN_KEY, `unknown setting "${e}" — stored but never applied to any stage`, { key: e });
1029
+ }
1030
+ get(e) {
1031
+ return this._values.get(e);
1032
+ }
1033
+ getEffective() {
1034
+ let e = {};
1035
+ for (let [t, n] of this._values) e[t] = {
1036
+ value: n,
1037
+ source: this._sources.get(t) ?? Y.DEFAULT,
1038
+ routed: this._routes.has(t)
1039
+ };
1040
+ return e;
1041
+ }
1042
+ getAll() {
1043
+ return Object.fromEntries(this._values);
1044
+ }
1045
+ serialize() {
1046
+ let e = {};
1047
+ for (let [t, n] of this._values) {
1048
+ if (this._sources.get(t) !== Y.HOST || !this._routes.has(t)) continue;
1049
+ let i = r(n);
1050
+ i !== void 0 && (e[t] = i);
1051
+ }
1052
+ return e;
1053
+ }
1054
+ restore(e) {
1055
+ let t = {}, n = [];
1056
+ for (let [r, i] of Object.entries(e ?? {})) this._routes.has(r) ? t[r] = f(i) : n.push(r);
1057
+ return this.setMany(t), n;
1058
+ }
1059
+ applyAll() {
1060
+ for (let [e, t] of this._values) {
1061
+ let n = this._routes.get(e);
1062
+ n && this._applyRoute(n, t, void 0);
1063
+ }
1064
+ }
1065
+ _applyRoute(e, t, n) {
1066
+ e.uniform ? this._pathTracer?.setUniform(e.uniform, t) : e.handler ? this._handlers[e.handler]?.(t, n) : e.apply(t, n);
1067
+ }
1068
+ _initDefaults(e) {
1069
+ for (let t of Object.keys(en)) t in e && (this._values.set(t, e[t]), this._sources.set(t, Y.DEFAULT));
1070
+ for (let [t, n] of Object.entries(tn)) t in e && (this._values.set(n, e[t]), this._sources.set(n, Y.DEFAULT));
1071
+ }
1072
+ }, rn = class {
1073
+ constructor({ issues: e = null } = {}) {
1074
+ this._issues = e, this._renderer = null, this._offRegistry = Te(() => {
1075
+ this._renderer && Ee(this._renderer);
1076
+ });
1077
+ }
1078
+ get hasConfig() {
1079
+ return !1;
1080
+ }
1081
+ get workingSpace() {
1082
+ return C;
1083
+ }
1084
+ get workingSpaceAdopted() {
1085
+ return !1;
1086
+ }
1087
+ get inputKey() {
1088
+ return "-";
1089
+ }
1090
+ attachRenderer(e) {
1091
+ this._renderer = e;
1092
+ let t = Ee(e);
1093
+ return e.outputColorSpace = B, t;
1094
+ }
1095
+ listViews() {
1096
+ return De();
1097
+ }
1098
+ get activeView() {
1099
+ return null;
1100
+ }
1101
+ setActiveView(e) {
1102
+ let t = T(e);
1103
+ if (!t) throw Error(`no view transform with id ${e}`);
1104
+ if (t.outputEncoded) throw Error(`"${t.name}" returns display-encoded colour: it needs rayzee/addons/color`);
1105
+ return this._renderer && (this._renderer.toneMapping = e), t;
1106
+ }
1107
+ _publishWorkingMatrix() {
1108
+ xe(null, C);
1109
+ }
1110
+ loadConfig() {
1111
+ let e = "colour configs need the OCIO pipeline: renderer.setColorManagement( ColorManagement ), from rayzee/addons/color";
1112
+ return this._issues?.record(x.CAPABILITY_MISSING, e, { capability: "color" }), Promise.reject(Error(e));
1113
+ }
1114
+ unloadConfig() {}
1115
+ setWorkingSpace() {}
1116
+ exportPixels(e) {
1117
+ return {
1118
+ rgba: e,
1119
+ colorSpace: C
1120
+ };
1121
+ }
1122
+ status() {
1123
+ let e = this._renderer ? T(this._renderer.toneMapping) : null;
1124
+ return {
1125
+ config: null,
1126
+ workingSpace: C,
1127
+ workingSpaceAdopted: !1,
1128
+ activeTransform: e ? {
1129
+ id: e.id,
1130
+ name: e.name,
1131
+ source: e.source
1132
+ } : null,
1133
+ activeView: null,
1134
+ context: null,
1135
+ exportSpace: null,
1136
+ views: De(),
1137
+ registryVersion: we(),
1138
+ bakeError: e?.error ?? null
1139
+ };
1140
+ }
1141
+ dispose() {
1142
+ this._offRegistry?.(), this._renderer = null, this._issues = null, Se() === this && (xe(null), S(null));
1143
+ }
1144
+ }, an = [
1145
+ [/\.jpe?g(\?|#|$)/i, "image/jpeg"],
1146
+ [/\.webp(\?|#|$)/i, "image/webp"],
1147
+ [/\.avif(\?|#|$)/i, "image/avif"]
1148
+ ];
1149
+ function on(e) {
1150
+ return e.mimeType ? e.mimeType : e.uri?.startsWith("data:") ? e.uri.slice(5, e.uri.indexOf(";")) : an.find(([t]) => t.test(e.uri ?? ""))?.[1] ?? "image/png";
1151
+ }
1152
+ function sn(e) {
1153
+ for (let t = 8; t + 12 <= e.length;) {
1154
+ let n = (e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]) >>> 0, r = t + 12 + n;
1155
+ if (e[t + 4] === 73 && e[t + 5] === 69 && e[t + 6] === 78 && e[t + 7] === 68) return e.subarray(0, r);
1156
+ t = r;
1157
+ }
1158
+ return e;
1159
+ }
1160
+ function cn({ data: e, width: t, height: n }, { shared: r = !1 } = {}) {
1161
+ let i = new Uint8Array(e.buffer, e.byteOffset, t * n * 4), a = i;
1162
+ r && typeof SharedArrayBuffer < "u" && !(i.buffer instanceof SharedArrayBuffer) && (a = new Uint8Array(new SharedArrayBuffer(i.byteLength)), a.set(i));
1163
+ let o = new Qe(a, t, n, gt, St);
1164
+ return o.needsUpdate = !0, o;
1165
+ }
1166
+ function ln(e, t) {
1167
+ return s().decodeImage(t === "image/png" ? sn(e) : e, t);
1168
+ }
1169
+ async function un(e) {
1170
+ let t = await fetch(e);
1171
+ if (!t.ok) throw Error(`HTTP ${t.status}`);
1172
+ return new Uint8Array(await t.arrayBuffer());
1173
+ }
1174
+ function dn(e, t) {
1175
+ return t.bufferView === void 0 ? un(e.options.manager.resolveURL(I.resolveURL(t.uri, e.options.path))) : e.getDependency("bufferView", t.bufferView).then((e) => new Uint8Array(e));
1176
+ }
1177
+ var fn = (e, t) => !!t && t !== e.textureLoader && typeof t.parse == "function";
1178
+ function pn(e, t, n) {
1179
+ if (e.sourceCache[t] !== void 0) return e.sourceCache[t].then((e) => e.clone());
1180
+ let r = dn(e, e.json.images[t]).then((e) => new Promise((t, r) => {
1181
+ n.parse(e.buffer.slice(e.byteOffset, e.byteOffset + e.byteLength), t, r);
1182
+ }));
1183
+ return e.sourceCache[t] = r, r;
1184
+ }
1185
+ async function mn(e, t = on({ uri: e })) {
1186
+ let n = cn(await ln(await un(e), t));
1187
+ return n.flipY = !0, n;
1188
+ }
1189
+ function hn(e, t = null) {
1190
+ return e.loadImageSource = function(e, n) {
1191
+ if (fn(this, n)) return pn(this, e, n);
1192
+ let r = this.json.images[e], i = /* @__PURE__ */ Error("no image decoder in this runtime: configurePlatform( nodePlatform( { decodeImage } ) ) — see \"Running in Node\"");
1193
+ return t?.(r.uri ?? `bufferView ${r.bufferView}`, i), Promise.reject(i);
1194
+ }, { name: "RAYZEE_missing_image_decoder" };
1195
+ }
1196
+ function gn(e, t = null) {
1197
+ return e.loadImageSource = function(e, n) {
1198
+ if (fn(this, n)) return pn(this, e, n);
1199
+ if (this.sourceCache[e] !== void 0) return this.sourceCache[e].then((e) => e.clone());
1200
+ let r = this.json.images[e], i = on(r), a = r.uri ?? `bufferView ${r.bufferView}`, o = dn(this, r).then((e) => ln(e, i)).then((e) => {
1201
+ let t = cn(e, { shared: !0 });
1202
+ return r.extras && typeof r.extras == "object" && Object.assign(t.userData, r.extras), t.userData.mimeType = i, t;
1203
+ }).catch((e) => {
1204
+ throw t?.(a, e), e;
1205
+ });
1206
+ return this.sourceCache[e] = o, o;
1207
+ }, { name: "RAYZEE_platform_images" };
1208
+ }
1209
+ //#endregion
1210
+ //#region src/Processor/GLTFDiffuseTransmission.js
1211
+ var _n = "KHR_materials_diffuse_transmission";
1212
+ function vn(e) {
1213
+ let t = (t, n, r, i) => {
1214
+ let a = {};
1215
+ return e.assignTexture(a, n, r, i).then(() => {
1216
+ a[n] && (t[n] = a[n]);
1217
+ });
1218
+ };
1219
+ return {
1220
+ name: _n,
1221
+ afterRoot(n) {
1222
+ let r = e.json.materials ?? [], i = /* @__PURE__ */ new Set(), a = [];
1223
+ for (let o of n.scenes ?? []) o.traverse((n) => {
1224
+ let o = Array.isArray(n.material) ? n.material : n.material ? [n.material] : [];
1225
+ for (let n of o) {
1226
+ if (i.has(n)) continue;
1227
+ i.add(n);
1228
+ let o = e.associations.get(n)?.materials, s = o === void 0 ? null : r[o]?.extensions?.[_n];
1229
+ if (!s) continue;
1230
+ n.diffuseTransmission = s.diffuseTransmissionFactor ?? 0;
1231
+ let [c, l, u] = s.diffuseTransmissionColorFactor ?? [
1232
+ 1,
1233
+ 1,
1234
+ 1
1235
+ ];
1236
+ n.diffuseTransmissionColor = new Ze().setRGB(c, l, u, it), s.diffuseTransmissionTexture && a.push(t(n, "diffuseTransmissionMap", s.diffuseTransmissionTexture)), s.diffuseTransmissionColorTexture && a.push(t(n, "diffuseTransmissionColorMap", s.diffuseTransmissionColorTexture, B));
1237
+ }
1238
+ });
1239
+ return Promise.all(a);
1240
+ }
1241
+ };
1242
+ }
1243
+ //#endregion
1244
+ //#region src/Processor/GLTFDecoders.js
1245
+ var yn = "KHR_draco_mesh_compression", bn = "KHR_texture_basisu", xn = ["EXT_meshopt_compression", "KHR_meshopt_compression"], Sn = new TextDecoder();
1246
+ function Cn(e) {
1247
+ if (typeof e == "string") return e;
1248
+ if (!(e instanceof ArrayBuffer)) return JSON.stringify(e?.extensionsUsed ?? []);
1249
+ let t = new DataView(e);
1250
+ if (!(e.byteLength >= 20 && t.getUint32(0, !0) === 1179937895)) return Sn.decode(e);
1251
+ let n = Math.min(t.getUint32(12, !0), e.byteLength - 20);
1252
+ return Sn.decode(new Uint8Array(e, 20, n));
1253
+ }
1254
+ async function wn(e, t, n) {
1255
+ let { dracoDecoderPath: r, ktx2TranscoderPath: i } = w(), [a, o, s] = await Promise.all([
1256
+ t.includes(yn) && !e.dracoLoader ? import("three/addons/loaders/DRACOLoader.js") : null,
1257
+ t.includes(bn) && !e.ktx2Loader ? import("three/addons/loaders/KTX2Loader.js") : null,
1258
+ xn.some((e) => t.includes(e)) && !e.meshoptDecoder ? import("three/addons/libs/meshopt_decoder.module.js") : null
1259
+ ]);
1260
+ if (a) {
1261
+ let t = new a.DRACOLoader();
1262
+ t.setDecoderConfig({ type: "js" }), t.setDecoderPath(r), e.setDRACOLoader(t);
1263
+ }
1264
+ if (o) {
1265
+ let t = new o.KTX2Loader();
1266
+ t.setTranscoderPath(i), n && (t.detectSupport(n), t.workerConfig = {
1267
+ astcSupported: !1,
1268
+ etc1Supported: !1,
1269
+ etc2Supported: !1,
1270
+ dxtSupported: !1,
1271
+ bptcSupported: !1,
1272
+ pvrtcSupported: !1
1273
+ }), e.setKTX2Loader(t);
1274
+ }
1275
+ s && e.setMeshoptDecoder(s.MeshoptDecoder);
1276
+ }
1277
+ function Tn(e, t) {
1278
+ let n = e.parse.bind(e);
1279
+ return e.parse = (r, i, a, o) => {
1280
+ wn(e, Cn(r), t).then(() => n(r, i, a, o), (e) => o?.(e));
1281
+ }, e;
1282
+ }
1283
+ //#endregion
1284
+ //#region src/Processor/AssetLoader.js
1285
+ var En = {
1286
+ glb: {
1287
+ type: "model",
1288
+ name: "GLB (GLTF Binary)"
1289
+ },
1290
+ gltf: {
1291
+ type: "model",
1292
+ name: "GLTF"
1293
+ },
1294
+ hdr: {
1295
+ type: "environment",
1296
+ name: "HDR (High Dynamic Range)"
1297
+ },
1298
+ png: {
1299
+ type: "image",
1300
+ name: "PNG"
1301
+ },
1302
+ jpg: {
1303
+ type: "image",
1304
+ name: "JPEG"
1305
+ },
1306
+ jpeg: {
1307
+ type: "image",
1308
+ name: "JPEG"
1309
+ },
1310
+ webp: {
1311
+ type: "image",
1312
+ name: "WebP"
1313
+ }
1314
+ }, X = {
1315
+ addOn: "rayzee/addons/archives",
1316
+ install: "assetLoader.setArchiveImporter()"
1317
+ }, Z = {
1318
+ addOn: "rayzee/addons/formats",
1319
+ install: "assetLoader.registerFormat()"
1320
+ }, Dn = {
1321
+ zip: X,
1322
+ gz: X,
1323
+ tgz: X,
1324
+ tar: X,
1325
+ fbx: Z,
1326
+ obj: Z,
1327
+ stl: Z,
1328
+ ply: Z,
1329
+ dae: Z,
1330
+ "3mf": Z,
1331
+ usd: Z,
1332
+ usda: Z,
1333
+ usdc: Z,
1334
+ usdz: Z,
1335
+ exr: Z
1336
+ };
1337
+ function On(e) {
1338
+ let t = new Ye();
1339
+ for (let n in e.attributes) t.setAttribute(n, e.attributes[n]);
1340
+ e.index && t.setIndex(e.index);
1341
+ for (let n of e.groups) t.addGroup(n.start, n.count, n.materialIndex);
1342
+ return t;
1343
+ }
1344
+ var kn = 683;
1345
+ function An(e, t, n, r) {
1346
+ if (!(r.normalize ?? !0)) return Math.PI;
1347
+ let i = r.shape === "ellipse" || r.shape === "disk" ? Math.PI / 4 : 1, a = e.getWorldScale(new V()), o = Math.PI * i * Math.abs(t * a.x * n * a.y);
1348
+ return Number.isFinite(o) ? o : Math.PI;
1349
+ }
1350
+ var jn = class e extends F {
1351
+ constructor(e, t, n, { issues: r = null, profile: i = null } = {}) {
1352
+ super(), this.scene = e, this.camera = t, this.controls = n, this.targetModel = null, this.floorPlane = null, this.sceneScale = 1, this.sceneSize = new V(1, 1, 1), this.loaderCache = {}, this.uploadedFileInfo = null, this.animations = [], this.renderer = null, this.sceneMetadata = null, this._loadingManager = new at(), this._loadCancelled = !1, this._urlAbort = null, this.storage = null, this._downloads = null, this._sourceKey = null, this._appended = !1, this.archives = null, this._archiveLoader = null, this._formats = /* @__PURE__ */ new Map(), this._issues = r, this._profile = i ?? he(), this._loadingManager.onError = (e) => {
1353
+ this._loadCancelled || this._issues?.record(x.ASSET_UNREACHABLE, `asset "${e}" could not be fetched — anything depending on it renders without it`, { url: e });
1354
+ };
1355
+ }
1356
+ cancelActiveLoad() {
1357
+ this._loadCancelled = !0, this._loadingManager.abort(), this._urlAbort?.abort();
1358
+ }
1359
+ async _viaCache(t, n, r, { cacheKey: i = t, cachePolicy: a } = {}) {
1360
+ if (!this.storage || !e._isNetworkUrl(t) || /\.gltf$/i.test(t.split(/[?#]/)[0])) return {
1361
+ url: t,
1362
+ release: () => {},
1363
+ cached: !1
1364
+ };
1365
+ let o = new AbortController();
1366
+ this._urlAbort = o;
1367
+ try {
1368
+ return await $t(t, {
1369
+ downloads: this.downloads,
1370
+ key: i,
1371
+ policy: a,
1372
+ name: K(t),
1373
+ signal: o.signal,
1374
+ onProgress: this._downloadProgress(n, r)
1375
+ });
1376
+ } catch (e) {
1377
+ throw this._isCancellation(e) ? this._cancellationError() : e;
1378
+ } finally {
1379
+ this._urlAbort = null;
1380
+ }
1381
+ }
1382
+ get sceneSourceKey() {
1383
+ return this._appended ? null : this._sourceKey;
1384
+ }
1385
+ _keyed(e, t) {
1386
+ return t ? `${e}:${this._profile?.name ?? ""}:${t}` : null;
1387
+ }
1388
+ get downloads() {
1389
+ return this._downloads?._storage !== this.storage && (this._downloads = new J(this.storage)), this._downloads;
1390
+ }
1391
+ _isCancellation(e) {
1392
+ return this._loadCancelled || e?.name === "AbortError" || e?.code === "LOAD_CANCELLED";
1393
+ }
1394
+ _cancellationError() {
1395
+ let e = /* @__PURE__ */ Error("Load cancelled");
1396
+ return e.code = "LOAD_CANCELLED", e;
1397
+ }
1398
+ _downloadProgress(e, t) {
1399
+ return (n) => {
1400
+ let r = n?.loaded || 0, i = n?.lengthComputable && n.total || 0;
1401
+ g({
1402
+ isLoading: !0,
1403
+ status: e,
1404
+ loadedBytes: r,
1405
+ totalBytes: i,
1406
+ canCancel: !!t,
1407
+ progress: i ? Math.min(60, 2 + Math.round(r / i * 58)) : 2
1408
+ });
1409
+ };
1410
+ }
1411
+ _downloadComplete(e = "Processing Data...", t = 62) {
1412
+ g({
1413
+ status: e,
1414
+ progress: t,
1415
+ canCancel: !1,
1416
+ loadedBytes: null,
1417
+ totalBytes: null
1418
+ });
1419
+ }
1420
+ static _isNetworkUrl(e) {
1421
+ return typeof e == "string" && /^https?:/i.test(e);
1422
+ }
1423
+ _adoptExternalObject(e) {
1424
+ let t;
1425
+ try {
1426
+ t = kt(e);
1427
+ } catch (t) {
1428
+ throw Error(`Cannot render "${e.name || e.type}": its userData must be JSON-serializable.`, { cause: t });
1429
+ }
1430
+ return t.userData.__rayzeeExternal = !0, this.scene?.children.some((t) => t.uuid === e.uuid) || (t.uuid = e.uuid), e.parent && (e.parent.updateWorldMatrix(!0, !1), t.applyMatrix4(e.parent.matrixWorld)), t;
1431
+ }
1432
+ releaseTargetModel() {
1433
+ this.sceneMetadata = null, this._sourceKey = null, this._appended = !1, this.archives?.release(), this.targetModel && (this.removeModelRoot(this.targetModel), this.targetModel = null, this.animations = []);
1434
+ }
1435
+ setRenderer(e) {
1436
+ this.renderer = e;
1437
+ }
1438
+ setArchiveImporter(e) {
1439
+ this.archives = e;
1440
+ }
1441
+ setArchiveImporterLoader(e, t) {
1442
+ this._archiveLoader = {
1443
+ load: e,
1444
+ formats: t,
1445
+ pending: null
1446
+ };
1447
+ }
1448
+ async _archiveImporter() {
1449
+ return !this.archives && this._archiveLoader && (this.archives = await (this._archiveLoader.pending ??= this._archiveLoader.load())), this.archives;
1450
+ }
1451
+ get _archiveFormats() {
1452
+ return this.archives?.constructor.FORMATS ?? this._archiveLoader?.formats ?? null;
1453
+ }
1454
+ registerFormat(...e) {
1455
+ for (let t of e) for (let e of t.extensions) this._formats.set(e, t);
1456
+ return this;
1457
+ }
1458
+ getFileFormat(e) {
1459
+ let t = e.split(".").pop().toLowerCase();
1460
+ return En[t] || this._formats.get(t) || this._archiveFormats?.[t] || null;
1461
+ }
1462
+ formatError(e) {
1463
+ let t = Dn[e.split(".").pop().toLowerCase()];
1464
+ return /* @__PURE__ */ Error(t ? `${e}: this format is read by ${t.addOn} — install it with ${t.install}` : `Unsupported file format: ${e}`);
1465
+ }
1466
+ async inspectArchive(e) {
1467
+ let t = await this._archiveImporter();
1468
+ if (!t) throw this.formatError(e.name ?? "archive.zip");
1469
+ return await t.inspectArchive(e);
1470
+ }
1471
+ flushPendingGraph(e) {
1472
+ this.archives?.flushPendingGraph(e);
1473
+ }
1474
+ readFileAsArrayBuffer(e) {
1475
+ return e.arrayBuffer();
1476
+ }
1477
+ readFileAsText(e) {
1478
+ return e.text();
1479
+ }
1480
+ async loadAssetFromFile(e, t = {}) {
1481
+ let n = e.name, r = this.getFileFormat(n);
1482
+ if (!r) throw this.formatError(n);
1483
+ g({
1484
+ isLoading: !0,
1485
+ status: `Loading ${r.name}...`,
1486
+ progress: 2
1487
+ });
1488
+ try {
1489
+ let i;
1490
+ switch (r.type) {
1491
+ case "model":
1492
+ i = await this.loadModelFromFile(e, n);
1493
+ break;
1494
+ case "environment":
1495
+ case "image":
1496
+ i = await this.loadEnvironmentFromFile(e, n);
1497
+ break;
1498
+ case "archive":
1499
+ i = await (await this._archiveImporter()).loadArchiveFromFile(e, n, t);
1500
+ break;
1501
+ default: throw Error(`Unknown asset type: ${r.type}`);
1502
+ }
1503
+ return i;
1504
+ } catch (e) {
1505
+ throw this.dispatchEvent({
1506
+ type: "error",
1507
+ message: e.message,
1508
+ filename: n
1509
+ }), e;
1510
+ }
1511
+ }
1512
+ async loadAssetFromUrl(t, n = {}) {
1513
+ let { filename: r = K(t), cacheKey: i = t, cachePolicy: a, ...o } = n;
1514
+ if (!this.getFileFormat(r)) throw this.formatError(r);
1515
+ this._loadCancelled = !1;
1516
+ let s = e._isNetworkUrl(t), c = `Downloading ${r}...`, l = new AbortController();
1517
+ this._urlAbort = l, g({
1518
+ isLoading: !0,
1519
+ status: c,
1520
+ progress: 2,
1521
+ canCancel: s,
1522
+ loadedBytes: 0,
1523
+ totalBytes: 0
1524
+ });
1525
+ let u;
1526
+ try {
1527
+ u = await this.downloads.fetch(t, {
1528
+ key: i,
1529
+ name: r,
1530
+ policy: a,
1531
+ signal: l.signal,
1532
+ onProgress: this._downloadProgress(c, s)
1533
+ });
1534
+ } catch (e) {
1535
+ throw this._isCancellation(e) ? this._cancellationError() : e;
1536
+ } finally {
1537
+ this._urlAbort = null;
1538
+ }
1539
+ this._downloadComplete();
1540
+ try {
1541
+ return await this.loadAssetFromFile(u.file, o);
1542
+ } catch (e) {
1543
+ throw e?.code === "ARCHIVE_NEEDS_ELEMENT" && (e.file = u.file), e;
1544
+ } finally {
1545
+ u.release();
1546
+ }
1547
+ }
1548
+ async loadModelFromFile(e, t) {
1549
+ let n = this.storage ? this._keyed("file", E(await Oe(e))) : null, r = await this._loadModelFileByExtension(e, t);
1550
+ return this._sourceKey = n, r;
1551
+ }
1552
+ async _loadModelFileByExtension(e, t) {
1553
+ let n = t.split(".").pop().toLowerCase();
1554
+ if (n === "glb" || n === "gltf") return await this.loadGLBFromArrayBuffer(await this.readFileAsArrayBuffer(e), t);
1555
+ let r = this._formats.get(n);
1556
+ if (r?.type !== "model") throw this.formatError(t);
1557
+ return await this._loadModelWithFormat(r, e, t);
1558
+ }
1559
+ async _loadModelWithFormat(e, t, n) {
1560
+ try {
1561
+ g({
1562
+ isLoading: !0,
1563
+ status: `Processing ${e.label} Data...`,
1564
+ progress: 5
1565
+ }), await new Promise((e) => setTimeout(e, 0));
1566
+ let { model: r, result: i = r } = await e.parse(t, {
1567
+ filename: n,
1568
+ cache: this.loaderCache
1569
+ });
1570
+ return this.releaseTargetModel(), this.targetModel = r, g({
1571
+ isLoading: !0,
1572
+ status: "Processing Data...",
1573
+ progress: 10
1574
+ }), await this.onModelLoad(this.targetModel), this.dispatchEvent({
1575
+ type: "load",
1576
+ model: r,
1577
+ filename: n
1578
+ }), i;
1579
+ } catch (t) {
1580
+ throw console.error(`Error loading ${e.label}:`, t), this.dispatchEvent({
1581
+ type: "error",
1582
+ message: t.message,
1583
+ filename: n
1584
+ }), t;
1585
+ }
1586
+ }
1587
+ async loadEnvironmentFromFile(e, t) {
1588
+ let n = URL.createObjectURL(e);
1589
+ this.uploadedFileInfo = {
1590
+ name: t,
1591
+ type: e.type,
1592
+ size: e.size
1593
+ };
1594
+ try {
1595
+ let r = await this.loadEnvironment(n);
1596
+ return ae(r, E(await Oe(e))), this.dispatchEvent({
1597
+ type: "load",
1598
+ texture: r,
1599
+ filename: t
1600
+ }), r;
1601
+ } finally {
1602
+ URL.revokeObjectURL(n);
1603
+ }
1604
+ }
1605
+ async loadEnvironment(t) {
1606
+ this._loadCancelled = !1;
1607
+ try {
1608
+ this.dispatchEvent({
1609
+ type: "beforeEnvironmentLoad",
1610
+ url: t
1611
+ });
1612
+ let n;
1613
+ if (t.startsWith("blob:")) n = await this.loadEnvironmentFromBlob(t);
1614
+ else {
1615
+ let e = t.split(/[?#]/)[0].split(".").pop().toLowerCase();
1616
+ n = await this.loadEnvironmentByExtension(t, e);
1617
+ }
1618
+ return n.generateMipmaps = !0, e._isNetworkUrl(t) && ae(n, t), this.applyEnvironmentToScene(n), this.dispatchEvent({
1619
+ type: "load",
1620
+ texture: n,
1621
+ url: t,
1622
+ filename: t.split(/[?#]/)[0].split("/").pop()
1623
+ }), n;
1624
+ } catch (e) {
1625
+ throw this._isCancellation(e) ? this._cancellationError() : (console.error("Error loading environment:", e), this.dispatchEvent({
1626
+ type: "error",
1627
+ message: e.message,
1628
+ filename: t
1629
+ }), e);
1630
+ }
1631
+ }
1632
+ async loadEnvironmentFromBlob(e) {
1633
+ let t = await (await fetch(e)).blob(), n = this.determineEnvironmentExtension(t, e), r = URL.createObjectURL(t);
1634
+ try {
1635
+ return await this.loadEnvironmentByExtension(r, n);
1636
+ } finally {
1637
+ URL.revokeObjectURL(r);
1638
+ }
1639
+ }
1640
+ determineEnvironmentExtension(e, t) {
1641
+ let n;
1642
+ if (e.type === "image/x-exr" || e.type.includes("exr")) n = "exr";
1643
+ else if (e.type === "image/vnd.radiance" || e.type.includes("hdr")) n = "hdr";
1644
+ else {
1645
+ let e = t.split("/").pop();
1646
+ if (e) {
1647
+ let t = e.match(/\.([^.]+)$/);
1648
+ t && (n = t[1].toLowerCase());
1649
+ }
1650
+ }
1651
+ return !n && this.uploadedFileInfo && (n = this.uploadedFileInfo.name.split(".").pop().toLowerCase()), n;
1652
+ }
1653
+ async loadEnvironmentByExtension(t, n, { loader: r = null } = {}) {
1654
+ let i = this._formats.get(n);
1655
+ if (!r && i?.type === "environment" && (r = this.loaderCache[n] ??= await i.createLoader(this._loadingManager)), !r && n === "hdr" && (r = this.loaderCache.hdr ??= new Dt(this._loadingManager).setDataType(nt)), !r && Dn[n]) throw this.formatError(`environment.${n}`);
1656
+ let a = e._isNetworkUrl(t), o = "Downloading Environment...", c = await this._viaCache(t, o, a), l = c.cached ? void 0 : this._downloadProgress(o, a), u;
1657
+ try {
1658
+ r ? u = await r.loadAsync(c.url, l) : s().decodeImage ? (u = await mn(c.url, `image/${n === "jpg" ? "jpeg" : n}`), u.colorSpace = B) : (this.loaderCache.texture || (this.loaderCache.texture = new xt(this._loadingManager)), u = await this.loaderCache.texture.loadAsync(c.url, l), u.colorSpace = B);
1659
+ } finally {
1660
+ c.release();
1661
+ }
1662
+ return this._downloadComplete("Processing Environment...", 62), u.mapping = tt, u.minFilter = rt, u.magFilter = rt, u;
1663
+ }
1664
+ applyEnvironmentToScene(e) {
1665
+ this.scene.background = e, this.scene.environment = e;
1666
+ }
1667
+ async createGLTFLoader() {
1668
+ let e = Tn(new Et(this._loadingManager), this.renderer), t = (e, t) => this._reportImageFailure(e, t);
1669
+ return s().decodeImage ? e.register((e) => gn(e, t)) : i() || e.register((e) => hn(e, t)), e.register((e) => vn(e)), e;
1670
+ }
1671
+ _reportImageFailure(e, t) {
1672
+ try {
1673
+ this._issues?.record(x.TEXTURE_BUILD_FAILED, `image ${e} could not be decoded (${t?.message ?? t}) — the surfaces using it render untextured`, {
1674
+ image: e,
1675
+ cause: String(t?.message ?? t)
1676
+ });
1677
+ } catch (e) {
1678
+ this._deferredError ??= e;
1679
+ }
1680
+ }
1681
+ _throwDeferred() {
1682
+ let e = this._deferredError;
1683
+ if (this._deferredError = null, e) throw e;
1684
+ }
1685
+ _disposeGLTFLoader(e) {
1686
+ e && (e.dracoLoader?.dispose(), e.ktx2Loader?.dispose());
1687
+ }
1688
+ async loadExampleModels(e, t) {
1689
+ if (!t || !t[e]) throw Error(`No model file at index ${e}`);
1690
+ let n = `${t[e].url}`;
1691
+ return await this.loadModel(n);
1692
+ }
1693
+ async loadModel(t, n = {}) {
1694
+ this._loadCancelled = !1;
1695
+ let r = await this.createGLTFLoader(), i = e._isNetworkUrl(t), a = null;
1696
+ try {
1697
+ g({
1698
+ isLoading: !0,
1699
+ status: "Downloading Model...",
1700
+ progress: 2,
1701
+ canCancel: i,
1702
+ loadedBytes: 0,
1703
+ totalBytes: 0
1704
+ }), a = await this._viaCache(t, "Downloading Model...", i, n), a.cached && r.setResourcePath(I.extractUrlBase(t));
1705
+ let e = await d(() => r.loadAsync(a.url, a.cached ? void 0 : this._downloadProgress("Downloading Model...", i)));
1706
+ return this._downloadComplete(), this._throwDeferred(), this.releaseTargetModel(), this._sourceKey = i ? this._keyed("url", n.cacheKey ?? t) : null, this.targetModel = e.scene, this.animations = e.animations || [], this.sceneMetadata = Ae(e), await this.onModelLoad(this.targetModel), this.dispatchEvent({
1707
+ type: "load",
1708
+ model: e.scene,
1709
+ filename: t.split("/").pop()
1710
+ }), e;
1711
+ } catch (e) {
1712
+ throw this._isCancellation(e) ? this._cancellationError() : (console.error("Error loading model:", e), this.dispatchEvent({
1713
+ type: "error",
1714
+ message: e.message,
1715
+ filename: t
1716
+ }), e);
1717
+ } finally {
1718
+ a?.release(), this._disposeGLTFLoader(r);
1719
+ }
1720
+ }
1721
+ _processAndParent(e) {
1722
+ this.processModelObjects(e), this.scene.add(e), e.updateMatrixWorld(!0);
1723
+ }
1724
+ async appendModel(t, n = {}) {
1725
+ this._loadCancelled = !1;
1726
+ let r = await this.createGLTFLoader(), i = e._isNetworkUrl(t), a = null;
1727
+ try {
1728
+ g({
1729
+ isLoading: !0,
1730
+ status: "Downloading Model...",
1731
+ progress: 2,
1732
+ canCancel: i,
1733
+ loadedBytes: 0,
1734
+ totalBytes: 0
1735
+ }), a = await this._viaCache(t, "Downloading Model...", i, n), a.cached && r.setResourcePath(I.extractUrlBase(t));
1736
+ let e = await d(() => r.loadAsync(a.url, a.cached ? void 0 : this._downloadProgress("Downloading Model...", i)));
1737
+ return this._downloadComplete(), this._throwDeferred(), this._appended = !0, this._processAndParent(e.scene), {
1738
+ root: e.scene,
1739
+ animations: e.animations || []
1740
+ };
1741
+ } catch (e) {
1742
+ throw this._isCancellation(e) ? this._cancellationError() : e;
1743
+ } finally {
1744
+ a?.release(), this._disposeGLTFLoader(r);
1745
+ }
1746
+ }
1747
+ appendObject3D(e, t = "object3d") {
1748
+ this._appended = !0;
1749
+ let n = this._adoptExternalObject(e);
1750
+ return n.name = e.name || t, this._processAndParent(n), { root: n };
1751
+ }
1752
+ removeModelRoot(e) {
1753
+ e && (e.userData.__rayzeeExternal ? (re(e), e.parent?.remove(e)) : se(e));
1754
+ }
1755
+ async loadGLBFromArrayBuffer(e, t = "model.glb") {
1756
+ let n = await this.createGLTFLoader();
1757
+ try {
1758
+ g({
1759
+ isLoading: !0,
1760
+ status: "Processing GLB Data...",
1761
+ progress: 5
1762
+ }), await new Promise((e) => setTimeout(e, 0));
1763
+ let r = await d(() => n.parseAsync(e, ""));
1764
+ return this._throwDeferred(), this.releaseTargetModel(), this.targetModel = r.scene, this.animations = r.animations || [], this.sceneMetadata = Ae(r), g({
1765
+ isLoading: !0,
1766
+ status: "Processing Data...",
1767
+ progress: 10
1768
+ }), await this.onModelLoad(this.targetModel), this.dispatchEvent({
1769
+ type: "load",
1770
+ model: r.scene,
1771
+ filename: t
1772
+ }), r;
1773
+ } catch (e) {
1774
+ throw console.error("Error loading GLB:", e), this.dispatchEvent({
1775
+ type: "error",
1776
+ message: e.message,
1777
+ filename: t
1778
+ }), e;
1779
+ } finally {
1780
+ this._disposeGLTFLoader(n);
1781
+ }
1782
+ }
1783
+ async loadObject3D(e, t = "object3d") {
1784
+ this.releaseTargetModel();
1785
+ let n = this._adoptExternalObject(e);
1786
+ return n.name = e.name || t, this.targetModel = n, g({
1787
+ isLoading: !0,
1788
+ status: "Processing Data...",
1789
+ progress: 10
1790
+ }), await this.onModelLoad(this.targetModel), this.dispatchEvent({
1791
+ type: "load",
1792
+ model: n,
1793
+ filename: t
1794
+ }), n;
1795
+ }
1796
+ async onModelLoad(e) {
1797
+ let t = new u("onModelLoad");
1798
+ t.start("Camera extraction");
1799
+ let n = this.extractCamerasFromModel(e);
1800
+ t.end("Camera extraction"), t.start("Camera setup");
1801
+ let r = new Je().setFromObject(e), i = r.getCenter(new V()), a = r.getSize(new V());
1802
+ this.controls?.target.copy(i);
1803
+ let o = Math.max(a.x, a.y, a.z), s = this.camera.fov * (Math.PI / 180), c = Math.abs(o / Math.sin(s / 2) / 2), l = Math.PI / 6, d = new V(Math.cos(l) * c, c / Math.sqrt(2), Math.sin(l) * c);
1804
+ if (this.camera.position.copy(d.add(i)), this.camera.lookAt(i), this.camera.near = o / 100, this.camera.far = o * 100, this.camera.updateProjectionMatrix(), this.controls && (this.controls.maxDistance = c * 10, this.controls.saveState(), this.controls.update()), t.end("Camera setup"), this.floorPlane) {
1805
+ let e = r.min.y;
1806
+ this.floorPlane.position.y = e, this.floorPlane.rotation.x = -Math.PI / 2, this.floorPlane.scale.setScalar(o * 5);
1807
+ }
1808
+ t.start("Process model objects"), this.processModelObjects(e), t.end("Process model objects"), t.start("Scene add"), this.scene.add(e), t.end("Scene add");
1809
+ let f = o;
1810
+ return this.sceneSize.copy(a), t.start("setupPathTracing"), await this.setupPathTracing(e, f), t.end("setupPathTracing"), t.print(), this.dispatchEvent({
1811
+ type: "modelProcessed",
1812
+ model: e,
1813
+ cameras: n,
1814
+ sceneData: {
1815
+ center: i,
1816
+ size: a,
1817
+ maxDim: o,
1818
+ sceneScale: f
1819
+ }
1820
+ }), this.dispatchEvent({ type: "SceneRebuild" }), {
1821
+ center: i,
1822
+ size: a,
1823
+ maxDim: o,
1824
+ sceneScale: f
1825
+ };
1826
+ }
1827
+ extractCamerasFromModel(e) {
1828
+ let t = [];
1829
+ return e.updateWorldMatrix(!0, !0), e.traverse((e) => {
1830
+ if (e.isCamera) {
1831
+ let n = e.clone();
1832
+ n.userData.__rayzeeSourceUuid = e.uuid, e.getWorldPosition(n.position), e.getWorldQuaternion(n.quaternion), e.getWorldScale(n.scale), n.scale.set(Math.sign(n.scale.x) || 1, Math.sign(n.scale.y) || 1, Math.sign(n.scale.z) || 1), (!n.name || n.name === "") && (n.name = `Model Camera ${t.length + 1}`), n.isPerspectiveCamera && (n.aspect = this.camera.aspect, n.updateProjectionMatrix()), t.push(n);
1833
+ }
1834
+ }), t;
1835
+ }
1836
+ processModelObjects(e) {
1837
+ let t = [], n = [];
1838
+ e.traverse((e) => {
1839
+ let r = e.userData;
1840
+ e.isRectAreaLight && !r.__radianceConverted && (e.intensity *= An(e, e.width, e.height, r), r.__radianceConverted = !0), (e.isPointLight || e.isSpotLight) && !r.__candelaConverted && (e.intensity *= 4 * Math.PI / kn, r.__candelaConverted = !0), e.isDirectionalLight && !r.__luxConverted && (e.intensity /= kn, r.__luxConverted = !0);
1841
+ let i = e.name.startsWith("RectAreaLightPlaceholder");
1842
+ if (i && !(r.name && r.type === "RectAreaLight") && !e.parent?.name?.startsWith("RectAreaLightPlaceholder") && n.push(e.name), i && r.name && r.type === "RectAreaLight") {
1843
+ let t = r.normalize ?? !0, n = r.shape ?? "rectangle", i = r.intensity * An(e, r.width, r.height, r), a = new z(new Ze(...r.color), i * this._profile.areaLightIntensityScale, r.width, r.height);
1844
+ a.userData.normalize = t, a.userData.spread = Number.isFinite(r.spread) ? r.spread : Math.PI, a.userData.shape = n, a.userData.__radianceConverted = !0, a.name = r.name, e.add(a);
1845
+ }
1846
+ e.isMesh && Array.isArray(e.material) && t.push(e);
1847
+ }), n.length && this._issues?.record(x.LIGHT_PLACEHOLDER_SKIPPED, `${n.length} area-light placeholder(s) lack userData.name or userData.type 'RectAreaLight' — no light was made for them`, {
1848
+ count: n.length,
1849
+ names: n.slice(0, 10)
1850
+ });
1851
+ let r = e.userData.__rayzeeExternal === !0;
1852
+ for (let e of t) {
1853
+ if (!e.parent) continue;
1854
+ console.log("Found multi-material mesh:", e.name), r && (e.geometry = On(e.geometry));
1855
+ let t = Ot(e);
1856
+ for (let e of t.children) e.geometry.userData.__rayzeeOwned = !0;
1857
+ e.parent.add(t), e.parent.remove(e);
1858
+ }
1859
+ }
1860
+ async setupPathTracing(e, t) {
1861
+ this.sceneScale = t;
1862
+ }
1863
+ createFloorPlane() {
1864
+ this.floorPlane = new ot(new Xe(), new st({
1865
+ transparent: !1,
1866
+ color: 3158064,
1867
+ roughness: 1,
1868
+ metalness: 0,
1869
+ opacity: 0,
1870
+ transmission: 0
1871
+ })), this.floorPlane.name = "Ground", this.floorPlane.visible = !1, this.scene.add(this.floorPlane);
1872
+ }
1873
+ setFloorPlane(e) {
1874
+ this.floorPlane = e;
1875
+ }
1876
+ getSceneScale() {
1877
+ return this.sceneScale;
1878
+ }
1879
+ getSceneSize() {
1880
+ return this.sceneSize.clone();
1881
+ }
1882
+ getTargetModel() {
1883
+ return this.targetModel;
1884
+ }
1885
+ getSupportedFormats(e = null) {
1886
+ let t = {
1887
+ ...En,
1888
+ ...this._archiveFormats
1889
+ };
1890
+ for (let [e, { type: n, name: r }] of this._formats) t[e] = {
1891
+ type: n,
1892
+ name: r
1893
+ };
1894
+ if (e) {
1895
+ let n = {};
1896
+ for (let [r, i] of Object.entries(t)) i.type === e && (n[r] = i);
1897
+ return n;
1898
+ }
1899
+ return t;
1900
+ }
1901
+ dispose() {
1902
+ for (let e in this.loaderCache) {
1903
+ let t = this.loaderCache[e];
1904
+ t && typeof t.dispose == "function" && t.dispose();
1905
+ }
1906
+ this.loaderCache = {}, this._listeners = void 0, this._loadingManager.onError = void 0, this._issues = null, this._urlAbort?.abort(), this._urlAbort = null, this.storage = null, this._downloads = null, this.archives?.release(), this.archives = null, this._archiveLoader = null, this.releaseTargetModel();
1907
+ }
1908
+ removeAllEventListeners() {
1909
+ this._listeners = void 0;
1910
+ }
1911
+ }, Mn = {
1912
+ addEventListener() {},
1913
+ removeEventListener() {},
1914
+ dispatchEvent() {
1915
+ return !0;
1916
+ }
1917
+ }, Nn = class {
1918
+ constructor(e) {
1919
+ this.canvas = e, this._configuration = null, this._texture = null;
1920
+ }
1921
+ configure(e) {
1922
+ this.unconfigure(), this._configuration = e;
1923
+ }
1924
+ unconfigure() {
1925
+ this._texture?.destroy(), this._texture = null, this._configuration = null;
1926
+ }
1927
+ getConfiguration() {
1928
+ return this._configuration;
1929
+ }
1930
+ getCurrentTexture() {
1931
+ if (!this._configuration) throw Error("HeadlessGPUContext: getCurrentTexture() before configure()");
1932
+ let e = Math.max(1, this.canvas.width), t = Math.max(1, this.canvas.height);
1933
+ if (this._texture?.width !== e || this._texture?.height !== t) {
1934
+ let { device: n, format: r, usage: i } = this._configuration;
1935
+ this._texture?.destroy(), this._texture = n.createTexture({
1936
+ label: "headless-canvas",
1937
+ size: [e, t],
1938
+ format: r,
1939
+ usage: i
1940
+ });
1941
+ }
1942
+ return this._texture;
1943
+ }
1944
+ };
1945
+ function Pn(e = 1, t = 1) {
1946
+ let n = {
1947
+ ...Mn,
1948
+ defaultView: null
1949
+ }, r = {
1950
+ ...Mn,
1951
+ isHeadlessCanvas: !0,
1952
+ width: e,
1953
+ height: t,
1954
+ clientWidth: 0,
1955
+ clientHeight: 0,
1956
+ style: {},
1957
+ parentNode: null,
1958
+ ownerDocument: n,
1959
+ getRootNode: () => n,
1960
+ getBoundingClientRect() {
1961
+ return {
1962
+ x: 0,
1963
+ y: 0,
1964
+ left: 0,
1965
+ top: 0,
1966
+ right: this.width,
1967
+ bottom: this.height,
1968
+ width: this.width,
1969
+ height: this.height
1970
+ };
1971
+ },
1972
+ setPointerCapture() {},
1973
+ releasePointerCapture() {},
1974
+ hasPointerCapture: () => !1,
1975
+ focus() {},
1976
+ getContext: (e) => e === "webgpu" ? i : null
1977
+ }, i = new Nn(r);
1978
+ return r;
1979
+ }
1980
+ //#endregion
1981
+ //#region src/managers/ViewCamera.js
1982
+ var Fn = class extends ft {
1983
+ constructor(e, t, n, r) {
1984
+ super(e, t, n, r), this.orthographic = !1, this.orthoHalfHeight = 1;
1985
+ }
1986
+ get isPerspectiveCamera() {
1987
+ return !this.orthographic;
1988
+ }
1989
+ set isPerspectiveCamera(e) {}
1990
+ get isOrthographicCamera() {
1991
+ return this.orthographic;
1992
+ }
1993
+ get top() {
1994
+ return this.orthoHalfHeight;
1995
+ }
1996
+ get bottom() {
1997
+ return -this.orthoHalfHeight;
1998
+ }
1999
+ get right() {
2000
+ return this.orthoHalfHeight * this.aspect;
2001
+ }
2002
+ get left() {
2003
+ return -this.orthoHalfHeight * this.aspect;
2004
+ }
2005
+ updateProjectionMatrix() {
2006
+ this.orthographic ? dt.prototype.updateProjectionMatrix.call(this) : super.updateProjectionMatrix();
2007
+ }
2008
+ copy(e, t) {
2009
+ return super.copy(e, t), this.orthographic = e.orthographic === !0, this.orthoHalfHeight = e.orthoHalfHeight ?? this.orthoHalfHeight, this;
2010
+ }
2011
+ }, In = "__rayzeeUserLight", Ln = {
2012
+ DirectionalLight: $e,
2013
+ PointLight: pt,
2014
+ SpotLight: yt,
2015
+ RectAreaLight: z
2016
+ }, Rn = class extends F {
2017
+ constructor(e, t, n, r = {}) {
2018
+ super(), this.scene = e, this.sceneHelpers = t, this.pathTracer = n, this._onReset = r.onReset || null, this._onLightRemoved = r.onLightRemoved || null;
2019
+ }
2020
+ addLight(e) {
2021
+ let t = {
2022
+ DirectionalLight: {
2023
+ position: [
2024
+ 1,
2025
+ 1,
2026
+ 1
2027
+ ],
2028
+ intensity: 1,
2029
+ color: "#ffffff"
2030
+ },
2031
+ PointLight: {
2032
+ position: [
2033
+ 0,
2034
+ 2,
2035
+ 0
2036
+ ],
2037
+ intensity: 1e3,
2038
+ color: "#ffffff"
2039
+ },
2040
+ SpotLight: {
2041
+ position: [
2042
+ 0,
2043
+ 1,
2044
+ 0
2045
+ ],
2046
+ intensity: 1e3,
2047
+ color: "#ffffff",
2048
+ angle: 15
2049
+ },
2050
+ RectAreaLight: {
2051
+ position: [
2052
+ 0,
2053
+ 2,
2054
+ 0
2055
+ ],
2056
+ intensity: 100,
2057
+ color: "#ffffff",
2058
+ width: 2,
2059
+ height: 2
2060
+ }
2061
+ }[e];
2062
+ if (!t) return null;
2063
+ let n;
2064
+ if (e === "DirectionalLight") n = new $e(t.color, t.intensity), n.position.fromArray(t.position);
2065
+ else if (e === "PointLight") n = new pt(t.color, t.intensity), n.position.fromArray(t.position);
2066
+ else if (e === "SpotLight") {
2067
+ n = new yt(t.color, t.intensity), n.position.fromArray(t.position), n.angle = L.degToRad(t.angle);
2068
+ let e = new R();
2069
+ this.scene.add(e), n.target = e;
2070
+ } else e === "RectAreaLight" && (n = new z(t.color, t.intensity, t.width, t.height), n.position.fromArray(t.position), n.lookAt(0, 0, 0), n.userData.normalize = !0, n.userData.spread = Math.PI, n.userData.shape = "rectangle");
2071
+ n.userData[In] = !0, n.userData.temperature = 6500, n.userData.useTemperature = !1, n.userData.exposure = 0;
2072
+ let r = this.scene.getObjectsByProperty("isLight", !0).length;
2073
+ return n.name = `${e.replace("Light", "")} ${r + 1}`, this.scene.add(n), this.updateLights(), this._syncHelpers(), this._onReset?.(), this._buildDescriptor(n);
2074
+ }
2075
+ getLight(e) {
2076
+ let t = this.scene.getObjectByProperty("uuid", e);
2077
+ return t?.isLight ? t : null;
2078
+ }
2079
+ setIntensity(e, t) {
2080
+ let n = this.getLight(e);
2081
+ return n ? (n.intensity = t, this.updateLights(), this._onReset?.(), !0) : !1;
2082
+ }
2083
+ removeLight(e) {
2084
+ let t = this.scene.getObjectByProperty("uuid", e);
2085
+ return !t || !t.isLight ? !1 : (this._onLightRemoved?.(t), this.sceneHelpers.remove(t), t.target && t.target.removeFromParent(), t.removeFromParent(), this.updateLights(), this._onReset?.(), !0);
2086
+ }
2087
+ clearLights() {
2088
+ this.sceneHelpers.clear(), this._removeAllLights(), this.updateLights(), this._onReset?.();
2089
+ }
2090
+ getLights() {
2091
+ return this.scene.getObjectsByProperty("isLight", !0).map((e) => this._buildDescriptor(e));
2092
+ }
2093
+ updateLights() {
2094
+ this.pathTracer?.updateLights(), this.sceneHelpers?.visible && this.sceneHelpers.update();
2095
+ }
2096
+ transferSceneLights(e, { keepUserLights: t = !1 } = {}) {
2097
+ this._removeAllLights(t ? (e) => !e.userData?.[In] : void 0);
2098
+ let n = e.getObjectsByProperty("isLight", !0);
2099
+ if (!n || n.length === 0) {
2100
+ this.updateLights();
2101
+ return;
2102
+ }
2103
+ for (let e of n) {
2104
+ let t = e.clone();
2105
+ if (e.updateWorldMatrix(!0, !1), e.getWorldPosition(t.position), e.getWorldQuaternion(t.quaternion), e.getWorldScale(t.scale), t.isRectAreaLight && (t.width *= t.scale.x, t.height *= t.scale.y, t.scale.set(1, 1, 1)), (e.isSpotLight || e.isDirectionalLight) && e.target) {
2106
+ let n = new R();
2107
+ e.target.updateWorldMatrix(!0, !1), e.target.getWorldPosition(n.position), this.scene.add(n), t.target = n;
2108
+ }
2109
+ this.scene.add(t);
2110
+ }
2111
+ this.updateLights(), this._syncHelpers();
2112
+ }
2113
+ setShowLightHelper(e) {
2114
+ this.sceneHelpers.visible = e, e ? this._syncHelpers() : this.sceneHelpers.clear();
2115
+ }
2116
+ serialize() {
2117
+ return this.scene.getObjectsByProperty("isLight", !0).map((e) => {
2118
+ let t = {
2119
+ type: e.type,
2120
+ name: e.name,
2121
+ visible: e.visible,
2122
+ color: [
2123
+ e.color.r,
2124
+ e.color.g,
2125
+ e.color.b
2126
+ ],
2127
+ intensity: e.intensity,
2128
+ position: e.position.toArray(),
2129
+ quaternion: e.quaternion.toArray(),
2130
+ scale: e.scale.toArray(),
2131
+ userData: r(e.userData) ?? {}
2132
+ };
2133
+ return e.isSpotLight && Object.assign(t, {
2134
+ angle: e.angle,
2135
+ penumbra: e.penumbra,
2136
+ distance: e.distance,
2137
+ decay: e.decay
2138
+ }), e.isPointLight && Object.assign(t, {
2139
+ distance: e.distance,
2140
+ decay: e.decay
2141
+ }), e.isRectAreaLight && Object.assign(t, {
2142
+ width: e.width,
2143
+ height: e.height
2144
+ }), e.target && (e.isSpotLight || e.isDirectionalLight) && (t.target = e.target.position.toArray()), t;
2145
+ });
2146
+ }
2147
+ restore(e) {
2148
+ this.sceneHelpers?.clear(), this._removeAllLights();
2149
+ let t = [];
2150
+ for (let n of e ?? []) {
2151
+ let e = Ln[n.type];
2152
+ if (!e) continue;
2153
+ let r = new e();
2154
+ r.name = n.name ?? "", r.visible = n.visible !== !1, r.color.setRGB(...n.color), r.intensity = n.intensity, r.position.fromArray(n.position), r.quaternion.fromArray(n.quaternion), r.scale.fromArray(n.scale ?? [
2155
+ 1,
2156
+ 1,
2157
+ 1
2158
+ ]), r.userData = f(n.userData) ?? {};
2159
+ for (let e of [
2160
+ "angle",
2161
+ "penumbra",
2162
+ "distance",
2163
+ "decay",
2164
+ "width",
2165
+ "height"
2166
+ ]) typeof n[e] == "number" && (r[e] = n[e]);
2167
+ if (n.target) {
2168
+ let e = new R();
2169
+ e.position.fromArray(n.target), this.scene.add(e), r.target = e;
2170
+ }
2171
+ this.scene.add(r), t.push(r);
2172
+ }
2173
+ return this.updateLights(), this._syncHelpers(), this._onReset?.(), t;
2174
+ }
2175
+ add(e) {
2176
+ return this.addLight(e);
2177
+ }
2178
+ remove(e) {
2179
+ return this.removeLight(e);
2180
+ }
2181
+ clear() {
2182
+ this.clearLights();
2183
+ }
2184
+ getAll() {
2185
+ return this.getLights();
2186
+ }
2187
+ sync() {
2188
+ this.updateLights();
2189
+ }
2190
+ showHelpers(e) {
2191
+ this.setShowLightHelper(e);
2192
+ }
2193
+ dispose() {
2194
+ this._disposed || (this._disposed = !0, this._onLightRemoved = null, this.sceneHelpers?.clear(), this._removeAllLights(), this._onReset = null, this.pathTracer = null, this.sceneHelpers = null, this.scene = null);
2195
+ }
2196
+ _removeAllLights(e) {
2197
+ this.scene.getObjectsByProperty("isLight", !0).filter((t) => !e || e(t)).forEach((e) => {
2198
+ this._onLightRemoved?.(e), e.target && this.scene.remove(e.target), this.scene.remove(e);
2199
+ });
2200
+ }
2201
+ _syncHelpers() {
2202
+ if (!this.sceneHelpers.visible) return;
2203
+ let e = this.scene.getObjectsByProperty("isLight", !0);
2204
+ this.sceneHelpers.sync(e);
2205
+ }
2206
+ _buildDescriptor(e) {
2207
+ let t = 0;
2208
+ e.type === "SpotLight" && e.angle !== void 0 ? t = L.radToDeg(e.angle) : e.type === "DirectionalLight" && (t = L.radToDeg(e.userData?.angle ?? 0));
2209
+ let n = {
2210
+ uuid: e.uuid,
2211
+ name: e.name,
2212
+ type: e.type,
2213
+ visible: e.visible,
2214
+ intensity: e.intensity,
2215
+ color: `#${e.color.getHexString()}`,
2216
+ position: [
2217
+ e.position.x,
2218
+ e.position.y,
2219
+ e.position.z
2220
+ ],
2221
+ angle: t,
2222
+ temperature: e.userData?.temperature ?? 6500,
2223
+ useTemperature: e.userData?.useTemperature ?? !1,
2224
+ exposure: e.userData?.exposure ?? 0
2225
+ };
2226
+ if (e.type === "RectAreaLight") {
2227
+ n.width = e.width, n.height = e.height, n.normalize = e.userData?.normalize ?? !0, n.spread = L.radToDeg(e.userData?.spread ?? Math.PI);
2228
+ let t = e.userData?.shape;
2229
+ n.shape = t === "square" || t === "rectangle" || t === "disk" || t === "ellipse" ? t : t === 1 ? "ellipse" : "rectangle";
2230
+ let r = e.getWorldDirection(e.position.clone());
2231
+ n.target = [
2232
+ e.position.x + r.x,
2233
+ e.position.y + r.y,
2234
+ e.position.z + r.z
2235
+ ];
2236
+ } else e.type === "SpotLight" && e.target ? (n.target = [
2237
+ e.target.position.x,
2238
+ e.target.position.y,
2239
+ e.target.position.z
2240
+ ], n.distance = e.distance ?? 0, n.penumbra = e.penumbra ?? 0, n.decay = e.decay ?? 2) : e.type === "PointLight" && (n.distance = e.distance ?? 0, n.decay = e.decay ?? 2);
2241
+ return (e.type === "SpotLight" || e.type === "DirectionalLight") && e.userData?.gobo && (n.gobo = e.userData.gobo.name, n.goboIntensity = e.userData.gobo.intensity, n.goboInverted = !!e.userData.gobo.inverted, e.type === "DirectionalLight" && (n.goboScale = e.userData.gobo.scale ?? 5)), e.type === "SpotLight" && e.userData?.ies && (n.ies = e.userData.ies.name, n.iesIntensity = e.userData.ies.intensity ?? 1, n.fixtureLumens = e.userData.ies.fixtureLumens ?? null), n;
2242
+ }
2243
+ }, zn = ({ element: e, pbrtEntry: t } = {}) => ({
2244
+ ...e === void 0 ? {} : { element: e },
2245
+ ...t === void 0 ? {} : { pbrtEntry: t }
2246
+ }), Q = /* @__PURE__ */ new WeakMap(), Bn = new Set([...Object.values(m), ...Object.values(p)]), Vn = /* @__PURE__ */ new Set();
2247
+ async function Hn(e, t) {
2248
+ if (!t || typeof self < "u") return e.init();
2249
+ globalThis.self = {
2250
+ requestAnimationFrame: () => 0,
2251
+ cancelAnimationFrame: () => {}
2252
+ };
2253
+ try {
2254
+ return await e.init();
2255
+ } finally {
2256
+ delete globalThis.self;
2257
+ }
2258
+ }
2259
+ var $ = ge("engine");
2260
+ function Un() {
2261
+ let e = new Float32Array(16);
2262
+ return new Uint32Array(e.buffer)[3] = fe.TRIANGLE_LEAF, e;
2263
+ }
2264
+ function Wn(e, t) {
2265
+ e.lost.then((e) => {
2266
+ t.app && t.app._handleDeviceLost(e);
2267
+ });
2268
+ }
2269
+ var Gn = /swiftshader|llvmpipe|lavapipe|basic render|microsoft basic|warp/i;
2270
+ function Kn(e) {
2271
+ let t = e.info ?? {}, n = `${t.vendor ?? ""} ${t.architecture ?? ""} ${t.device ?? ""} ${t.description ?? ""}`;
2272
+ return {
2273
+ vendor: t.vendor ?? "",
2274
+ architecture: t.architecture ?? "",
2275
+ device: t.device ?? "",
2276
+ description: t.description ?? "",
2277
+ isSoftware: t.isFallbackAdapter === !0 || e.isFallbackAdapter === !0 || Gn.test(n)
2278
+ };
2279
+ }
2280
+ var qn = class extends F {
2281
+ constructor(e, t = {}) {
2282
+ super(), this._headless = t.headless === !0 || !e, e ??= Pn();
2283
+ try {
2284
+ Q.get(e)?.dispose();
2285
+ } catch (e) {
2286
+ $.warn("prior canvas owner dispose failed", e);
2287
+ }
2288
+ Q.set(e, this), this.canvas = e, this._autoResize = !this._headless && t.autoResize !== !1, this._maxSceneBytes = t.maxSceneBytes, this._hostMemoryGB = t.hostMemoryGB, this._storageOption = t.storage, this._storageOpener = null, this._memorySpill = t.memorySpill === !0, this.storage = null, this._storageRelease = null, this._applySceneMetadataEnabled = t.applySceneMetadata !== !1, this._unlitRestore = null, this._applyingSceneMetadata = !1, this._profile = he(t.profile), this._profileName = t.profile ?? "viewer", this._issues = new _e({
2289
+ strict: t.strict === !0,
2290
+ onIssue: (e) => this.dispatchEvent({
2291
+ type: m.ISSUE,
2292
+ issue: e
2293
+ })
2294
+ }), this.color = new rn({ issues: this._issues }), S(this.color), this.settings = new nn({
2295
+ ...v,
2296
+ environmentRotation: this._profile.environmentRotation,
2297
+ saturation: this._profile.saturation,
2298
+ dofMode: this._profile.dofMode
2299
+ }, { issues: this._issues }), this.renderer = null, this.scene = null, this.meshScene = null, this._sceneHelpers = null, this.assetLoader = null, this._sdf = null, this._maxTextureSize = v.maxTextureSize, this.pipeline = null, this._pendingReservedRenderSize = null, this.stages = {}, this.camera = null, this.lightManager = null, 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 Gt(), this._resizeDebounceTimer = null, this._displayWidth = 0, this._displayHeight = 0, this._renderScale = 1, this._renderWidth = 0, this._renderHeight = 0, 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;
2300
+ }
2301
+ _addTrackedListener(e, t, n) {
2302
+ e && (e.addEventListener(t, n), this._trackedListeners.push({
2303
+ target: e,
2304
+ type: t,
2305
+ handler: n
2306
+ }));
2307
+ }
2308
+ _removeTrackedListeners() {
2309
+ for (let { target: e, type: t, handler: n } of this._trackedListeners) try {
2310
+ e.removeEventListener(t, n);
2311
+ } catch (e) {
2312
+ $.warn("failed to remove listener", t, e);
2313
+ }
2314
+ this._trackedListeners.length = 0;
2315
+ }
2316
+ async init() {
2317
+ let e = this._initStorage();
2318
+ return await this._initRenderer(), this._applyPendingReservedRenderSize(), this.camera = this._createCamera(), this._initScenes(), this._initAssetPipeline(), this._initPipeline(), await this._initManagers(), this._wireEvents(), await e, this._attachStorage(), this.stages.pathTracer.setTriangleData(new Uint32Array(le.FLOATS_PER_TRIANGLE), 0), this.stages.pathTracer.setBVHData(Un()), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setupMaterial(), this.isInitialized = !0, $.debug("WebGPU path tracer app initialized"), this;
2319
+ }
2320
+ async setStorageOpener(e) {
2321
+ this._storageOpener = e, !(!this.isInitialized || this.storage || this._disposed) && (await this._initStorage(), this._attachStorage());
2322
+ }
2323
+ async _initStorage() {
2324
+ let e = this._storageOption ?? (this._issues.strict && !Ce("storage") ? !1 : w().storage);
2325
+ if (e !== !1) {
2326
+ if (e && typeof e == "object") this.storage = e;
2327
+ else {
2328
+ if (!this._storageOpener) {
2329
+ (this._storageOption !== void 0 || Ce("storage")) && this._issues.warn(x.CAPABILITY_MISSING, "on-disk storage needs rayzee/addons/storage: setStorageOpener( acquireSharedStorage )");
2330
+ return;
2331
+ }
2332
+ let { storage: e, reason: t, release: n } = await this._storageOpener(w().cacheNamespace);
2333
+ if (this._disposed) {
2334
+ n();
2335
+ return;
2336
+ }
2337
+ if (!e) {
2338
+ this._issues.warn(x.STORAGE_UNAVAILABLE, `on-disk storage is off: ${t}`, { reason: t });
2339
+ return;
2340
+ }
2341
+ this.storage = e, this._storageRelease = n;
2342
+ }
2343
+ this._addTrackedListener(this.storage, "change", (e) => this.dispatchEvent({
2344
+ type: m.STORAGE_CHANGED,
2345
+ area: e.area
2346
+ })), this._addTrackedListener(this.storage, "issue", (e) => this._issues.warn(e.code, e.message, e.detail));
2347
+ }
2348
+ }
2349
+ _attachStorage() {
2350
+ this.assetLoader && (this.assetLoader.storage = this.storage);
2351
+ }
2352
+ dispatchEvent(e) {
2353
+ super.dispatchEvent(e);
2354
+ let t = p[e.type];
2355
+ t && super.dispatchEvent({
2356
+ ...e,
2357
+ type: t
2358
+ });
2359
+ }
2360
+ addEventListener(e, t) {
2361
+ !Bn.has(e) && !Vn.has(e) && (Vn.add(e), $.warn(`no engine event is named "${e}", so this listener will never fire — see EngineEvents`)), super.addEventListener(e, t);
2362
+ }
2363
+ animate() {
2364
+ if (this._headless) throw Error("a headless app has no render loop — drive it with renderFrames() or renderUntilComplete()");
2365
+ if (this._deviceLost) return;
2366
+ if (this.animationManagerId = requestAnimationFrame(() => this.animate()), this._loadingInProgress || this._sdf?.isProcessing) {
2367
+ this.dispatchEvent({ type: m.FRAME });
2368
+ return;
2369
+ }
2370
+ this._beginFrame();
2371
+ let e = this.needsReset;
2372
+ if (this.needsReset &&= (this.stages.pathTracer?.noteViewChanged(), this.reset(!0), !1), this.camera.updateMatrixWorld(), !this.pathTracerEnabled) {
2373
+ this.renderer.render(this.meshScene, this.camera), this._renderHelperOverlay();
2374
+ return;
2375
+ }
2376
+ if (!this.pauseRendering) {
2377
+ if (this._beforeTrace(), this.stages.pathTracer?.isReady) {
2378
+ if (this.stages.pathTracer.isComplete && this.completion.renderCompleteDispatched) {
2379
+ this._needsDisplayRefresh && (this._needsDisplayRefresh = !1, this.stages.compositor.render(this.pipeline.context), this._renderHelperOverlay()), this.stopAnimation();
2380
+ return;
2381
+ }
2382
+ if (this._holdTrace(e)) {
2383
+ this._renderHelperOverlay(), this.dispatchEvent({ type: m.FRAME });
2384
+ return;
2385
+ }
2386
+ if (this.stages.pathTracer.readbackWait()) {
2387
+ this.dispatchEvent({ type: m.FRAME });
2388
+ return;
2389
+ }
2390
+ this._traceFrame({ liveDenoise: !0 }), this.stages.pathTracer.isComplete && this.completion.markComplete() && (this._renderCompleted(), this.dispatchEvent({
2391
+ type: m.RENDER_COMPLETE,
2392
+ ...this._completionInfo()
2393
+ }));
2394
+ }
2395
+ this._renderHelperOverlay(), this.dispatchEvent({ type: m.FRAME });
2396
+ }
2397
+ }
2398
+ _traceFrame({ liveDenoise: e = !1 } = {}) {
2399
+ let t = this.stages.pathTracer;
2400
+ this.pipeline.render(), this._afterTrace(t, e), t.isComplete || this.completion.updateTime(), this._ensureVRAMWiring();
2401
+ let n = t.vramTracker, r = t.frameCount ?? 0;
2402
+ n && (r <= 1 || r % 30 == 0) && n.measure(), h({
2403
+ timeElapsed: this.completion.timeElapsed,
2404
+ samples: ne(t),
2405
+ memoryUsed: n?.current ?? 0,
2406
+ memoryPeak: n?.peak ?? 0
2407
+ }), this.completion.isTimeLimitReached(t, this.settings.get("renderLimitMode"), this.settings.get("renderTimeLimit")) && (t.isComplete = !0);
2408
+ }
2409
+ _completionInfo() {
2410
+ return {
2411
+ samples: this.stages.pathTracer.frameCount,
2412
+ timeElapsed: this.completion.timeElapsed,
2413
+ budgetOverrun: this.completion.budgetOverrun,
2414
+ reason: this.completion.stopCondition(this.stages.pathTracer) ?? "samples"
2415
+ };
2416
+ }
2417
+ stopAnimation() {
2418
+ this.animationManagerId &&= (cancelAnimationFrame(this.animationManagerId), null);
2419
+ }
2420
+ _handleDeviceLost(e) {
2421
+ this._deviceLost || (this._deviceLost = !0, $.error(`WebGPU device lost (${e?.reason || "unknown"}): ${e?.message || ""}`), this.stopAnimation(), this.dispatchEvent({
2422
+ type: m.DEVICE_LOST,
2423
+ reason: e?.reason,
2424
+ message: e?.message
2425
+ }));
2426
+ }
2427
+ wake() {
2428
+ this._deviceLost || this._headless || !this.animationManagerId && this.isInitialized && !this._paused && this.animate();
2429
+ }
2430
+ pause() {
2431
+ this._paused = !0, this.stopAnimation();
2432
+ }
2433
+ resume() {
2434
+ this._paused = !1, !this.animationManagerId && !this._headless && this.animate();
2435
+ }
2436
+ reset(e = !1, { motion: t = !1 } = {}) {
2437
+ t && this.stages.pathTracer?.noteViewChanged(), this._beforeReset(e || t), this.pipeline && (this.pipeline.reset(), e || this.pipeline.eventBus.emit("pipeline:historyReset")), this._afterReset(), this.completion.reset(), this.wake(), this.dispatchEvent({ type: m.RENDER_RESET });
2438
+ }
2439
+ dispose() {
2440
+ if (!this._disposed) {
2441
+ if (this._disposed = !0, this.dispatchEvent({ type: m.DISPOSE }), this.stopAnimation(), clearTimeout(this._resizeDebounceTimer), this._resizeDebounceTimer = null, this._removeTrackedListeners(), ie(null), this._storageRelease?.(), this._storageRelease = null, this.storage = null, this._sceneSource = this._sceneSourceFile = null, this._issues.detach(), this.color?.dispose(), this.color = null, this._textureReadback?.dispose(), this._textureReadback = null, this._readbackToneMapper?.dispose(), this._readbackToneMapper = null, this._disposeExtensions(), this.lightManager?.dispose(), this.pipeline?.dispose(), this._sdf?.dispose(), this._sdf = null, this.assetLoader?.dispose(), this.assetLoader = null, this.meshScene) {
2442
+ this.meshScene.environment?.dispose(), this.meshScene.environment = null;
2443
+ for (let e of [...this.meshScene.children]) se(e);
2444
+ this.meshScene.clear(), this.meshScene = null;
2445
+ }
2446
+ this._sceneHelpers?.clear(), this._sceneHelpers = null, this.scene?.clear(), this.scene = null;
2447
+ try {
2448
+ let e = Ge().value, t = Be().value;
2449
+ e?._listeners?.dispose && (e._listeners.dispose.length = 0), t?._listeners?.dispose && (t._listeners.dispose.length = 0);
2450
+ } catch (e) {
2451
+ $.warn("failed to clear TSL texture singleton listeners", e);
2452
+ }
2453
+ this.canvas && Q.get(this.canvas) === this && Q.delete(this.canvas), this._gpuDevice &&= (this._gpuDevice.onuncapturederror = null, null), this._deviceLostHolder &&= (this._deviceLostHolder.app = null, null), te(this.renderer), this.renderer = null, this.stages = {}, this.isInitialized = !1;
2454
+ }
2455
+ }
2456
+ unloadScene() {
2457
+ if (this.isInitialized) {
2458
+ if (this._loadingInProgress) throw Error("PathTracerApp.unloadScene: cannot unload while a load is in progress");
2459
+ this._disposed || (this._releaseSceneState(), this.assetLoader?.releaseTargetModel(), this._sceneSource = this._sceneSourceFile = null, this.lightManager?.clearLights?.(), this.stages.pathTracer && (this.stages.pathTracer.setTriangleData(new Uint32Array(le.FLOATS_PER_TRIANGLE), 0), this.stages.pathTracer.setBVHData(Un()), this.stages.pathTracer.materialData.setMaterialData(new Float32Array(16)), this.stages.pathTracer.setEmissiveTriangleData?.(new Float32Array(), 0, 0), this.stages.pathTracer.setupMaterial()), this._dropDisplay(), this.reset(), this.dispatchEvent({ type: m.SCENE_UNLOADED }));
2460
+ }
2461
+ }
2462
+ async loadModel(e, t = {}) {
2463
+ await this._loadWithSceneRebuild(() => this.assetLoader.loadModel(e, t), {
2464
+ type: m.MODEL_LOADED,
2465
+ url: e
2466
+ }, {
2467
+ kind: "url",
2468
+ url: e,
2469
+ cacheKey: t.cacheKey ?? null
2470
+ });
2471
+ }
2472
+ async loadObject3D(e, t = "object3d") {
2473
+ await this._loadWithSceneRebuild(() => this.assetLoader.loadObject3D(e, t), {
2474
+ type: m.OBJECT3D_LOADED,
2475
+ name: t
2476
+ }, {
2477
+ kind: "object3d",
2478
+ name: t
2479
+ });
2480
+ }
2481
+ _busyError(e) {
2482
+ let t = /* @__PURE__ */ Error(`${e}: another load is already in progress`);
2483
+ return t.code = "LOAD_IN_PROGRESS", t;
2484
+ }
2485
+ async loadEnvironment(e) {
2486
+ if (this._loadingInProgress) throw this._busyError("PathTracerApp.loadEnvironment");
2487
+ this._loadingInProgress = !0;
2488
+ try {
2489
+ await this.assetLoader.loadEnvironment(e);
2490
+ let t = this.meshScene.environment;
2491
+ t && this.stages.pathTracer && await this.stages.pathTracer.environment.setEnvironmentMap(t), this.pipeline?.eventBus.emit("pipeline:lightingChanged"), this.reset(), this.dispatchEvent({
2492
+ type: m.ENVIRONMENT_LOADED,
2493
+ url: e
2494
+ });
2495
+ } finally {
2496
+ this._loadingInProgress = !1;
2497
+ }
2498
+ }
2499
+ async inspectArchive(e) {
2500
+ return await this.assetLoader.inspectArchive(e);
2501
+ }
2502
+ async loadFile(e, t = {}) {
2503
+ if (t = this._sceneBudgets(t), typeof e == "string") {
2504
+ let n = t.filename ?? K(e), r = this.assetLoader?.getFileFormat(n);
2505
+ if (!r) throw this.assetLoader.formatError(n);
2506
+ if (r.type === "environment" || r.type === "image") return this.loadEnvironment(e);
2507
+ await this._loadWithSceneRebuild(() => this.assetLoader.loadAssetFromUrl(e, {
2508
+ ...t,
2509
+ filename: n
2510
+ }), {
2511
+ type: m.MODEL_LOADED,
2512
+ filename: n
2513
+ }, {
2514
+ kind: "url",
2515
+ url: e,
2516
+ filename: n,
2517
+ cacheKey: t.cacheKey ?? null,
2518
+ ...zn(t)
2519
+ });
2520
+ return;
2521
+ }
2522
+ let n = this.assetLoader?.getFileFormat(e?.name || "");
2523
+ if (!n) throw this.assetLoader.formatError(e?.name || "");
2524
+ if (n.type !== "environment" && n.type !== "image") {
2525
+ let n = Oe(e).catch(() => ({
2526
+ name: e.name,
2527
+ size: e.size,
2528
+ lastModified: e.lastModified ?? 0,
2529
+ sample: null
2530
+ }));
2531
+ await this._loadWithSceneRebuild(() => this.assetLoader.loadAssetFromFile(e, t), {
2532
+ type: m.MODEL_LOADED,
2533
+ filename: e.name
2534
+ }, async () => {
2535
+ let e = await n;
2536
+ return {
2537
+ kind: "local-file",
2538
+ file: e,
2539
+ key: e.sample ? E(e) : null,
2540
+ ...zn(t)
2541
+ };
2542
+ }), this._sceneSourceFile = e;
2543
+ return;
2544
+ }
2545
+ if (this._loadingInProgress) throw this._busyError("PathTracerApp.loadFile");
2546
+ this._loadingInProgress = !0;
2547
+ try {
2548
+ await this.assetLoader.loadAssetFromFile(e);
2549
+ let t = this.meshScene.environment;
2550
+ t && this.stages.pathTracer && await this.stages.pathTracer.environment.applyHDRI(t), this.pipeline?.eventBus.emit("pipeline:lightingChanged"), this.reset(), this.dispatchEvent({
2551
+ type: m.ENVIRONMENT_LOADED,
2552
+ filename: e.name
2553
+ });
2554
+ } finally {
2555
+ this._loadingInProgress = !1;
2556
+ }
2557
+ }
2558
+ async loadExampleModels(e, t) {
2559
+ await this._loadWithSceneRebuild(() => this.assetLoader.loadExampleModels(e, t), {
2560
+ type: m.MODEL_LOADED,
2561
+ index: e
2562
+ }, {
2563
+ kind: "url",
2564
+ url: t[e]?.url ?? null,
2565
+ cacheKey: null
2566
+ });
2567
+ }
2568
+ cancelLoad() {
2569
+ this._loadingInProgress && this.assetLoader?.cancelActiveLoad();
2570
+ }
2571
+ async setMaxTextureSize(e, { reprocess: t = !0 } = {}) {
2572
+ let n = this._maxTextureSize;
2573
+ if (this._maxTextureSize = this._sdf?.setMaxTextureSize(e) ?? e, typeof this.stages?.pathTracer?.sdfs?.setMaxTextureSize == "function" && this.stages.pathTracer.sdfs.setMaxTextureSize(this._maxTextureSize), t && this._maxTextureSize !== n && this._sdf?.triangles && !this._loadingInProgress) {
2574
+ this._loadingInProgress = !0;
2575
+ try {
2576
+ await this.loadSceneData(), this.reset(), this.dispatchEvent({
2577
+ type: m.TEXTURES_REPROCESSED,
2578
+ maxTextureSize: this._maxTextureSize
2579
+ });
2580
+ } finally {
2581
+ this._loadingInProgress = !1;
2582
+ }
2583
+ }
2584
+ }
2585
+ get sceneSource() {
2586
+ return this._sceneSource ?? null;
2587
+ }
2588
+ get sceneSourceFile() {
2589
+ return this._sceneSourceFile ?? null;
2590
+ }
2591
+ async _loadWithSceneRebuild(e, t, n = null) {
2592
+ if (this._loadingInProgress) throw this._busyError("PathTracerApp");
2593
+ this._loadingInProgress = !0;
2594
+ try {
2595
+ await e(), this._sceneSource = typeof n == "function" ? await n() : n, this._sceneSourceFile = null, this._emissiveSamplingUserSet = !1, this._clearAppendedModels(), this._modelReplaced(), await this.loadSceneData({ pendingEnvironment: this._beginSceneMetadataEnvironment() }), this._maybeSpill(), this.pipeline?.eventBus.emit("pipeline:lightingChanged"), this._dropDisplay(), this.reset(), this.dispatchEvent(t), this._modelAnnounced();
2596
+ } catch (e) {
2597
+ throw (!e || e.code !== "LOAD_IN_PROGRESS") && this._discardFailedLoad(), e?.code === "ARCHIVE_NEEDS_ELEMENT" ? _() : e?.code !== "LOAD_IN_PROGRESS" && g({
2598
+ status: `Error: ${e?.message ?? e}`,
2599
+ failed: !0,
2600
+ progress: 100
2601
+ }), e;
2602
+ } finally {
2603
+ this._loadingInProgress = !1;
2604
+ }
2605
+ }
2606
+ _discardFailedLoad() {
2607
+ this._sceneSource = this._sceneSourceFile = null;
2608
+ try {
2609
+ this._clearAppendedModels(), this.assetLoader?.releaseTargetModel(), this._dropDisplay(), this.reset();
2610
+ } catch (e) {
2611
+ console.warn("PathTracerApp: could not clear the scene after a failed load", e);
2612
+ }
2613
+ }
2614
+ get sceneMetadata() {
2615
+ return this.assetLoader?.sceneMetadata ?? null;
2616
+ }
2617
+ _beginSceneMetadataEnvironment() {
2618
+ this._restoreUnlitSettings();
2619
+ let e = this.sceneMetadata?.environment;
2620
+ return this._applySceneMetadataEnabled && e?.enabled === !1 ? (this._applyUnlitSettings(), null) : !this._applySceneMetadataEnabled || !e?.sourceFile || !this.stages.pathTracer ? null : (this.stages.pathTracer.environment.beginHDRI(), this._applyingSceneMetadata = !0, this.assetLoader.loadEnvironment(e.sourceFile).catch((t) => (this._issues.record(x.ENVIRONMENT_LOAD_FAILED, `authored environment "${e.sourceFile}" failed to load — lighting falls back to the previous environment`, {
2621
+ sourceFile: e.sourceFile,
2622
+ cause: String(t?.message ?? t)
2623
+ }), null)).finally(() => {
2624
+ this._applyingSceneMetadata = !1;
2625
+ }));
2626
+ }
2627
+ _applySceneMetadataSettings(e) {
2628
+ let t = this.sceneMetadata, n = t?.environment;
2629
+ if (!n || n.enabled === !1) return;
2630
+ let r = {
2631
+ enableEnvironment: !0,
2632
+ showBackground: !0,
2633
+ transparentBackground: !1
2634
+ };
2635
+ n.intensity !== void 0 && (r.environmentIntensity = n.intensity, r.backgroundIntensity = n.intensity), n.rotation !== void 0 && (r.environmentRotation = n.rotation), this.settings.setMany(r, {
2636
+ reset: !1,
2637
+ source: Y.SCENE_METADATA
2638
+ }), this.scene && (this.scene.background = e), this.dispatchEvent({
2639
+ type: m.SCENE_METADATA_APPLIED,
2640
+ metadata: t,
2641
+ environment: { ...n }
2642
+ });
2643
+ }
2644
+ _applyUnlitSettings() {
2645
+ let e = this.settings.getEffective(), t = {
2646
+ enableEnvironment: !1,
2647
+ showBackground: !1
2648
+ };
2649
+ this._unlitRestore = Object.fromEntries(Object.keys(t).map((t) => [t, {
2650
+ value: e[t].value,
2651
+ source: e[t].source
2652
+ }])), this.settings.setMany(t, {
2653
+ reset: !1,
2654
+ source: Y.SCENE_METADATA
2655
+ }), this.dispatchEvent({
2656
+ type: m.SCENE_METADATA_APPLIED,
2657
+ metadata: this.sceneMetadata,
2658
+ environment: { enabled: !1 }
2659
+ });
2660
+ }
2661
+ _restoreUnlitSettings() {
2662
+ let e = this._unlitRestore;
2663
+ if (!e) return;
2664
+ this._unlitRestore = null;
2665
+ let t = this.settings.getEffective();
2666
+ for (let [n, { value: r, source: i }] of Object.entries(e)) t[n]?.source === Y.SCENE_METADATA && this.settings.set(n, r, {
2667
+ reset: !1,
2668
+ source: i
2669
+ });
2670
+ this.dispatchEvent({
2671
+ type: m.SCENE_METADATA_APPLIED,
2672
+ metadata: this.sceneMetadata,
2673
+ environment: { enabled: this.settings.get("enableEnvironment") }
2674
+ });
2675
+ }
2676
+ async loadSceneData({ pendingEnvironment: e = null, keepUserLights: t = !1 } = {}) {
2677
+ this._releaseSceneState({ keepSelection: !!this._preserveSelectionOnRebuild }), this._tagPrimarySceneObject();
2678
+ let n = new u("", {
2679
+ namespace: "scene",
2680
+ level: "info"
2681
+ }), r = () => this.stages.pathTracer.environment.envParams.mode === "hdri" ? this.meshScene.environment : null, i = r(), a = null;
2682
+ if (e ? (n.start("Environment fetch + CDF (concurrent)"), a = e.then(async (e) => {
2683
+ e && (await this.stages.pathTracer.environment.applyHDRI(e), this._applySceneMetadataSettings(e));
2684
+ }).catch((e) => this._issues.record(x.ENVIRONMENT_LOAD_FAILED, "authored environment failed to install — the scene is lit by whatever was already loaded", { cause: String(e?.message ?? e) })).finally(() => n.end("Environment fetch + CDF (concurrent)"))) : i?.image?.data && (n.start("Environment CDF build (worker)"), this.stages.pathTracer.scene.environment = i, a = this.stages.pathTracer.environment.buildEnvironmentCDF().then(() => {
2685
+ n.end("Environment CDF build (worker)"), this._applySceneMetadataEnabled && this._applySceneMetadataSettings(i);
2686
+ })), n.start("BVH build (SceneProcessor)"), this._sdf.setMaxTextureSize(this._maxTextureSize), await this._sdf.buildBVH(this.meshScene, {
2687
+ sceneKey: this.assetLoader?.sceneSourceKey ?? null,
2688
+ progressive: this._progressiveSpill()
2689
+ }), this.assetLoader?.flushPendingGraph(this._sdf.performanceMetrics.totalProcessingTime), n.end("BVH build (SceneProcessor)"), g({
2690
+ status: "Transferring data to GPU...",
2691
+ progress: 86
2692
+ }), await new Promise((e) => setTimeout(e, 0)), n.start("GPU data transfer"), !this._sdf.uploadToPathTracer(this.stages.pathTracer, this.lightManager, this.meshScene, r(), { keepUserLights: t })) return !1;
2693
+ this.stages.pathTracer._meshRefs = this.stages.pathTracer._collectMeshRefs(this.meshScene), this.stages.pathTracer.setMeshVisibilityData(this.stages.pathTracer._meshRefs), this._refreshEmissiveForVisibility(), n.end("GPU data transfer"), g({
2694
+ status: "Compiling shaders...",
2695
+ progress: 90
2696
+ }), await new Promise((e) => setTimeout(e, 0)), n.start("Material setup (TSL compile)"), this.stages.pathTracer.setupMaterial(), n.end("Material setup (TSL compile)"), this._rasterPrecompile = null, this._pathTracerEnabled || (n.start("Pipeline precompile"), await this.precompileRaster(), n.end("Pipeline precompile")), a && (g({
2697
+ status: "Finalizing environment map...",
2698
+ progress: 95
2699
+ }), await a, this.stages.pathTracer.environment.applyCDFResults());
2700
+ let o = this.getSceneMinY();
2701
+ if (this.settings.set("groundProjectionLevel", o, { reset: !1 }), this.settings.set("groundCatcherHeight", o, { reset: !1 }), !this._emissiveSamplingUserSet) {
2702
+ let e = (this._sdf?.emissiveTriangleBuilder?.emissiveTriangles?.length ?? this._sdf?.emissiveTriangleCount ?? 0) > 0;
2703
+ this.settings.set("enableEmissiveTriangleSampling", e, { reset: !1 });
2704
+ }
2705
+ return n.start("Apply settings"), this.settings.applyAll(), this.stages.compositor.setTransparentBackground(this.settings.get("transparentBackground")), n.end("Apply settings"), n.print(this._sceneSummaryParts()), _(), this._sceneRebuilt(), this.dispatchEvent({ type: m.SCENE_REBUILD }), !0;
2706
+ }
2707
+ _sceneSummaryParts() {
2708
+ let e = this.stages.pathTracer, t = this._sdf?.instanceTable?.setCount ?? 0, n = this._sdf?.geometryExtractor?.maps?.length ?? 0;
2709
+ return [
2710
+ b.count(e.triangleCount, "tri"),
2711
+ t ? b.count(t, "mesh", "meshes") : null,
2712
+ b.count(e.materialData.materialCount, "material"),
2713
+ n ? b.count(n, "map") : null,
2714
+ b.count(e.bvhNodeCount, "BVH node")
2715
+ ];
2716
+ }
2717
+ _tagPrimarySceneObject() {
2718
+ let e = this.sceneModel;
2719
+ e && (e.userData.__rayzeeSceneObject = !0);
2720
+ }
2721
+ _clearAppendedModels() {
2722
+ let e = this.meshScene;
2723
+ if (!e) return;
2724
+ let t = this.assetLoader?.floorPlane, n = this.sceneModel;
2725
+ for (let r of [...e.children]) r === t || r === n || r.userData?.__rayzeeSceneObject && this.assetLoader.removeModelRoot(r);
2726
+ }
2727
+ async _finishRebuildNoReframe(e) {
2728
+ await this.loadSceneData({ keepUserLights: !0 }), this._maybeSpill(), this._sceneBoundsChanged(), this.pipeline?.eventBus.emit("pipeline:lightingChanged"), this.reset(), e && this.dispatchEvent(e);
2729
+ }
2730
+ async addModel(e, { name: t, cacheKey: n } = {}) {
2731
+ if (this._loadingInProgress) throw Error("PathTracerApp.addModel: another load is already in progress");
2732
+ this._loadingInProgress = !0, this._preserveSelectionOnRebuild = !0;
2733
+ try {
2734
+ let { root: r } = await this.assetLoader.appendModel(e, { cacheKey: n });
2735
+ return r.userData.__rayzeeSceneObject = !0, r.userData.__rayzeeSourceUrl = e, n && (r.userData.__rayzeeCacheKey = n), t && (r.userData.__rayzeeName = t), await this._finishRebuildNoReframe({
2736
+ type: m.MODEL_ADDED,
2737
+ url: e,
2738
+ id: r.uuid
2739
+ }), r.uuid;
2740
+ } finally {
2741
+ this._preserveSelectionOnRebuild = !1, this._loadingInProgress = !1;
2742
+ }
2743
+ }
2744
+ async addModelFromObject3D(e, { name: t } = {}) {
2745
+ if (this._loadingInProgress) throw Error("PathTracerApp.addModelFromObject3D: another load is already in progress");
2746
+ this._loadingInProgress = !0, this._preserveSelectionOnRebuild = !0;
2747
+ try {
2748
+ let { root: n } = this.assetLoader.appendObject3D(e, t || "object3d");
2749
+ return n.userData.__rayzeeSceneObject = !0, t && (n.userData.__rayzeeName = t), await this._finishRebuildNoReframe({
2750
+ type: m.MODEL_ADDED,
2751
+ id: n.uuid
2752
+ }), n.uuid;
2753
+ } finally {
2754
+ this._preserveSelectionOnRebuild = !1, this._loadingInProgress = !1;
2755
+ }
2756
+ }
2757
+ async removeSceneObject(e) {
2758
+ if (!this.meshScene) return !1;
2759
+ let t = this.assetLoader?.floorPlane;
2760
+ if (t && t.uuid === e) return !1;
2761
+ let n = this.getSceneObject(e);
2762
+ if (!n) return !1;
2763
+ if (this._loadingInProgress) throw Error("PathTracerApp.removeSceneObject: another load is already in progress");
2764
+ this._loadingInProgress = !0;
2765
+ try {
2766
+ return this._releaseSceneState(), n === this.sceneModel ? this.assetLoader.releaseTargetModel() : this.assetLoader.removeModelRoot(n), await this._finishRebuildNoReframe({
2767
+ type: m.SCENE_OBJECT_REMOVED,
2768
+ id: e
2769
+ }), !0;
2770
+ } finally {
2771
+ this._loadingInProgress = !1;
2772
+ }
2773
+ }
2774
+ setSceneObjectVisibility(e, t) {
2775
+ return this.setMeshVisibilityByUuid(e, t);
2776
+ }
2777
+ _sceneBudgets(e) {
2778
+ return !this._memorySpill || !this.storage ? e : {
2779
+ maxTriangles: ce,
2780
+ maxPlacements: ue,
2781
+ ...e
2782
+ };
2783
+ }
2784
+ _progressiveSpill() {
2785
+ if (!this._memorySpill || !this.storage || (this.assetLoader?.animations?.length ?? 0) > 0) return null;
2786
+ let e = this.stages.pathTracer;
2787
+ return {
2788
+ storage: this.storage,
2789
+ uploader: (t, n) => n === "triangles" ? e.createTriangleChunkUploader(t) : e.createChunkUploader(t)
2790
+ };
2791
+ }
2792
+ _maybeSpill() {
2793
+ !this._memorySpill || !this.storage || (this.assetLoader?.animations?.length ?? 0) > 0 || this._sdf?.spillToDisk(this.storage).then((e) => e && this.dispatchEvent({
2794
+ type: m.SCENE_SPILLED,
2795
+ ...e
2796
+ })).catch((e) => this._issues.warn(x.STORAGE_WRITE_FAILED, `memory spill failed: ${e.message}`));
2797
+ }
2798
+ async ensureSceneResident() {
2799
+ this._sdf?.spilled && await this._sdf.ensureResident();
2800
+ }
2801
+ get sceneMeshes() {
2802
+ return this._sdf?.meshes ?? [];
2803
+ }
2804
+ get sceneModel() {
2805
+ return this.assetLoader?.targetModel ?? null;
2806
+ }
2807
+ getSceneObject(e) {
2808
+ let t = this.meshScene?.children.find((t) => t.uuid === e);
2809
+ return t?.userData?.__rayzeeSceneObject ? t : null;
2810
+ }
2811
+ async refitBVH(e, t) {
2812
+ await this.ensureSceneResident();
2813
+ let { triRanges: n, bvhRanges: r, ...i } = await this._sdf.refitBVH(e, t);
2814
+ return this.stages.pathTracer.updateTriangleData(this._sdf.triangles, n), this.stages.pathTracer.updateBVHData(this._sdf.bvh, r), this.reset(!1, { motion: !0 }), i;
2815
+ }
2816
+ refitBLASes(e, t, n) {
2817
+ if (this._sdf?.spilled) throw Error("refitBLASes: the scene is spilled to disk — await app.ensureSceneResident() first");
2818
+ let r = this._sdf.refitBLASes(e, t, n), { triRanges: i, bvhRanges: a } = this._sdf.computeBLASDirtyRanges(e);
2819
+ return this.stages.pathTracer.updateBufferRanges(i, a), this.reset(!1, { motion: !0 }), this._sdf.scheduleBackgroundRebuild(e, (e) => {
2820
+ let t = this._sdf.computeBLASDirtyRanges([e]);
2821
+ this.stages.pathTracer.updateBufferRanges(t.triRanges, t.bvhRanges), this.reset(!1, { motion: !0 });
2822
+ }), r;
2823
+ }
2824
+ updateMeshTransforms(e) {
2825
+ this._notePlacementsMoving(e);
2826
+ let t = this._sdf.updateMeshTransforms(e);
2827
+ return this.stages.pathTracer.updateBufferRanges([], [this._sdf.computeTLASDirtyRange()]), this.reset(!1, { motion: !0 }), t;
2828
+ }
2829
+ setReservedRenderResolution(e, { allowLower: t = !1 } = {}) {
2830
+ let n = t ? e : Math.max(e, y);
2831
+ if (!this.renderer) return this._pendingReservedRenderSize = {
2832
+ requestedPx: e,
2833
+ allowLower: t
2834
+ }, Math.max(256, Math.min(me, Math.floor(n) || 256));
2835
+ let r = this.renderer.backend?.device?.limits?.maxStorageBufferBindingSize || 128 * 1024 * 1024, i = o(this._hostMemoryGB), a = i.gb >= 8 && r >= 1024 * 1024 * 1024 ? me : 2048, s = pe(Math.min(n, a));
2836
+ if (s < Math.floor(e) && this._issues.warn(x.RENDER_RESERVE_CAPPED, `reserved render size ${b.n(e)}px was capped to ${b.n(s)}px by this device's limits — renders above ${b.n(s)}px will be declined` + (i.assumed && i.gb < 8 ? " (host memory unknown, 4 GB assumed: pass hostMemoryGB)" : ""), {
2837
+ requested: e,
2838
+ applied: s,
2839
+ deviceMemoryGB: i.gb,
2840
+ assumed: i.assumed,
2841
+ maxStorageBufferBindingSize: r
2842
+ }), (this.stages?.pathTracer?.storageTextures?.writeColor?.image?.width ?? s) !== s) {
2843
+ let e = this.pauseRendering;
2844
+ this.pauseRendering = !0;
2845
+ try {
2846
+ let e = this.renderer.domElement;
2847
+ (e.width > s || e.height > s) && this.renderer.setSize(Math.min(e.width, s), Math.min(e.height, s), !1);
2848
+ for (let e of Object.values(this.stages)) e?.reallocateReservedStorage?.();
2849
+ } finally {
2850
+ this.pauseRendering = e;
2851
+ }
2852
+ this.reset(), this.dispatchEvent({
2853
+ type: m.RESERVED_RENDER_SIZE_CHANGED,
2854
+ size: s
2855
+ });
2856
+ }
2857
+ return s;
2858
+ }
2859
+ _applyPendingReservedRenderSize() {
2860
+ let e = this._pendingReservedRenderSize;
2861
+ if (!e) return;
2862
+ this._pendingReservedRenderSize = null;
2863
+ let t = this.setReservedRenderResolution(e.requestedPx, { allowLower: e.allowLower });
2864
+ this.dispatchEvent({
2865
+ type: m.RESERVED_RENDER_SIZE_CHANGED,
2866
+ size: t
2867
+ });
2868
+ }
2869
+ getReservedRenderResolution() {
2870
+ return y;
2871
+ }
2872
+ _isRenderSizeSupported(e, t) {
2873
+ return e > y || t > y ? (this._issues.record(x.RENDER_SIZE_DECLINED, `render resolution ${e}×${t} exceeds the ${y}px storage reserve — resize ignored, so output stays at the previous size. Raise it with setReservedRenderResolution( ${Math.max(e, t)} ) before init().`, {
2874
+ width: e,
2875
+ height: t,
2876
+ reserve: y
2877
+ }), !1) : !0;
2878
+ }
2879
+ onResize() {
2880
+ let e = this.canvas.clientWidth, t = this.canvas.clientHeight;
2881
+ e === 0 || t === 0 || this._isRenderSizeSupported(e, t) && (this.renderer.setPixelRatio(1), this._setDisplaySize(e, t), !(e === this._renderWidth && t === this._renderHeight) && (clearTimeout(this._resizeDebounceTimer), this._resizeDebounceTimer = setTimeout(() => {
2882
+ this._applyRenderResize(e, t);
2883
+ }, 300)));
2884
+ }
2885
+ _applyRenderResize(e, t) {
2886
+ this._isRenderSizeSupported(e, t) && (this.pipeline?.setSize(this._scaled(e), this._scaled(t)), this._renderWidth = e, this._renderHeight = t, this._renderSizeChanged(e, t), this.needsReset = !0, this.dispatchEvent({
2887
+ type: m.RESOLUTION_CHANGED,
2888
+ width: e,
2889
+ height: t
2890
+ }));
2891
+ }
2892
+ setCanvasSize(e, t) {
2893
+ return e === 0 || t === 0 || !this._isRenderSizeSupported(e, t) ? null : (this.renderer.setPixelRatio(1), this._setDisplaySize(e, t), clearTimeout(this._resizeDebounceTimer), this._applyRenderResize(e, t), {
2894
+ width: e,
2895
+ height: t
2896
+ });
2897
+ }
2898
+ _scaled(e) {
2899
+ return Math.max(1, Math.round(e * this._renderScale));
2900
+ }
2901
+ _setDisplaySize(e, t) {
2902
+ this._displayWidth = e, this._displayHeight = t, this.renderer.setSize(this._scaled(e), this._scaled(t), !1), this.camera.aspect = e / t, this.camera.updateProjectionMatrix();
2903
+ }
2904
+ refreshFrame() {
2905
+ this._needsDisplayRefresh = !0, this.wake();
2906
+ }
2907
+ setDeterministicMode(e = !0, { pinDispatch: t = !0 } = {}) {
2908
+ let n = this.stages.pathTracer;
2909
+ if (!n) return !1;
2910
+ if (e) this._deterministicRestore ||= {
2911
+ settings: {
2912
+ useAdaptiveSampling: this.settings.get("useAdaptiveSampling"),
2913
+ usePixelFreeze: this.settings.get("usePixelFreeze"),
2914
+ interactionModeEnabled: this.settings.get("interactionModeEnabled"),
2915
+ renderLimitMode: this.settings.get("renderLimitMode"),
2916
+ renderTimeLimit: this.settings.get("renderTimeLimit")
2917
+ },
2918
+ bounceEarlyExit: n._bounceEarlyExitThreshold,
2919
+ dynamicDispatch: n._useDynamicDispatch,
2920
+ extras: this._deterministicSnapshot()
2921
+ }, this.settings.setMany({
2922
+ useAdaptiveSampling: !1,
2923
+ usePixelFreeze: !1,
2924
+ interactionModeEnabled: !1,
2925
+ renderLimitMode: "frames",
2926
+ renderTimeLimit: 0
2927
+ }, { silent: !0 }), t ? (n._bounceEarlyExitThreshold = -1, n._useDynamicDispatch = !1) : (n._bounceEarlyExitThreshold = this._deterministicRestore.bounceEarlyExit, n._useDynamicDispatch = this._deterministicRestore.dynamicDispatch), this._setDeterministicExtras(!0, this._deterministicRestore.extras), n._pinSeedToFrame = !0, this._deterministic = !0, this._dispatchPinned = t;
2928
+ else if (this._deterministicRestore) {
2929
+ let e = this._deterministicRestore;
2930
+ this.settings.setMany(e.settings, { silent: !0 }), n._bounceEarlyExitThreshold = e.bounceEarlyExit, n._useDynamicDispatch = e.dynamicDispatch, this._setDeterministicExtras(!1, e.extras), n._pinSeedToFrame = !1, this._deterministicRestore = null, this._deterministic = !1, this._dispatchPinned = !1;
2931
+ }
2932
+ return this.reset(), this.stopAnimation(), this._deterministic;
2933
+ }
2934
+ get issues() {
2935
+ return this._issues.list;
2936
+ }
2937
+ get issueErrors() {
2938
+ return this._issues.errors;
2939
+ }
2940
+ clearIssues() {
2941
+ this._issues.clear();
2942
+ }
2943
+ get isDeterministic() {
2944
+ return this._deterministic && this._dispatchPinned;
2945
+ }
2946
+ async renderFrames(e, { reset: t = !0, yieldEvery: n = 8, onProgress: r, allowEarlyRetire: i = !1 } = {}) {
2947
+ let a = this.stages.pathTracer;
2948
+ if (!a) throw Error("renderFrames: app is not initialized");
2949
+ if (!(e > 0)) throw Error(`renderFrames: count must be positive, got ${e}`);
2950
+ let o = (t ? 0 : a.frameCount) + e;
2951
+ this.settings.get("maxSamples") < o && this.settings.set("maxSamples", o, {
2952
+ silent: !0,
2953
+ reset: !1
2954
+ }), t && this.reset(), this.stopAnimation();
2955
+ let s = e + 64, c = 0, l = !1;
2956
+ for (; a.frameCount < o && c < s;) {
2957
+ if (this._deviceLost) throw Error("renderFrames: WebGPU device lost");
2958
+ if (!a.isReady) throw Error("renderFrames: path tracer stage is not ready");
2959
+ let e = a.readbackWait();
2960
+ if (e) {
2961
+ await this._awaitReadback(e);
2962
+ continue;
2963
+ }
2964
+ if (this.camera.updateMatrixWorld(), this.pipeline.render(), c++, a.isComplete && a.frameCount < o) {
2965
+ l = !0;
2966
+ break;
2967
+ }
2968
+ r?.(a.frameCount), n > 0 && c % n === 0 && await new Promise((e) => setTimeout(e, 0));
2969
+ }
2970
+ if (a.frameCount < o && !(l && i)) {
2971
+ let e = l ? "adaptive sampling retired the frame at the convergence threshold — pass `allowEarlyRetire: true`, or disable it with setDeterministicMode()" : "something retired the render (maxSamples, a stray reset, or a canvas resize)";
2972
+ throw Error(`renderFrames: stopped at ${a.frameCount}/${o} samples after ${c} passes — ${e}`);
2973
+ }
2974
+ return a.frameCount;
2975
+ }
2976
+ async renderUntilComplete({ reset: e = !0, denoise: t = !0, signal: n, drainEvery: r = 4, onProgress: i } = {}) {
2977
+ let a = this.stages.pathTracer;
2978
+ if (!a) throw Error("renderUntilComplete: app is not initialized");
2979
+ if (this._loadingInProgress || this._sdf?.isProcessing) throw Error("renderUntilComplete: a scene is still loading");
2980
+ let o = a.lockstepReadbacks;
2981
+ a.setLockstepReadbacks(!0);
2982
+ let s = this.settings.getEffective().interactionModeEnabled;
2983
+ this.settings.set("interactionModeEnabled", !1, {
2984
+ silent: !0,
2985
+ reset: !1
2986
+ });
2987
+ try {
2988
+ e && this.reset(), this.stopAnimation();
2989
+ let o = this.renderer.backend.device?.queue, s = 0, c = null;
2990
+ for (; !a.isComplete;) {
2991
+ if (n?.throwIfAborted(), this._deviceLost) throw Error("renderUntilComplete: WebGPU device lost");
2992
+ if (!a.isReady) throw Error("renderUntilComplete: path tracer stage is not ready");
2993
+ let e = a.readbackWait();
2994
+ if (e) {
2995
+ await this._awaitReadback(e);
2996
+ continue;
2997
+ }
2998
+ this.camera.updateMatrixWorld();
2999
+ let t = a.frameCount;
3000
+ if (this._traceFrame(), i?.(a.frameCount), a.frameCount === t && !a.isComplete && await new Promise((e) => setTimeout(e, 0)), o && r > 0 && ++s % r === 0) {
3001
+ let e = o.onSubmittedWorkDone();
3002
+ c && await c, c = e;
3003
+ }
3004
+ }
3005
+ let l = this._completionInfo();
3006
+ this.completion.markComplete() && this.dispatchEvent({
3007
+ type: m.RENDER_COMPLETE,
3008
+ ...l
3009
+ });
3010
+ let u = t ? await this._finalDenoise() : !1, { reason: d, ...f } = l;
3011
+ return {
3012
+ ...f,
3013
+ retiredBy: d,
3014
+ denoised: u
3015
+ };
3016
+ } finally {
3017
+ a.setLockstepReadbacks(o), s && this.settings.set("interactionModeEnabled", s.value, {
3018
+ silent: !0,
3019
+ reset: !1,
3020
+ source: s.source
3021
+ });
3022
+ }
3023
+ }
3024
+ getProvenance() {
3025
+ let e = this.stages.pathTracer, t = this.color?.status();
3026
+ return r({
3027
+ engine: oe,
3028
+ three: ht,
3029
+ profile: {
3030
+ name: this._profileName,
3031
+ values: { ...this._profile }
3032
+ },
3033
+ adapter: this.adapterInfo ?? null,
3034
+ mode: {
3035
+ headless: this._headless,
3036
+ strict: this._issues.strict,
3037
+ deterministic: this.isDeterministic,
3038
+ lockstep: !!e?.accumulationLockstep
3039
+ },
3040
+ render: e ? {
3041
+ width: e.width,
3042
+ height: e.height,
3043
+ samples: e.frameCount,
3044
+ complete: e.isComplete,
3045
+ retiredBy: e.isComplete ? this.completion.stopCondition(e) ?? "samples" : null
3046
+ } : null,
3047
+ color: t ? {
3048
+ config: t.config?.id ?? null,
3049
+ workingSpace: t.workingSpace,
3050
+ view: t.activeView ?? t.activeTransform?.id ?? null,
3051
+ context: t.context
3052
+ } : null,
3053
+ scene: this.sceneSource,
3054
+ settings: this.settings.getEffective(),
3055
+ issues: this.issues.map(({ code: e, severity: t }) => ({
3056
+ code: e,
3057
+ severity: t
3058
+ }))
3059
+ });
3060
+ }
3061
+ setLockstepReadbacks(e = !0) {
3062
+ this.stages.pathTracer?.setLockstepReadbacks(e);
3063
+ }
3064
+ async _awaitReadback(e) {
3065
+ let t = this.renderer.backend.device?.lost, n = await (t ? Promise.race([e.then(() => null), t]) : e);
3066
+ if (n) throw Error(`WebGPU device lost while awaiting a readback: ${n.message ?? n.reason}`);
3067
+ }
3068
+ async captureRenderCheckpoint() {
3069
+ let e = this.stages.pathTracer;
3070
+ if (!e) return null;
3071
+ let t = await e.captureAccumulation();
3072
+ return {
3073
+ v: 1,
3074
+ engine: oe,
3075
+ savedAt: Date.now(),
3076
+ samples: t.state.frameCount,
3077
+ ...t
3078
+ };
3079
+ }
3080
+ restoreRenderCheckpoint(e) {
3081
+ if (e?.v !== 1) throw Error(`render checkpoint version ${e?.v} is not 1`);
3082
+ let t = this.stages.pathTracer;
3083
+ if (!t) throw Error("restoreRenderCheckpoint: app is not initialized");
3084
+ t.restoreAccumulation(e), this.needsReset = !1, this.dispatchEvent({
3085
+ type: m.RENDER_RESET,
3086
+ restored: e.samples
3087
+ });
3088
+ }
3089
+ async renderToBuffer({ colorSpace: e = "srgb", preserveAlpha: t = !1, source: n = "accumulation" } = {}) {
3090
+ if (e !== "linear" && e !== "srgb" && !this.color?.hasConfig) throw Error(`renderToBuffer: colorSpace must be 'linear' or 'srgb' without a colour config loaded, got "${e}"`);
3091
+ let r = this.stages?.pathTracer, i = r?.storageTextures?.readTarget;
3092
+ if (!i) throw Error("renderToBuffer: no render target — call init() and render at least one sample");
3093
+ let { width: o, height: s } = r;
3094
+ if (e === "srgb") {
3095
+ let r = n === "display" ? this._displaySource(i) : null, c = {
3096
+ exposure: this.renderer.toneMappingExposure,
3097
+ toneMapping: this.renderer.toneMapping,
3098
+ saturation: this.settings.get("saturation") ?? 1,
3099
+ preserveAlpha: t
3100
+ }, l = await this._toneMapOnGPU(r?.texture ?? null, i, o, s, c);
3101
+ return {
3102
+ data: l ?? a(r ? await this._readTexture(r.texture, o, s) : await this.renderer.readRenderTargetPixelsAsync(i, 0, 0, o, s, 0), c),
3103
+ width: o,
3104
+ height: s,
3105
+ colorSpace: e,
3106
+ source: r?.source ?? "accumulation",
3107
+ toneMappedOn: l ? "gpu" : "cpu"
3108
+ };
3109
+ }
3110
+ let { data: c, source: l } = n === "display" ? await this._readDisplaySource(i, o, s) : {
3111
+ data: await this.renderer.readRenderTargetPixelsAsync(i, 0, 0, o, s, 0),
3112
+ source: "accumulation"
3113
+ };
3114
+ if (e === "linear") return {
3115
+ data: c,
3116
+ width: o,
3117
+ height: s,
3118
+ colorSpace: e,
3119
+ workingSpace: this.color?.workingSpace ?? null,
3120
+ source: l
3121
+ };
3122
+ let { rgba: u, colorSpace: d } = this.color.exportPixels(c, e);
3123
+ return {
3124
+ data: u,
3125
+ width: o,
3126
+ height: s,
3127
+ colorSpace: d,
3128
+ source: l
3129
+ };
3130
+ }
3131
+ async _toneMapOnGPU(e, t, n, r, i) {
3132
+ let a = this.renderer?.backend;
3133
+ if (!a?.device) return this._toneMapFallback("the renderer has no WebGPU device");
3134
+ try {
3135
+ let o = e ? this._readbackPass().draw(e, n, r).texture : t.textures[0], s = a.get(o).texture;
3136
+ return s ? (this._readbackToneMapper ??= new ke(a.device, "rayzee:readback-tonemap", { input: "texture" }), this._readbackToneMapper.ensureSize(n, r), await this._readbackToneMapper.toRGBA8(s, i)) : this._toneMapFallback("the picture has no GPU texture yet");
3137
+ } catch (e) {
3138
+ if (e instanceof ve) throw e;
3139
+ return this._toneMapFallback("the GPU pass threw", e);
3140
+ } finally {
3141
+ this._readbackToneMapper?.release(), e && this._textureReadback?.release();
3142
+ }
3143
+ }
3144
+ _toneMapFallback(e, t = null) {
3145
+ let n = t ? String(t?.message ?? t) : null, r = `renderToBuffer: tone mapped on the CPU — ${e}${n ? `: ${n}` : ""}`;
3146
+ return $.warn(r), this._issues.warn(x.OUTPUT_TONEMAP_FALLBACK, r, {
3147
+ reason: e,
3148
+ cause: n
3149
+ }), null;
3150
+ }
3151
+ enableGPUTiming(e = !0) {
3152
+ let t = this.renderer?.backend;
3153
+ return !t || e && t.hasFeature?.("timestamp-query") !== !0 ? !1 : (t.trackTimestamp = e, t.trackTimestamp === e);
3154
+ }
3155
+ async getGPUTimings() {
3156
+ let e = this.renderer;
3157
+ if (!e?.backend?.trackTimestamp) return null;
3158
+ await e.resolveTimestampsAsync("compute"), await e.resolveTimestampsAsync("render");
3159
+ let t = e.info.compute.timestamp || 0, n = e.info.render.timestamp || 0;
3160
+ return {
3161
+ compute: t,
3162
+ render: n,
3163
+ total: t + n
3164
+ };
3165
+ }
3166
+ async getKernelGPUTimings() {
3167
+ let e = this.renderer;
3168
+ if (!e?.backend?.trackTimestamp) return null;
3169
+ await e.resolveTimestampsAsync("compute");
3170
+ let t = e.backend.timestampQueryPool?.compute?.timestamps;
3171
+ if (!t || t.size === 0) return null;
3172
+ let n = /* @__PURE__ */ new Map(), r = this.stages?.pathTracer?._kernelManager?.kernels;
3173
+ if (r) for (let [e, t] of r) n.set(t.id, e);
3174
+ let i = [], a = -1;
3175
+ for (let [e, n] of t) {
3176
+ let t = e.split(":");
3177
+ if (t.length !== 4) continue;
3178
+ let r = Number(t[3].slice(1));
3179
+ Number.isFinite(r) && (i.push({
3180
+ nodeId: Number(t[2]),
3181
+ f: r,
3182
+ ms: n
3183
+ }), r > a && (a = r));
3184
+ }
3185
+ let o = {}, s = 0, c = 0;
3186
+ for (let e of i) {
3187
+ if (e.f !== a) continue;
3188
+ s += e.ms;
3189
+ let t = n.get(e.nodeId);
3190
+ t === void 0 ? c += e.ms : o[t] = (o[t] ?? 0) + e.ms;
3191
+ }
3192
+ return {
3193
+ kernels: o,
3194
+ total: s,
3195
+ unattributed: c,
3196
+ frame: a
3197
+ };
3198
+ }
3199
+ getCanvas() {
3200
+ return this.renderer?.domElement ? this._displayCanvas() || (this.stages.compositor && this.pipeline?.context && this.stages.compositor.render(this.pipeline.context), this.renderer.domElement) : null;
3201
+ }
3202
+ screenshot({ type: e = "image/png", quality: t } = {}) {
3203
+ let n = this.getCanvas();
3204
+ return n ? new Promise((r) => n.toBlob(r, e, t)) : Promise.resolve(null);
3205
+ }
3206
+ getStatistics() {
3207
+ try {
3208
+ return this._sdf?.getStatistics?.() ?? null;
3209
+ } catch {
3210
+ return null;
3211
+ }
3212
+ }
3213
+ get pathTracerEnabled() {
3214
+ return this._pathTracerEnabled;
3215
+ }
3216
+ set pathTracerEnabled(e) {
3217
+ this._pathTracerEnabled = e, e || this.precompileRaster();
3218
+ }
3219
+ precompileRaster() {
3220
+ return !this.renderer || !this.meshScene ? Promise.resolve() : (this._rasterPrecompile ??= this.renderer.compileAsync(this.meshScene, this.camera).catch((e) => $.warn("raster fallback precompile failed", e)), this._rasterPrecompile);
3221
+ }
3222
+ get isLoading() {
3223
+ return this._loadingInProgress;
3224
+ }
3225
+ isComplete() {
3226
+ return this.stages.pathTracer?.isComplete ?? !1;
3227
+ }
3228
+ getFrameCount() {
3229
+ return this.stages.pathTracer?.frameCount || 0;
3230
+ }
3231
+ getConvergenceStats() {
3232
+ return this.stages.pathTracer?.getConvergenceStats?.() ?? null;
3233
+ }
3234
+ get vram() {
3235
+ return this.stages.pathTracer?.vramTracker ?? null;
3236
+ }
3237
+ getMemoryInfo() {
3238
+ return this._ensureVRAMWiring(), this.stages.pathTracer?.vramTracker?.measure() ?? {
3239
+ current: 0,
3240
+ peak: 0,
3241
+ byCategory: {}
3242
+ };
3243
+ }
3244
+ getHostMemoryInfo() {
3245
+ let e = this._sdf;
3246
+ return e?.memory ? {
3247
+ preflight: e.memoryPreflight,
3248
+ ...e.memory.report
3249
+ } : null;
3250
+ }
3251
+ _ensureVRAMWiring() {
3252
+ if (this._vramWired) return;
3253
+ let e = this.stages.pathTracer?.vramTracker;
3254
+ if (!e) return;
3255
+ e.register("stages", () => this._collectStageTextures()), this._registerVRAM(e), e.register("canvas", () => [
3256
+ { bytes: this.canvas.width * this.canvas.height * 4 },
3257
+ ...this.renderer?._frameBufferTargets?.values() ?? [],
3258
+ ...this._canvasResources()
3259
+ ]);
3260
+ let t = () => e.measure();
3261
+ this._addTrackedListener(this, m.SCENE_REBUILD, t), this._addTrackedListener(this, m.ENVIRONMENT_LOADED, t), this._addTrackedListener(this, m.RESOLUTION_CHANGED, t), this._vramWired = !0;
3262
+ }
3263
+ _collectStageTextures() {
3264
+ let e = [], t = this.stages || {}, n = t.pathTracer;
3265
+ for (let r in t) {
3266
+ let i = t[r];
3267
+ if (!(!i || i === n || typeof i != "object")) for (let t in i) {
3268
+ let n = i[t];
3269
+ n && (n.isTexture || n.isRenderTarget) && e.push(n);
3270
+ }
3271
+ }
3272
+ return e;
3273
+ }
3274
+ getSceneMinY() {
3275
+ if (!this.meshScene) return 0;
3276
+ let e = new Je().setFromObject(this.meshScene);
3277
+ return Number.isFinite(e.min.y) ? e.min.y : 0;
3278
+ }
3279
+ getMaterialProperty(e, t) {
3280
+ return this.stages.pathTracer?.materialData.getMaterialProperty(e, t);
3281
+ }
3282
+ getMaterialPropertySource(e, t) {
3283
+ return this.stages.pathTracer?.materialData.getMaterialPropertySource(e, t);
3284
+ }
3285
+ setMaterialProperty(e, t, n) {
3286
+ if (this._sdf?.spilled && ee.has(t)) {
3287
+ this.ensureSceneResident().then(() => this.setMaterialProperty(e, t, n));
3288
+ return;
3289
+ }
3290
+ this.stages.pathTracer?.materialData.updateMaterialProperty(e, t, n), ["emissive", "emissiveIntensity"].includes(t) && this._sdf && this._uploadEmissivePayload(this._sdf.updateMaterialEmissive(e, t, n)), this.reset();
3291
+ }
3292
+ _uploadEmissivePayload(e) {
3293
+ !e || !this.stages.pathTracer || (this.stages.pathTracer.setEmissiveTriangleData(e.rawData, e.emissiveCount, e.totalPower, e.bitTrailMap), e.lightBVHNodeData && this.stages.pathTracer.setLightBVHData(e.lightBVHNodeData, e.lightBVHNodeCount));
3294
+ }
3295
+ _refreshEmissiveForVisibility() {
3296
+ let e = this._sdf?.instanceTable;
3297
+ if (!e) return;
3298
+ let t = /* @__PURE__ */ new Set();
3299
+ for (let n = 0; n < e.count; n++) e.isSet[n] && !e.visible[n] && t.add(e.sourceMesh[n]);
3300
+ this._uploadEmissivePayload(this._sdf.rebuildEmissiveForVisibility(t));
3301
+ }
3302
+ setEmissiveTriangleSampling(e) {
3303
+ this._emissiveSamplingUserSet = !0, this.settings.set("enableEmissiveTriangleSampling", e);
3304
+ }
3305
+ hasEmissiveGeometry() {
3306
+ return (this._sdf?.emissiveTriangleBuilder?.emissiveTriangles?.length ?? this._sdf?.emissiveTriangleCount ?? 0) > 0;
3307
+ }
3308
+ setMeshVisibility(e, t) {
3309
+ this.stages.pathTracer?.updateMeshVisibility(e, t), this._refreshEmissiveForVisibility(), this.reset();
3310
+ }
3311
+ updateAllMeshVisibility() {
3312
+ this.stages.pathTracer?.updateAllMeshVisibility(), this._refreshEmissiveForVisibility(), this.reset();
3313
+ }
3314
+ getScene() {
3315
+ return this.meshScene || this.scene;
3316
+ }
3317
+ setMeshVisibilityByUuid(e, t) {
3318
+ let n = this.getScene()?.getObjectByProperty("uuid", e);
3319
+ if (!n) return null;
3320
+ let r = typeof t == "function" ? !!t(n.visible) : !!t;
3321
+ return n.visible = r, this.updateAllMeshVisibility(), r;
3322
+ }
3323
+ setTextureTransform(e, t, n) {
3324
+ this.stages.pathTracer?.materialData.updateTextureTransform(e, t, n), this.reset();
3325
+ }
3326
+ _displaySource(e) {
3327
+ let t = this.pipeline?.context, n = t && this.stages.compositor?.resolveLightSource(t);
3328
+ return n && n.key !== "pathtracer:color" && n.texture !== e.texture ? {
3329
+ texture: n.texture,
3330
+ source: n.key.split(":")[0]
3331
+ } : (this._denoiserInUse() && this._issues.record(x.OUTPUT_SOURCE_FALLBACK, "renderToBuffer: 'display' was asked for, but no denoiser has published a picture — returned the raw accumulation", {
3332
+ requested: "display",
3333
+ read: "accumulation"
3334
+ }), null);
3335
+ }
3336
+ async _readDisplaySource(e, t, n) {
3337
+ let r = this._displaySource(e);
3338
+ return r ? {
3339
+ data: await this._readTexture(r.texture, t, n),
3340
+ source: r.source
3341
+ } : {
3342
+ data: await this.renderer.readRenderTargetPixelsAsync(e, 0, 0, t, n, 0),
3343
+ source: "accumulation"
3344
+ };
3345
+ }
3346
+ _readbackPass() {
3347
+ return this._textureReadback ??= new Kt(this.renderer);
3348
+ }
3349
+ _readTexture(e, t, n) {
3350
+ return this._readbackPass().read(e, t, n);
3351
+ }
3352
+ async setTextureColorSpace(e, t) {
3353
+ if (!e?.isTexture) throw Error("setTextureColorSpace wants a three.js texture");
3354
+ let n = e.userData ??= {};
3355
+ n.__rayzeeOriginalColorSpace === void 0 && (n.__rayzeeOriginalColorSpace = e.colorSpace);
3356
+ let r = n.__rayzeeOriginalColorSpace;
3357
+ if (delete n.ocioColorSpace, delete n.__rayzeeColorSpaceChoice, t == null) e.colorSpace = r, delete n.__rayzeeOriginalColorSpace;
3358
+ else if (t === "srgb" || t === "linear") e.colorSpace = t === "srgb" ? Fe : je, n.__rayzeeColorSpaceChoice = t;
3359
+ else {
3360
+ if (!this.color?.hasConfig) throw Error(`"${t}" needs a colour config loaded`);
3361
+ n.ocioColorSpace = t, e.colorSpace = Fe;
3362
+ }
3363
+ e.needsUpdate = !0, this.stages.pathTracer?.sdfs && await this.rebuildMaterials();
3364
+ }
3365
+ setColorManagement(e) {
3366
+ this.color?.dispose(), this.color = new e({ issues: this._issues }), S(this.color), this.renderer && this.color.attachRenderer(this.renderer);
3367
+ }
3368
+ async loadColorConfig(e = {}) {
3369
+ await this._leaveColorWorkingSpace();
3370
+ let t = T(this.renderer?.toneMapping), n = await this.color.loadConfig(e);
3371
+ return this.color.workingSpaceAdopted && await this.applyColorWorkingSpace(), (!(t?.source === "ocio" && T(this.renderer?.toneMapping) === t) || this.color.workingSpaceAdopted) && this.reset(), n;
3372
+ }
3373
+ async unloadColorConfig() {
3374
+ await this._leaveColorWorkingSpace(), this.color.unloadConfig(), this.reset();
3375
+ }
3376
+ async _leaveColorWorkingSpace() {
3377
+ this.color?.workingSpaceAdopted && (this.color.setWorkingSpace(null), await this.applyColorWorkingSpace());
3378
+ }
3379
+ async applyColorWorkingSpace() {
3380
+ let e = this.environmentManager?.getEnvironmentTexture?.(), t = !1;
3381
+ if (e && this.color?.hasConfig) try {
3382
+ t = this.color.convertTexturePixels(e);
3383
+ } catch (e) {
3384
+ $.warn(`environment colour conversion failed: ${e.message}`);
3385
+ }
3386
+ 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();
3387
+ }
3388
+ async rebuildMaterials(e) {
3389
+ await this.ensureSceneResident(), await this.stages.pathTracer?.rebuildMaterials(e || this.meshScene), this.reset();
3390
+ }
3391
+ async _initRenderer() {
3392
+ if (ie((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)");
3393
+ let e = await navigator.gpu.requestAdapter({ powerPreference: "high-performance" });
3394
+ if (!e) throw Error("Failed to get WebGPU adapter");
3395
+ this.adapterInfo = Kn(e), this.adapterInfo.isSoftware && (this._issues.warn(x.ADAPTER_SOFTWARE, `software GPU adapter "${this.adapterInfo.description || this.adapterInfo.vendor}" — renders are correct but orders of magnitude slower than hardware`, { ...this.adapterInfo }), $.warn(`software GPU adapter — check app.adapterInfo.isSoftware. ${this.adapterInfo.description}`));
3396
+ let t = e.limits, n = { maxColorAttachmentBytesPerSample: 128 };
3397
+ for (let e of [
3398
+ "maxBufferSize",
3399
+ "maxStorageBufferBindingSize",
3400
+ "maxSampledTexturesPerShaderStage",
3401
+ "maxStorageTexturesPerShaderStage",
3402
+ "maxTextureArrayLayers",
3403
+ "maxTextureDimension2D",
3404
+ "maxComputeInvocationsPerWorkgroup",
3405
+ "maxComputeWorkgroupStorageSize",
3406
+ "maxComputeWorkgroupSizeX",
3407
+ "maxComputeWorkgroupSizeY",
3408
+ "maxComputeWorkgroupSizeZ"
3409
+ ]) {
3410
+ let r = t[e];
3411
+ r !== void 0 && (n[e] = r);
3412
+ }
3413
+ if (n.maxStorageBuffersPerShaderStage = Math.min(t.maxStorageBuffersPerShaderStage, 10), this.renderer = new Le({
3414
+ canvas: this.canvas,
3415
+ alpha: !0,
3416
+ powerPreference: "high-performance",
3417
+ requiredLimits: n
3418
+ }), await Hn(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.");
3419
+ let r = this.renderer.backend?.device;
3420
+ r?.lost && (this._gpuDevice = r, this._deviceLostHolder = { app: this }, Wn(r, this._deviceLostHolder), r.onuncapturederror = (e) => $.error("WebGPU uncaptured error:", e.error)), Pe.setLTC(wt.init()), this.renderer.outputColorSpace = Fe, this.renderer.toneMapping = this._profile.toneMapping, this.renderer.toneMappingExposure = 1, this.renderer.setPixelRatio(1), this.color.attachRenderer(this.renderer);
3421
+ }
3422
+ _initScenes() {
3423
+ this.scene = new vt(), this.meshScene = new vt(), this._sceneHelpers = new At();
3424
+ }
3425
+ _initAssetPipeline() {
3426
+ this._sdf = new l({
3427
+ issues: this._issues,
3428
+ ...this._maxSceneBytes === void 0 ? {} : { maxSceneBytes: this._maxSceneBytes }
3429
+ }), this.assetLoader = new jn(this.meshScene, this.camera, null, {
3430
+ issues: this._issues,
3431
+ profile: this._profile
3432
+ }), this.assetLoader.setRenderer(this.renderer), this.assetLoader.createFloorPlane();
3433
+ }
3434
+ _initPipeline() {
3435
+ this._createStages();
3436
+ let { clientWidth: e, clientHeight: t } = this.canvas;
3437
+ this.pipeline = new Ut(this.renderer, e || 1, t || 1, { issues: this._issues }), this.pipeline.addStage(this.stages.pathTracer);
3438
+ for (let e of this._extraStages) this.pipeline.addStage(e);
3439
+ this.pipeline.addStage(this.stages.compositor);
3440
+ let n = this.canvas.clientWidth || 1, r = this.canvas.clientHeight || 1;
3441
+ this._displayWidth = n, this._displayHeight = r, this._renderWidth = n, this._renderHeight = r, this.pipeline.setSize(n, r);
3442
+ }
3443
+ async _initManagers() {
3444
+ this.lightManager = new Rn(this.scene, this._sceneHelpers, this.stages.pathTracer, {
3445
+ onReset: () => this.reset(),
3446
+ onLightRemoved: (e) => this._lightRemoved(e)
3447
+ }), this.environmentManager = this.stages.pathTracer.environment, this.environmentManager.issues = this._issues, this.stages.pathTracer.issues = this._issues, this.environmentManager.callbacks.onLightingChanged = () => this.pipeline.eventBus.emit("pipeline:lightingChanged"), this.environmentManager.callbacks.onReset = () => this.reset();
3448
+ }
3449
+ _wireEvents() {
3450
+ this.settings.bind(this._settingsBindings()), this.renderer.toneMappingExposure = this.settings.get("exposure") ?? 1, this.onResize(), this.resizeHandler = () => this.onResize(), this._autoResize && this._addTrackedListener(window, "resize", this.resizeHandler), this._onAssetLoaded = async (e) => {
3451
+ if (!this._loadingInProgress && !(this._applyingSceneMetadata && e.texture)) {
3452
+ if (e.model) this._clearAppendedModels(), await this.loadSceneData({ pendingEnvironment: this._beginSceneMetadataEnvironment() });
3453
+ else if (e.texture) {
3454
+ let e = this.meshScene.environment;
3455
+ e && this.stages.pathTracer && await this.stages.pathTracer.environment.setEnvironmentMap(e), _();
3456
+ }
3457
+ this.pauseRendering = !1, this.reset();
3458
+ }
3459
+ }, this._addTrackedListener(this.assetLoader, "load", this._onAssetLoaded), this.pipeline.eventBus.on("pathtracer:compiling", ({ compiling: e }) => this.dispatchEvent({
3460
+ type: m.SHADERS_COMPILING,
3461
+ compiling: e
3462
+ }));
3463
+ }
3464
+ _createStages() {
3465
+ this.stages.pathTracer = new c(this.renderer, this.scene, this.camera, { hostMemoryGB: this._hostMemoryGB }), this._extraStages = this._createExtraStages(), this.stages.compositor = new jt(this.renderer, {
3466
+ saturation: this.settings.get("saturation") ?? v.saturation,
3467
+ pathTracer: this.stages.pathTracer,
3468
+ displaySources: this._displaySources()
3469
+ });
3470
+ }
3471
+ _reconcileCompletion() {
3472
+ let e = this.stages.pathTracer;
3473
+ if (!e) return;
3474
+ let t = this.completion.isLimitReached(e, this.settings.get("renderLimitMode"), this.settings.get("renderTimeLimit"));
3475
+ t && !e.isComplete ? e.isComplete = !0 : !t && e.isComplete && (e.isComplete = !1, this.completion.resumeFromPause(), this._completionReopened(), this.dispatchEvent({ type: m.RENDER_RESET }), this.wake());
3476
+ }
3477
+ _forwardEvents(e, t) {
3478
+ if (e) for (let n of t) this._addTrackedListener(e, n, (e) => this.dispatchEvent(e));
3479
+ }
3480
+ _createCamera() {
3481
+ let e = new Fn(60, this.canvas.clientWidth / this.canvas.clientHeight || 1, .01, 1e3);
3482
+ return e.position.set(0, 0, 5), e;
3483
+ }
3484
+ _createExtraStages() {
3485
+ return [];
3486
+ }
3487
+ _displaySources() {
3488
+ return [];
3489
+ }
3490
+ _settingsBindings() {
3491
+ return {
3492
+ stages: this.stages,
3493
+ resetCallback: () => this.reset(),
3494
+ reconcileCompletion: () => this._reconcileCompletion(),
3495
+ applyExposure: (e) => {
3496
+ this.renderer.toneMappingExposure = e;
3497
+ }
3498
+ };
3499
+ }
3500
+ _beginFrame() {}
3501
+ _beforeTrace() {}
3502
+ _holdTrace() {
3503
+ return !1;
3504
+ }
3505
+ _afterTrace() {}
3506
+ _renderCompleted() {}
3507
+ _renderHelperOverlay() {
3508
+ this.scene.updateMatrixWorld();
3509
+ }
3510
+ _beforeReset() {}
3511
+ _afterReset() {}
3512
+ _dropDisplay() {}
3513
+ _releaseSceneState() {}
3514
+ _modelReplaced() {}
3515
+ _modelAnnounced() {}
3516
+ _sceneRebuilt() {}
3517
+ _sceneBoundsChanged() {}
3518
+ _notePlacementsMoving() {}
3519
+ _lightRemoved() {}
3520
+ _renderSizeChanged() {}
3521
+ _completionReopened() {}
3522
+ async _finalDenoise() {
3523
+ return !1;
3524
+ }
3525
+ _denoiserInUse() {
3526
+ return !1;
3527
+ }
3528
+ _displayCanvas() {
3529
+ return null;
3530
+ }
3531
+ _registerVRAM() {}
3532
+ _canvasResources() {
3533
+ return [];
3534
+ }
3535
+ _deterministicSnapshot() {
3536
+ return null;
3537
+ }
3538
+ _setDeterministicExtras() {}
3539
+ _disposeExtensions() {}
3540
+ };
3541
+ //#endregion
3542
+ export { Mt as _, nn as a, J as c, K as d, Qt as f, It as g, Lt as h, Fn as i, $t as l, Rt as m, Kn as n, Y as o, Ut as p, Rn as r, U as s, qn as t, Zt as u };