@oeave/bakery3 0.0.0-stage → 0.2.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 (86) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +562 -2
  3. package/dist/animation-B1h0Ryvj.d.ts +97 -0
  4. package/dist/bake/index.d.ts +369 -0
  5. package/dist/bake/index.js +9 -0
  6. package/dist/bake/index.js.map +1 -0
  7. package/dist/bake-DZ-CJR6f.d.ts +1364 -0
  8. package/dist/catalog/index.d.ts +100 -0
  9. package/dist/catalog/index.js +154 -0
  10. package/dist/catalog/index.js.map +1 -0
  11. package/dist/catalog.gen-BM-aNf7n.d.ts +733 -0
  12. package/dist/chunk-3G5QL4F4.js +145 -0
  13. package/dist/chunk-3G5QL4F4.js.map +1 -0
  14. package/dist/chunk-4E5VV4QY.js +12 -0
  15. package/dist/chunk-4E5VV4QY.js.map +1 -0
  16. package/dist/chunk-62M6XXNX.js +142 -0
  17. package/dist/chunk-62M6XXNX.js.map +1 -0
  18. package/dist/chunk-6FYI6AJM.js +1157 -0
  19. package/dist/chunk-6FYI6AJM.js.map +1 -0
  20. package/dist/chunk-6NYR73Y7.js +832 -0
  21. package/dist/chunk-6NYR73Y7.js.map +1 -0
  22. package/dist/chunk-APWUCEEB.js +118 -0
  23. package/dist/chunk-APWUCEEB.js.map +1 -0
  24. package/dist/chunk-HNMSWQU7.js +1709 -0
  25. package/dist/chunk-HNMSWQU7.js.map +1 -0
  26. package/dist/chunk-JFYUDERE.js +1412 -0
  27. package/dist/chunk-JFYUDERE.js.map +1 -0
  28. package/dist/chunk-KNUAOILG.js +551 -0
  29. package/dist/chunk-KNUAOILG.js.map +1 -0
  30. package/dist/chunk-KZLVTSBI.js +191 -0
  31. package/dist/chunk-KZLVTSBI.js.map +1 -0
  32. package/dist/chunk-LAKXC4WR.js +2028 -0
  33. package/dist/chunk-LAKXC4WR.js.map +1 -0
  34. package/dist/chunk-NXBAZGNB.js +1107 -0
  35. package/dist/chunk-NXBAZGNB.js.map +1 -0
  36. package/dist/chunk-QRCT5UGZ.js +3286 -0
  37. package/dist/chunk-QRCT5UGZ.js.map +1 -0
  38. package/dist/chunk-S4AJTLLN.js +23 -0
  39. package/dist/chunk-S4AJTLLN.js.map +1 -0
  40. package/dist/chunk-UWBP7B54.js +92 -0
  41. package/dist/chunk-UWBP7B54.js.map +1 -0
  42. package/dist/chunk-XK35ANPJ.js +346 -0
  43. package/dist/chunk-XK35ANPJ.js.map +1 -0
  44. package/dist/chunk-Z7IYVH22.js +4781 -0
  45. package/dist/chunk-Z7IYVH22.js.map +1 -0
  46. package/dist/chunk-ZEBVAIJJ.js +156 -0
  47. package/dist/chunk-ZEBVAIJJ.js.map +1 -0
  48. package/dist/devtools/index.d.ts +536 -0
  49. package/dist/devtools/index.js +15 -0
  50. package/dist/devtools/index.js.map +1 -0
  51. package/dist/environments/index.d.ts +93 -0
  52. package/dist/environments/index.js +382 -0
  53. package/dist/environments/index.js.map +1 -0
  54. package/dist/hotspots/index.d.ts +111 -0
  55. package/dist/hotspots/index.js +285 -0
  56. package/dist/hotspots/index.js.map +1 -0
  57. package/dist/index.d.ts +975 -0
  58. package/dist/index.js +15 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/node/index.cjs +5240 -0
  61. package/dist/node/index.cjs.map +1 -0
  62. package/dist/node/index.d.cts +4927 -0
  63. package/dist/node/index.d.ts +597 -0
  64. package/dist/node/index.js +1328 -0
  65. package/dist/node/index.js.map +1 -0
  66. package/dist/prepare-BtjY4G3q.d.ts +112 -0
  67. package/dist/presets/index.d.ts +562 -0
  68. package/dist/presets/index.js +14 -0
  69. package/dist/presets/index.js.map +1 -0
  70. package/dist/r3f/index.d.ts +159 -0
  71. package/dist/r3f/index.js +592 -0
  72. package/dist/r3f/index.js.map +1 -0
  73. package/dist/room-FS26KAPQ.js +9 -0
  74. package/dist/room-FS26KAPQ.js.map +1 -0
  75. package/dist/rooms.gen-DItzBR9k.d.ts +1462 -0
  76. package/dist/session-VCIQEO26.js +9 -0
  77. package/dist/session-VCIQEO26.js.map +1 -0
  78. package/dist/shapes/index.d.ts +222 -0
  79. package/dist/shapes/index.js +836 -0
  80. package/dist/shapes/index.js.map +1 -0
  81. package/dist/testRun-20OARnQr.d.ts +1139 -0
  82. package/dist/timeline-ChwgD7bT.d.ts +470 -0
  83. package/dist/tsl/index.d.ts +165 -0
  84. package/dist/tsl/index.js +310 -0
  85. package/dist/tsl/index.js.map +1 -0
  86. package/package.json +170 -4
@@ -0,0 +1,551 @@
1
+ import { buildPatch, probeTargets, bakeCandidates, configureShadow } from './chunk-JFYUDERE.js';
2
+ import { presetBaseUrl } from './chunk-4E5VV4QY.js';
3
+ import { prebakedRoomsUnder, findPresetRooms, roomShownBaked } from './chunk-APWUCEEB.js';
4
+ import { PRESETS_VERSION } from './chunk-6NYR73Y7.js';
5
+ import { Bakery3Error } from './chunk-3G5QL4F4.js';
6
+ import { LinearSRGBColorSpace, SRGBColorSpace, LinearFilter, ClampToEdgeWrapping, TextureLoader, EquirectangularReflectionMapping, NoColorSpace } from 'three';
7
+ import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
8
+
9
+ function configureLightmap(texture, format) {
10
+ texture.channel = 1;
11
+ texture.flipY = false;
12
+ texture.colorSpace = format === "exr" ? LinearSRGBColorSpace : SRGBColorSpace;
13
+ texture.generateMipmaps = false;
14
+ texture.minFilter = LinearFilter;
15
+ texture.magFilter = LinearFilter;
16
+ texture.wrapS = ClampToEdgeWrapping;
17
+ texture.wrapT = ClampToEdgeWrapping;
18
+ texture.needsUpdate = true;
19
+ return texture;
20
+ }
21
+ function configureProbe(texture) {
22
+ texture.mapping = EquirectangularReflectionMapping;
23
+ texture.colorSpace = LinearSRGBColorSpace;
24
+ texture.needsUpdate = true;
25
+ return texture;
26
+ }
27
+ function configureStandInMap(texture, role) {
28
+ texture.channel = 0;
29
+ if (role === "billboard") {
30
+ texture.colorSpace = LinearSRGBColorSpace;
31
+ texture.generateMipmaps = false;
32
+ texture.minFilter = LinearFilter;
33
+ texture.magFilter = LinearFilter;
34
+ } else {
35
+ texture.flipY = true;
36
+ texture.colorSpace = role === "color" ? SRGBColorSpace : NoColorSpace;
37
+ }
38
+ texture.wrapS = ClampToEdgeWrapping;
39
+ texture.wrapT = ClampToEdgeWrapping;
40
+ texture.needsUpdate = true;
41
+ return texture;
42
+ }
43
+ function defaultTextureFactory() {
44
+ const exr = new EXRLoader();
45
+ const png = new TextureLoader();
46
+ exr.setCrossOrigin("anonymous");
47
+ png.setCrossOrigin("anonymous");
48
+ return async (source) => {
49
+ const loader = source.format === "exr" ? exr : png;
50
+ const texture = await new Promise((resolve, reject) => {
51
+ loader.load(
52
+ source.url,
53
+ (loaded) => resolve(loaded),
54
+ void 0,
55
+ () => reject(
56
+ new Bakery3Error({
57
+ code: "InvalidRequest",
58
+ message: source.role === "probe" ? "Could not load the reflection probe." : source.role === "color" || source.role === "normal" || source.role === "billboard" ? `Could not load the ${source.role} map of "${source.objectId}".` : `Could not load the lightmap for "${source.objectId}".`,
59
+ why: `${source.url} did not load. A bundle's uris are relative to where the bundle came from, and the artifacts have to be reachable from the browser.`,
60
+ fix: "Pass { baseUrl } to addGeneration() if the bundle moved, and check the artifact server allows cross-origin reads."
61
+ })
62
+ )
63
+ );
64
+ });
65
+ if (source.role === "probe") return configureProbe(texture);
66
+ if (source.role === "shadow") return configureShadow(texture);
67
+ if (source.role === "color" || source.role === "normal" || source.role === "billboard") {
68
+ return configureStandInMap(texture, source.role);
69
+ }
70
+ return configureLightmap(texture, source.format);
71
+ };
72
+ }
73
+ function resolveBundleUri(uri, baseUrl) {
74
+ if (/^[a-z][a-z0-9+.-]*:/i.test(uri) || uri.startsWith("//")) return uri;
75
+ if (!baseUrl) return uri;
76
+ try {
77
+ return new URL(uri, baseUrl).toString();
78
+ } catch {
79
+ return uri;
80
+ }
81
+ }
82
+
83
+ // src/bake/session.ts
84
+ var LIVE = -1;
85
+ function createBakeSession(options) {
86
+ const scene = options.scene;
87
+ const intensity = options.intensity ?? 1;
88
+ const shading = options.shading ?? "replace";
89
+ const resident = Math.max(1, options.residentGenerations ?? 3);
90
+ let useProbe = options.probe ?? true;
91
+ const loadTexture = options.textureFactory ?? defaultTextureFactory();
92
+ const generations = [];
93
+ const loaded = /* @__PURE__ */ new Map();
94
+ const listeners = /* @__PURE__ */ new Set();
95
+ let current = LIVE;
96
+ let patch = null;
97
+ let lastReport = null;
98
+ let comparing = false;
99
+ let muted = null;
100
+ let disposed = false;
101
+ let applyToken = 0;
102
+ let clock = 0;
103
+ let suspendedRooms = [];
104
+ function emit() {
105
+ for (const listener of listeners) listener(session);
106
+ }
107
+ function releasePatch() {
108
+ patch?.dispose();
109
+ patch = null;
110
+ comparing = false;
111
+ for (const room of suspendedRooms) room.resume();
112
+ suspendedRooms = [];
113
+ }
114
+ function disposeGeneration(index) {
115
+ const entry = loaded.get(index);
116
+ if (!entry) return;
117
+ for (const texture of new Set(entry.textures.values())) texture.dispose();
118
+ for (const texture of new Set(entry.room?.textures.values() ?? []))
119
+ texture.dispose();
120
+ for (const maps of entry.proxies.values()) {
121
+ if (maps.kind === "billboard") maps.map.dispose();
122
+ else if (maps.kind === "decimated") maps.light.dispose();
123
+ else
124
+ for (const texture of [maps.color, maps.normal, maps.light])
125
+ texture.dispose();
126
+ }
127
+ entry.probe?.dispose();
128
+ entry.shadow?.dispose();
129
+ loaded.delete(index);
130
+ const generation = generations[index];
131
+ if (generation) generation.loaded = false;
132
+ }
133
+ function evict(keep) {
134
+ if (loaded.size <= resident) return;
135
+ const ranked = [...loaded.entries()].filter(([index]) => index !== keep).sort((a, b) => a[1].usedAt - b[1].usedAt);
136
+ while (loaded.size > resident && ranked.length) {
137
+ disposeGeneration(ranked.shift()[0]);
138
+ }
139
+ }
140
+ async function ensureLoaded(index) {
141
+ const existing = loaded.get(index);
142
+ if (existing) {
143
+ existing.usedAt = ++clock;
144
+ return existing;
145
+ }
146
+ const generation = generations[index];
147
+ const textures = /* @__PURE__ */ new Map();
148
+ const failures = /* @__PURE__ */ new Map();
149
+ const byUrl = /* @__PURE__ */ new Map();
150
+ for (const baked of generation.bundle.objects) {
151
+ try {
152
+ const url = resolveBundleUri(baked.lightmap.uri, generation.baseUrl);
153
+ let texture = byUrl.get(url);
154
+ if (!texture) {
155
+ texture = await loadTexture({
156
+ url,
157
+ format: baked.lightmap.format,
158
+ objectId: baked.objectId,
159
+ size: baked.lightmap.size
160
+ });
161
+ byUrl.set(url, texture);
162
+ }
163
+ textures.set(baked.objectId, texture);
164
+ } catch (error) {
165
+ failures.set(baked.objectId, describe(error));
166
+ }
167
+ }
168
+ const proxies = /* @__PURE__ */ new Map();
169
+ for (const proxy of generation.bundle.proxies ?? []) {
170
+ const label = proxy.name ?? `stand-in ${proxy.index}`;
171
+ const load = (uri, format, role, size) => loadTexture({
172
+ url: resolveBundleUri(uri, generation.baseUrl),
173
+ format,
174
+ objectId: label,
175
+ size,
176
+ role
177
+ });
178
+ try {
179
+ if (proxy.kind === "billboard") {
180
+ proxies.set(proxy.index, {
181
+ kind: "billboard",
182
+ map: await load(proxy.map.uri, "exr", "billboard", proxy.map.width)
183
+ });
184
+ } else if (proxy.kind === "decimated") {
185
+ proxies.set(proxy.index, {
186
+ kind: "decimated",
187
+ light: await load(
188
+ proxy.lightmap.uri,
189
+ "exr",
190
+ "lightmap",
191
+ proxy.lightmap.size
192
+ )
193
+ });
194
+ } else {
195
+ const size = proxy.lightmap.size;
196
+ proxies.set(proxy.index, {
197
+ kind: "mesh",
198
+ color: await load(proxy.color.uri, "png", "color", size),
199
+ normal: await load(proxy.normal.uri, "png", "normal", size),
200
+ light: await load(proxy.lightmap.uri, "exr", "lightmap", size)
201
+ });
202
+ }
203
+ } catch (error) {
204
+ failures.set(`simplify[${proxy.index}]`, describe(error));
205
+ }
206
+ }
207
+ let shadow;
208
+ if (generation.bundle.shadow) {
209
+ const shadowEntry = generation.bundle.shadow;
210
+ try {
211
+ shadow = configureShadow(
212
+ await loadTexture({
213
+ url: resolveBundleUri(shadowEntry.uri, generation.baseUrl),
214
+ format: shadowEntry.format,
215
+ objectId: "shadow",
216
+ size: shadowEntry.size,
217
+ role: "shadow"
218
+ })
219
+ );
220
+ } catch (error) {
221
+ failures.set("shadow", describe(error));
222
+ }
223
+ }
224
+ let room;
225
+ let roomFailed;
226
+ const wantsRoom = findPresetRooms(scene).some(roomShownBaked) ? void 0 : generation.bundle.room;
227
+ if (wantsRoom) {
228
+ const base = `${(options.presetBaseUrl ?? presetBaseUrl()).replace(/\/$/, "")}/v${PRESETS_VERSION}/`;
229
+ const url = new URL(wantsRoom.uri, base).toString();
230
+ try {
231
+ const response = await fetch(url);
232
+ if (!response.ok)
233
+ throw new Error(`${response.status} ${response.statusText}`);
234
+ const bundle = await response.json();
235
+ const roomTextures = /* @__PURE__ */ new Map();
236
+ const byUrl2 = /* @__PURE__ */ new Map();
237
+ for (const baked of bundle.objects) {
238
+ const textureUrl = resolveBundleUri(baked.lightmap.uri, url);
239
+ let texture = byUrl2.get(textureUrl);
240
+ if (!texture) {
241
+ texture = await loadTexture({
242
+ url: textureUrl,
243
+ format: baked.lightmap.format,
244
+ objectId: baked.objectId,
245
+ size: baked.lightmap.size
246
+ });
247
+ byUrl2.set(textureUrl, texture);
248
+ }
249
+ roomTextures.set(baked.objectId, texture);
250
+ }
251
+ room = { bundle, baseUrl: url, textures: roomTextures };
252
+ } catch (error) {
253
+ roomFailed = describe(error);
254
+ }
255
+ }
256
+ const entry = {
257
+ textures,
258
+ failures,
259
+ proxies,
260
+ usedAt: ++clock,
261
+ ...shadow ? { shadow } : {},
262
+ ...room ? { room } : {},
263
+ ...roomFailed ? { roomFailed } : {}
264
+ };
265
+ loaded.set(index, entry);
266
+ generation.loaded = true;
267
+ return entry;
268
+ }
269
+ async function ensureProbe(index, entry) {
270
+ if (entry.probe || entry.probeFailed) return entry.probe;
271
+ const generation = generations[index];
272
+ const probeEntry = generation.bundle.probe;
273
+ if (!probeEntry) return void 0;
274
+ try {
275
+ entry.probe = configureProbe(
276
+ await loadTexture({
277
+ url: resolveBundleUri(probeEntry.uri, generation.baseUrl),
278
+ format: probeEntry.format,
279
+ objectId: "probe",
280
+ size: probeEntry.width,
281
+ role: "probe"
282
+ })
283
+ );
284
+ } catch (error) {
285
+ entry.probeFailed = describe(error);
286
+ }
287
+ return entry.probe;
288
+ }
289
+ const session = {
290
+ get generations() {
291
+ return generations;
292
+ },
293
+ get current() {
294
+ return current;
295
+ },
296
+ get lastReport() {
297
+ return lastReport;
298
+ },
299
+ get comparing() {
300
+ return comparing;
301
+ },
302
+ get lightsMuted() {
303
+ return muted !== null;
304
+ },
305
+ get probe() {
306
+ return useProbe;
307
+ },
308
+ candidates() {
309
+ return bakeCandidates({ scene });
310
+ },
311
+ addGeneration(bundle, addOptions = {}) {
312
+ if (disposed) throw disposedError("addGeneration");
313
+ const index = generations.length;
314
+ generations.push({
315
+ index,
316
+ label: addOptions.label ?? `${bundle.settings.textureSize} \xB7 ${bundle.settings.quality}`,
317
+ bundle,
318
+ ...addOptions.baseUrl !== void 0 ? { baseUrl: addOptions.baseUrl } : {},
319
+ createdAt: Date.now(),
320
+ loaded: false
321
+ });
322
+ emit();
323
+ return index;
324
+ },
325
+ async apply(index) {
326
+ if (disposed) throw disposedError("apply");
327
+ if (index === LIVE) {
328
+ session.revert();
329
+ return lastReport;
330
+ }
331
+ const generation = generations[index];
332
+ if (!generation) {
333
+ throw new Bakery3Error({
334
+ code: "InvalidRequest",
335
+ message: `There is no bake generation ${index}.`,
336
+ why: `This session has ${generations.length} generation(s).`,
337
+ fix: "Call addGeneration(bundle) with a BakeBundle first, or revert() to go back to live."
338
+ });
339
+ }
340
+ const token = ++applyToken;
341
+ const entry = await ensureLoaded(index);
342
+ const probe = useProbe ? await ensureProbe(index, entry) : void 0;
343
+ if (token !== applyToken || disposed)
344
+ return lastReport ?? emptyReport(index);
345
+ releasePatch();
346
+ const objects = [];
347
+ const missingTextures = [];
348
+ for (const baked of generation.bundle.objects) {
349
+ const texture = entry.textures.get(baked.objectId);
350
+ if (!texture) {
351
+ missingTextures.push({
352
+ objectId: baked.objectId,
353
+ ...baked.name ? { name: baked.name } : {},
354
+ code: "BakeLightmapUnavailable",
355
+ message: `The lightmap for "${baked.name ?? baked.objectId}" did not load.`,
356
+ why: entry.failures.get(baked.objectId) ?? "Its texture is missing from this generation, so there is nothing to apply.",
357
+ fix: "Check the bundle uris are reachable from the browser, then apply again."
358
+ });
359
+ continue;
360
+ }
361
+ objects.push({ baked, texture });
362
+ }
363
+ const roomObjects = (entry.room?.bundle.objects ?? []).flatMap(
364
+ (baked) => {
365
+ const texture = entry.room.textures.get(baked.objectId);
366
+ return texture ? [{ baked, texture }] : [];
367
+ }
368
+ );
369
+ const litIds = new Set(
370
+ generation.bundle.objects.map((object) => object.objectId)
371
+ );
372
+ for (const { baked } of roomObjects) litIds.add(baked.objectId);
373
+ const standIns = (generation.bundle.proxies ?? []).flatMap((proxy) => {
374
+ const textures = entry.proxies.get(proxy.index);
375
+ if (textures) return [{ proxy, textures }];
376
+ missingTextures.push({
377
+ objectId: `simplify[${proxy.index}]`,
378
+ ...proxy.name ? { name: proxy.name } : {},
379
+ code: "BakeLightmapUnavailable",
380
+ message: `The maps for the stand-in "${proxy.name ?? proxy.index}" did not load.`,
381
+ why: entry.failures.get(`simplify[${proxy.index}]`) ?? "One of its textures is missing from this generation.",
382
+ fix: "Check the bundle uris are reachable from the browser, then apply again. The objects it replaces are left as they were."
383
+ });
384
+ return [];
385
+ });
386
+ for (const { proxy } of standIns)
387
+ for (const id of proxy.replaces) litIds.add(id);
388
+ const byObjectId = /* @__PURE__ */ new Map();
389
+ for (const entry_ of [...roomObjects, ...objects])
390
+ byObjectId.set(entry_.baked.objectId, entry_);
391
+ const winners = [...byObjectId.values()];
392
+ const touched = /* @__PURE__ */ new Set([
393
+ ...byObjectId.keys(),
394
+ ...standIns.flatMap(({ proxy }) => proxy.replaces)
395
+ ]);
396
+ for (const { group, handle } of prebakedRoomsUnder(scene)) {
397
+ if (group === scene) continue;
398
+ let lightsIt = false;
399
+ group.traverse((node) => {
400
+ if (touched.has(node.userData.bakery3Id)) lightsIt = true;
401
+ });
402
+ if (!lightsIt) continue;
403
+ handle.suspend();
404
+ suspendedRooms.push(handle);
405
+ }
406
+ const built = buildPatch({
407
+ scene,
408
+ objects: winners,
409
+ intensity,
410
+ shading,
411
+ ...probe ? {
412
+ probe: {
413
+ texture: probe,
414
+ meshes: probeTargets(session.candidates(), litIds)
415
+ }
416
+ } : {},
417
+ ...standIns.length ? { proxies: standIns } : {},
418
+ ...generation.bundle.shadow && entry.shadow ? {
419
+ shadow: {
420
+ shadow: generation.bundle.shadow,
421
+ texture: entry.shadow
422
+ }
423
+ } : {}
424
+ });
425
+ built.patch.on();
426
+ patch = built.patch;
427
+ current = index;
428
+ const bakedIds = new Set(litIds);
429
+ for (const skip of generation.bundle.skipped) bakedIds.add(skip.objectId);
430
+ const unbaked = session.candidates().filter(
431
+ (candidate) => candidate.bakeable && candidate.defaultInclude && !bakedIds.has(candidate.objectId)
432
+ ).map((candidate) => candidate.objectId);
433
+ lastReport = {
434
+ generation: index,
435
+ applied: built.applied,
436
+ unmatched: built.unmatched,
437
+ unbaked,
438
+ skipped: [...missingTextures, ...built.skipped],
439
+ probed: built.probed,
440
+ standIns: built.standIns,
441
+ replaced: built.replaced,
442
+ shadow: built.shadow,
443
+ ...entry.room ? {
444
+ room: {
445
+ name: generation.bundle.room.name,
446
+ lighting: generation.bundle.room.lighting,
447
+ applied: roomObjects.filter(
448
+ ({ baked }) => built.applied.includes(baked.objectId)
449
+ ).length,
450
+ unmatched: roomObjects.filter(
451
+ ({ baked }) => built.unmatched.includes(baked.objectId)
452
+ ).length
453
+ }
454
+ } : {},
455
+ ...entry.roomFailed ? { roomError: entry.roomFailed } : {},
456
+ ...useProbe && entry.probeFailed ? { probeError: entry.probeFailed } : {}
457
+ };
458
+ evict(index);
459
+ emit();
460
+ return lastReport;
461
+ },
462
+ revert() {
463
+ releasePatch();
464
+ current = LIVE;
465
+ lastReport = emptyReport(LIVE);
466
+ emit();
467
+ },
468
+ compare(showLive) {
469
+ if (!patch) return;
470
+ if (showLive) patch.off();
471
+ else patch.on();
472
+ comparing = showLive;
473
+ emit();
474
+ },
475
+ async setProbe(on) {
476
+ if (disposed) throw disposedError("setProbe");
477
+ if (on === useProbe) return lastReport ?? emptyReport(current);
478
+ useProbe = on;
479
+ if (current === LIVE) {
480
+ emit();
481
+ return lastReport ?? emptyReport(LIVE);
482
+ }
483
+ return session.apply(current);
484
+ },
485
+ muteLights(on) {
486
+ if (on === (muted !== null)) return;
487
+ if (on) {
488
+ const touched = [];
489
+ scene.traverse((object) => {
490
+ const light = object;
491
+ if (!light.isLight) return;
492
+ touched.push({ light, intensity: light.intensity });
493
+ light.intensity = 0;
494
+ });
495
+ muted = touched;
496
+ } else {
497
+ for (const entry of muted) entry.light.intensity = entry.intensity;
498
+ muted = null;
499
+ }
500
+ emit();
501
+ },
502
+ on(_event, listener) {
503
+ listeners.add(listener);
504
+ return () => listeners.delete(listener);
505
+ },
506
+ dispose() {
507
+ if (disposed) return;
508
+ disposed = true;
509
+ releasePatch();
510
+ if (muted) {
511
+ for (const entry of muted) entry.light.intensity = entry.intensity;
512
+ muted = null;
513
+ }
514
+ for (const index of [...loaded.keys()]) disposeGeneration(index);
515
+ current = LIVE;
516
+ listeners.clear();
517
+ }
518
+ };
519
+ return session;
520
+ }
521
+ function emptyReport(generation) {
522
+ return {
523
+ generation,
524
+ applied: [],
525
+ unmatched: [],
526
+ unbaked: [],
527
+ skipped: [],
528
+ probed: [],
529
+ standIns: [],
530
+ replaced: [],
531
+ shadow: false
532
+ };
533
+ }
534
+ function describe(error) {
535
+ if (error && typeof error === "object" && "toDisplayString" in error) {
536
+ return error.toDisplayString();
537
+ }
538
+ return error instanceof Error ? error.message : String(error);
539
+ }
540
+ function disposedError(what) {
541
+ return new Bakery3Error({
542
+ code: "InvalidRequest",
543
+ message: `${what}() was called on a disposed bake session.`,
544
+ why: "dispose() reverts the scene and drops every texture, so there is nothing left to apply.",
545
+ fix: "Create a new session with createBakeSession({ scene })."
546
+ });
547
+ }
548
+
549
+ export { LIVE, configureLightmap, createBakeSession };
550
+ //# sourceMappingURL=chunk-KNUAOILG.js.map
551
+ //# sourceMappingURL=chunk-KNUAOILG.js.map