@oeave/bakery3 0.1.0 → 0.3.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 (77) hide show
  1. package/README.md +10 -10
  2. package/dist/bake/index.d.ts +3 -3
  3. package/dist/bake/index.js +4 -4
  4. package/dist/{bake-DaOlenyx.d.ts → bake-DZ-CJR6f.d.ts} +8 -1
  5. package/dist/catalog/index.d.ts +5 -5
  6. package/dist/catalog/index.js +3 -3
  7. package/dist/{chunk-TGFNQBKC.js → chunk-3T3FJOSD.js} +5 -5
  8. package/dist/chunk-3T3FJOSD.js.map +1 -0
  9. package/dist/{chunk-V3QINEEG.js → chunk-62M6XXNX.js} +58 -3
  10. package/dist/chunk-62M6XXNX.js.map +1 -0
  11. package/dist/{chunk-ARMTTZXZ.js → chunk-6FAMQZXB.js} +8 -8
  12. package/dist/chunk-6FAMQZXB.js.map +1 -0
  13. package/dist/{chunk-54WJDN5R.js → chunk-CSSJRP5W.js} +9 -6
  14. package/dist/chunk-CSSJRP5W.js.map +1 -0
  15. package/dist/{chunk-W6WQ5UP7.js → chunk-EN4ROBYQ.js} +32 -5
  16. package/dist/chunk-EN4ROBYQ.js.map +1 -0
  17. package/dist/chunk-KZLVTSBI.js +191 -0
  18. package/dist/chunk-KZLVTSBI.js.map +1 -0
  19. package/dist/{chunk-MD2U6S4N.js → chunk-LAKXC4WR.js} +218 -142
  20. package/dist/chunk-LAKXC4WR.js.map +1 -0
  21. package/dist/{chunk-HQTUFVMM.js → chunk-NEK5TBEH.js} +3 -3
  22. package/dist/chunk-NEK5TBEH.js.map +1 -0
  23. package/dist/chunk-OPM2L63B.js +253 -0
  24. package/dist/chunk-OPM2L63B.js.map +1 -0
  25. package/dist/{chunk-APBOWWSV.js → chunk-R5IUPOWI.js} +3 -3
  26. package/dist/chunk-R5IUPOWI.js.map +1 -0
  27. package/dist/{chunk-6YVQANMW.js → chunk-STRK4SZN.js} +262 -16
  28. package/dist/chunk-STRK4SZN.js.map +1 -0
  29. package/dist/{chunk-CX4WTVGH.js → chunk-WLEFNUOH.js} +411 -371
  30. package/dist/chunk-WLEFNUOH.js.map +1 -0
  31. package/dist/{chunk-25ZXSVQ3.js → chunk-X6GW43EX.js} +3 -3
  32. package/dist/{chunk-25ZXSVQ3.js.map → chunk-X6GW43EX.js.map} +1 -1
  33. package/dist/{chunk-WBIAFIHV.js → chunk-XK35ANPJ.js} +3 -3
  34. package/dist/{chunk-WBIAFIHV.js.map → chunk-XK35ANPJ.js.map} +1 -1
  35. package/dist/devtools/index.d.ts +3 -3
  36. package/dist/devtools/index.js +10 -9
  37. package/dist/hotspots/index.d.ts +237 -31
  38. package/dist/hotspots/index.js +1013 -118
  39. package/dist/hotspots/index.js.map +1 -1
  40. package/dist/index.d.ts +39 -8
  41. package/dist/index.js +11 -10
  42. package/dist/node/index.cjs +266 -141
  43. package/dist/node/index.cjs.map +1 -1
  44. package/dist/node/index.d.cts +152 -87
  45. package/dist/node/index.d.ts +27 -6
  46. package/dist/node/index.js +52 -3
  47. package/dist/node/index.js.map +1 -1
  48. package/dist/{prepare-C5qVvaw4.d.ts → prepare-BtjY4G3q.d.ts} +1 -1
  49. package/dist/presets/index.d.ts +37 -1
  50. package/dist/presets/index.js +4 -4
  51. package/dist/presets/index.js.map +1 -1
  52. package/dist/r3f/index.d.ts +4 -4
  53. package/dist/r3f/index.js +13 -12
  54. package/dist/r3f/index.js.map +1 -1
  55. package/dist/{room-S5TLCK4F.js → room-BM7Z7NKG.js} +6 -6
  56. package/dist/{room-S5TLCK4F.js.map → room-BM7Z7NKG.js.map} +1 -1
  57. package/dist/{rooms.gen-vhj6sFW5.d.ts → rooms.gen-DItzBR9k.d.ts} +112 -84
  58. package/dist/session-NPVBESWA.js +9 -0
  59. package/dist/{session-YCQS4MRH.js.map → session-NPVBESWA.js.map} +1 -1
  60. package/dist/{testRun-BIPXaVPb.d.ts → testRun-20OARnQr.d.ts} +12 -3
  61. package/dist/tsl/index.d.ts +14 -1
  62. package/dist/tsl/index.js +8 -2
  63. package/dist/tsl/index.js.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/chunk-54WJDN5R.js.map +0 -1
  66. package/dist/chunk-6YVQANMW.js.map +0 -1
  67. package/dist/chunk-AF5BIELI.js +0 -70
  68. package/dist/chunk-AF5BIELI.js.map +0 -1
  69. package/dist/chunk-APBOWWSV.js.map +0 -1
  70. package/dist/chunk-ARMTTZXZ.js.map +0 -1
  71. package/dist/chunk-CX4WTVGH.js.map +0 -1
  72. package/dist/chunk-HQTUFVMM.js.map +0 -1
  73. package/dist/chunk-MD2U6S4N.js.map +0 -1
  74. package/dist/chunk-TGFNQBKC.js.map +0 -1
  75. package/dist/chunk-V3QINEEG.js.map +0 -1
  76. package/dist/chunk-W6WQ5UP7.js.map +0 -1
  77. package/dist/session-YCQS4MRH.js +0 -9
package/README.md CHANGED
@@ -495,16 +495,16 @@ parametric room and HDR environments. See
495
495
 
496
496
  ## What's supported
497
497
 
498
- | | |
499
- | -------------------- | ----------------------------------------------------------------------- |
500
- | **Cameras** | Perspective, orthographic |
501
- | **Geometry** | Static meshes, instanced meshes, skinned meshes, morph targets |
502
- | **Materials** | Standard and physical, with clearcoat, transmission, sheen, iridescence |
503
- | **Node materials** | Standard and physical node materials with TSL graphs |
504
- | **Approximated** | Basic, Lambert, Phong, Toon, Matcap (each warns once) |
505
- | **Not translatable** | `ShaderMaterial`, `RawShaderMaterial`: declare a fallback |
506
- | **Lighting** | Directional, point, spot, area, hemisphere, ambient, HDRI, IES |
507
- | **Output** | PNG, JPEG, WebP, EXR. Transparent background by default |
498
+ | | |
499
+ | -------------------- | ------------------------------------------------------------------------------------------- |
500
+ | **Cameras** | Perspective, orthographic |
501
+ | **Geometry** | Static meshes, instanced meshes, skinned meshes, morph targets |
502
+ | **Materials** | Standard and physical, with clearcoat, transmission, sheen |
503
+ | **Node materials** | Standard and physical node materials with TSL graphs |
504
+ | **Approximated** | Basic, Lambert, Phong, Toon, Matcap; Normal, Depth, Distance as flat gray (each warns once) |
505
+ | **Not translatable** | `ShaderMaterial`, `RawShaderMaterial`: declare a fallback |
506
+ | **Lighting** | Directional, point, spot, area, hemisphere, ambient, HDRI, IES |
507
+ | **Output** | PNG, JPEG, WebP, EXR. Transparent background by default |
508
508
 
509
509
  The full list is at
510
510
  [bakery3.com/docs/compatibility](https://bakery3.com/docs/compatibility).
@@ -1,7 +1,7 @@
1
- export { B as BakeSimplifyInput, P as PrepareBakeSettings } from '../prepare-C5qVvaw4.js';
1
+ export { B as BakeSimplifyInput, P as PrepareBakeSettings } from '../prepare-BtjY4G3q.js';
2
2
  import { Mesh, Object3D, Texture, Scene } from 'three';
3
- import { j as BakeBundle } from '../bake-DaOlenyx.js';
4
- export { r as BAKE_TEXTURE_SIZES, a as BakeQuality, i as BakeSettings, e as BakeSpec, B as BakeTextureSize, s as MAX_BAKE_OBJECTS, t as MAX_BAKE_TEXELS } from '../bake-DaOlenyx.js';
3
+ import { j as BakeBundle } from '../bake-DZ-CJR6f.js';
4
+ export { r as BAKE_TEXTURE_SIZES, a as BakeQuality, i as BakeSettings, e as BakeSpec, B as BakeTextureSize, s as MAX_BAKE_OBJECTS, t as MAX_BAKE_TEXELS } from '../bake-DZ-CJR6f.js';
5
5
  import '../animation-B1h0Ryvj.js';
6
6
 
7
7
  /**
@@ -1,9 +1,9 @@
1
- export { configureLightmap, createBakeSession } from '../chunk-TGFNQBKC.js';
2
- export { bakeCandidates } from '../chunk-HQTUFVMM.js';
1
+ export { configureLightmap, createBakeSession } from '../chunk-3T3FJOSD.js';
2
+ export { bakeCandidates } from '../chunk-NEK5TBEH.js';
3
3
  import '../chunk-4E5VV4QY.js';
4
- export { BAKE_TEXTURE_SIZES, MAX_BAKE_OBJECTS, MAX_BAKE_TEXELS } from '../chunk-W6WQ5UP7.js';
4
+ export { BAKE_TEXTURE_SIZES, MAX_BAKE_OBJECTS, MAX_BAKE_TEXELS } from '../chunk-EN4ROBYQ.js';
5
5
  import '../chunk-6NYR73Y7.js';
6
- import '../chunk-MD2U6S4N.js';
6
+ import '../chunk-LAKXC4WR.js';
7
7
  import '../chunk-3G5QL4F4.js';
8
8
  //# sourceMappingURL=index.js.map
9
9
  //# sourceMappingURL=index.js.map
@@ -221,10 +221,17 @@ type CameraSpec = {
221
221
  zoom?: number;
222
222
  /** Present when the developer named a camera; only ever a label. */
223
223
  name?: string;
224
- /** Physical-camera extras. Depth of field is off unless `fStop` is set. */
224
+ /**
225
+ * Depth of field, off unless present. `fStop` is a full-frame f-number
226
+ * at this `fov`; `focalDistance` is in metres along the view axis.
227
+ * `target` is the world point it was measured to: a worker that reads
228
+ * it keeps that point sharp on every frame of a clip, and one that
229
+ * does not still focuses the first frame right.
230
+ */
225
231
  focus?: {
226
232
  fStop: number;
227
233
  focalDistance: number;
234
+ target?: Vec3;
228
235
  };
229
236
  } | {
230
237
  type: 'orthographic';
@@ -1,12 +1,12 @@
1
1
  import { Scene, Object3D } from 'three';
2
- import { Q as QualityPreset, O as OutputSpec } from '../bake-DaOlenyx.js';
3
- import { B as BatchProgress, V as VariantsQuote, a as BatchRecord } from '../testRun-BIPXaVPb.js';
4
- export { b as Batch } from '../testRun-BIPXaVPb.js';
2
+ import { Q as QualityPreset, O as OutputSpec } from '../bake-DZ-CJR6f.js';
3
+ import { B as BatchProgress, V as VariantsQuote, a as BatchRecord } from '../testRun-20OARnQr.js';
4
+ export { b as Batch } from '../testRun-20OARnQr.js';
5
5
  import { CatalogCamera, CatalogFinish, Bakery3 } from '../index.js';
6
- import { R as RoomPresetName, a as RoomPresetLighting } from '../rooms.gen-vhj6sFW5.js';
6
+ import { R as RoomPresetName, a as RoomPresetLighting } from '../rooms.gen-DItzBR9k.js';
7
7
  import '../animation-B1h0Ryvj.js';
8
8
  import '../timeline-ChwgD7bT.js';
9
- import '../prepare-C5qVvaw4.js';
9
+ import '../prepare-BtjY4G3q.js';
10
10
 
11
11
  /**
12
12
  * @oeave/bakery3/catalog: render a catalog of products × finishes × cameras
@@ -1,6 +1,6 @@
1
- import { record, disposeTree } from '../chunk-WBIAFIHV.js';
1
+ import { record, disposeTree } from '../chunk-XK35ANPJ.js';
2
2
  import '../chunk-ZEBVAIJJ.js';
3
- import '../chunk-V3QINEEG.js';
3
+ import '../chunk-62M6XXNX.js';
4
4
  import { Bakery3Error } from '../chunk-3G5QL4F4.js';
5
5
 
6
6
  // src/catalog/index.ts
@@ -83,7 +83,7 @@ function validate(catalog, options) {
83
83
  }
84
84
  async function mountRoom(scene, room) {
85
85
  if (!room) return void 0;
86
- const { createPresetRoom, findPresetRooms } = await import('../room-S5TLCK4F.js');
86
+ const { createPresetRoom, findPresetRooms } = await import('../room-BM7Z7NKG.js');
87
87
  if (findPresetRooms(scene).length) return void 0;
88
88
  const group = createPresetRoom(
89
89
  room.preset,
@@ -1,6 +1,6 @@
1
- import { buildPatch, probeTargets, bakeCandidates, configureShadow } from './chunk-HQTUFVMM.js';
1
+ import { buildPatch, probeTargets, bakeCandidates, configureShadow } from './chunk-NEK5TBEH.js';
2
2
  import { presetBaseUrl } from './chunk-4E5VV4QY.js';
3
- import { prebakedRoomsUnder } from './chunk-W6WQ5UP7.js';
3
+ import { prebakedRoomsUnder, findPresetRooms, roomShownBaked } from './chunk-EN4ROBYQ.js';
4
4
  import { PRESETS_VERSION } from './chunk-6NYR73Y7.js';
5
5
  import { Bakery3Error } from './chunk-3G5QL4F4.js';
6
6
  import { LinearSRGBColorSpace, SRGBColorSpace, LinearFilter, ClampToEdgeWrapping, TextureLoader, EquirectangularReflectionMapping, NoColorSpace } from 'three';
@@ -223,7 +223,7 @@ function createBakeSession(options) {
223
223
  }
224
224
  let room;
225
225
  let roomFailed;
226
- const wantsRoom = generation.bundle.room;
226
+ const wantsRoom = findPresetRooms(scene).some(roomShownBaked) ? void 0 : generation.bundle.room;
227
227
  if (wantsRoom) {
228
228
  const base = `${(options.presetBaseUrl ?? presetBaseUrl()).replace(/\/$/, "")}/v${PRESETS_VERSION}/`;
229
229
  const url = new URL(wantsRoom.uri, base).toString();
@@ -547,5 +547,5 @@ function disposedError(what) {
547
547
  }
548
548
 
549
549
  export { LIVE, configureLightmap, createBakeSession };
550
- //# sourceMappingURL=chunk-TGFNQBKC.js.map
551
- //# sourceMappingURL=chunk-TGFNQBKC.js.map
550
+ //# sourceMappingURL=chunk-3T3FJOSD.js.map
551
+ //# sourceMappingURL=chunk-3T3FJOSD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bake/textures.ts","../src/bake/session.ts"],"names":["byUrl"],"mappings":"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","file":"chunk-3T3FJOSD.js","sourcesContent":["/**\n * A lightmap URI becomes a `THREE.Texture`, with the settings that make it\n * land the right way up on the right UV set.\n *\n * Orientation is a contract, not a guess: the render worker encodes the flip\n * at bake time, so the pixels and the UV values it ships are already correct\n * for `EXRLoader`'s defaults. This module changes nothing: `flipY = false` on\n * both the EXR and the PNG path, so an LDR fallback lands identically to the\n * HDR one.\n *\n * The bake's unwrap is a second UV set (your own `uv` still maps your\n * albedo). In three the second set is the `uv1` attribute, and\n * `texture.channel = 1` is how a map selects it, under WebGLRenderer and\n * WebGPURenderer alike.\n *\n * No mipmaps: a lightmap atlas is islands separated by a dilation margin, and\n * mipping it averages across island boundaries, which shows as light leaking\n * round the silhouette of every object at distance. Linear filtering with no\n * mips is the right trade for a map that is already low-frequency.\n */\n\nimport {\n ClampToEdgeWrapping,\n EquirectangularReflectionMapping,\n LinearFilter,\n LinearSRGBColorSpace,\n NoColorSpace,\n SRGBColorSpace,\n TextureLoader,\n type Texture,\n} from 'three';\nimport { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';\nimport { configureShadow } from './shadow.js';\nimport { Bakery3Error } from '../errors.js';\n\nexport type BakeTextureSource = {\n /** Already resolved against the bundle's own location. */\n url: string;\n format: 'exr' | 'png';\n /** For error messages: which object's lightmap this is. */\n objectId: string;\n size: number;\n /** What the texture is for. A lightmap (the default) is configured by\n * `configureLightmap`; the reflection probe by `configureProbe`. A factory\n * of your own may ignore this: the session applies the probe's mapping\n * itself either way. */\n role?: 'lightmap' | 'probe' | 'color' | 'normal' | 'billboard' | 'shadow';\n};\n\n/**\n * How a lightmap URI becomes a texture.\n *\n * Injectable for two reasons: a test wants a `DataTexture` and no\n * network, and an application that already has a loading manager, a CDN\n * rewrite or an auth header wants its own fetch in the loop.\n */\nexport type BakeTextureFactory = (\n source: BakeTextureSource,\n) => Promise<Texture>;\n\n/**\n * Apply the settings above to a texture from any source.\n *\n * Exported because a caller supplying their own `BakeTextureFactory` still\n * wants the channel, the color space and the filtering to be the ones the\n * bake was authored against: those are part of the format, not of the\n * loader.\n */\nexport function configureLightmap(\n texture: Texture,\n format: 'exr' | 'png',\n): Texture {\n texture.channel = 1;\n texture.flipY = false;\n // EXR is linear HDR irradiance and must not be decoded. A PNG lightmap is\n // the LDR fallback and is sRGB-encoded; three then decodes it to linear\n // before multiplying, which is what keeps the two formats interchangeable.\n texture.colorSpace = format === 'exr' ? LinearSRGBColorSpace : SRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The reflection probe as an environment map: three's equirect mapping, in\n * linear light, as the render worker wrote it (three's own equirect frame,\n * so no rotation). Everything else (the loader's flip, filtering, mips) is\n * left as `EXRLoader` sets it, which is what an HDRI loaded for\n * `scene.environment` gets.\n */\nexport function configureProbe(texture: Texture): Texture {\n texture.mapping = EquirectangularReflectionMapping;\n texture.colorSpace = LinearSRGBColorSpace;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * A stand-in's own maps (see proxies.ts and `BakedProxy`).\n *\n * `color` and `normal` are ordinary PNGs, the right way up for an ordinary\n * image loader, on the stand-in's first uv set; the color is sRGB and the\n * normals are data. They keep their mipmaps: a bookcase of spines shimmers\n * without them, and the unwrap's margin is what keeps a mip from reaching\n * across islands. `billboard` is linear radiance with alpha, left as\n * `EXRLoader` hands it over apart from the clamp.\n */\nexport function configureStandInMap(\n texture: Texture,\n role: 'color' | 'normal' | 'billboard',\n): Texture {\n texture.channel = 0;\n if (role === 'billboard') {\n texture.colorSpace = LinearSRGBColorSpace;\n texture.generateMipmaps = false;\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n } else {\n texture.flipY = true;\n texture.colorSpace = role === 'color' ? SRGBColorSpace : NoColorSpace;\n }\n texture.wrapS = ClampToEdgeWrapping;\n texture.wrapT = ClampToEdgeWrapping;\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * The default loader: `EXRLoader` for HDR, `TextureLoader` for the PNG\n * fallback.\n *\n * A failure here is a designed error naming the object and the URL, because\n * \"the bake applied to 11 of 12 objects\" is a question the developer must be\n * able to answer without opening the network tab.\n */\nexport function defaultTextureFactory(): BakeTextureFactory {\n const exr = new EXRLoader();\n const png = new TextureLoader();\n // Both loaders are asked for cross-origin data by default; a bundle served\n // from a CDN on another origin is the normal case, not the exception.\n exr.setCrossOrigin('anonymous');\n png.setCrossOrigin('anonymous');\n\n return async (source) => {\n const loader = source.format === 'exr' ? exr : png;\n const texture = await new Promise<Texture>((resolve, reject) => {\n loader.load(\n source.url,\n (loaded) => resolve(loaded as Texture),\n undefined,\n () =>\n reject(\n new Bakery3Error({\n code: 'InvalidRequest',\n message:\n source.role === 'probe'\n ? 'Could not load the reflection probe.'\n : source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ? `Could not load the ${source.role} map of \"${source.objectId}\".`\n : `Could not load the lightmap for \"${source.objectId}\".`,\n 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.`,\n fix: 'Pass { baseUrl } to addGeneration() if the bundle moved, and check the artifact server allows cross-origin reads.',\n }),\n ),\n );\n });\n if (source.role === 'probe') return configureProbe(texture);\n if (source.role === 'shadow') return configureShadow(texture);\n if (\n source.role === 'color' ||\n source.role === 'normal' ||\n source.role === 'billboard'\n ) {\n return configureStandInMap(texture, source.role);\n }\n return configureLightmap(texture, source.format);\n };\n}\n\n/**\n * A bundle uri, resolved against where the bundle came from.\n *\n * A uri is left alone when it already names its own origin (`https:`,\n * `data:`, `blob:`, `//host`): a hosted bundle carries signed URLs. `baseUrl`\n * is for a bundle saved to disk and served from somewhere else later.\n */\nexport function resolveBundleUri(uri: string, baseUrl?: string): string {\n if (/^[a-z][a-z0-9+.-]*:/i.test(uri) || uri.startsWith('//')) return uri;\n if (!baseUrl) return uri;\n try {\n return new URL(uri, baseUrl).toString();\n } catch {\n // A baseUrl that is not a URL is a caller mistake, but failing the whole\n // apply over it would be worse than trying the raw uri.\n return uri;\n }\n}\n","/**\n * A bake session: generations of lighting you can step through, over one\n * live scene.\n *\n * The session is the thing a panel binds to. It owns three pieces of state\n * and nothing else: which bundles it knows about, which one is currently\n * applied (`-1` means \"your scene, untouched\"), and whether the realtime\n * lights are muted. Everything visible follows from those.\n *\n * Generations do not stack: `apply(i)` reverts to live first, every time.\n * Applying generation 2 over generation 1 would leave generation 1's cloned\n * materials and rebuilt geometries in the scene under generation 2's\n * textures, and the second revert would restore the first bake rather than\n * your scene.\n *\n * Generations are evicted: twelve objects at 2048² of half-float RGBA is\n * around 400 MB of VRAM per generation, so only the applied generation and\n * the most recent few keep their textures. The rest are disposed and\n * reloaded on demand.\n */\n\nimport { findPresetRooms, roomShownBaked } from '../presets/roomState.js';\nimport type { Light, Object3D, Scene, Texture } from 'three';\nimport type { BakeBundle, BakedObject } from '../protocol/index.js';\nimport { Bakery3Error } from '../errors.js';\nimport { bakeCandidates, type BakeCandidate } from './candidates.js';\nimport { buildPatch, type BakeApplySkip, type BakePatch } from './apply.js';\nimport { probeTargets } from './probe.js';\nimport type { ProxyTextures } from './proxies.js';\nimport { configureShadow } from './shadow.js';\nimport { presetBaseUrl } from '../presets/baseUrl.js';\nimport { prebakedRoomsUnder } from '../presets/roomPrebake.js';\nimport { PRESETS_VERSION } from '../presets/catalog.gen.js';\nimport type { BakeShading } from './shading.js';\nimport {\n configureProbe,\n defaultTextureFactory,\n resolveBundleUri,\n type BakeTextureFactory,\n} from './textures.js';\n\n/** Your own scene, untouched: always a generation you can go back to. */\n/** No generation applied: your scene, untouched. */\nexport const LIVE = -1;\n\nexport type BakeGeneration = {\n /** Stable index into `session.generations`; generations are append-only. */\n index: number;\n /** What the stepper shows: `1024 · standard` unless the host names it. */\n label: string;\n bundle: BakeBundle;\n baseUrl?: string;\n /** When `addGeneration` was called, for \"2m ago\". */\n createdAt: number;\n /** True while this generation's textures are resident. */\n loaded: boolean;\n};\n\n/**\n * What one `apply()` actually managed to do.\n *\n * Reported rather than thrown, because a generation that no longer perfectly\n * matches the scene is the normal case the moment you edit anything, and\n * \"applied 10 of 12, here are the other two\" is more useful than either a\n * failure or a lie.\n */\nexport type BakeApplyReport = {\n /** The generation this report is about, or -1 for your scene untouched. */\n generation: number;\n /** objectIds whose lightmap landed. */\n applied: string[];\n /** Baked objects with nothing in the scene answering to their id. */\n unmatched: string[];\n /** Bakeable meshes in the scene this generation has no lightmap for. */\n unbaked: string[];\n /** Objects the apply refused, each with a reason and a fix. */\n skipped: BakeApplySkip[];\n /** objectIds that received the bake's reflection probe as `envMap`: the\n * meshes the bake did not light (the product, the glass beside it). */\n probed: string[];\n /** Stand-ins that went into the scene, by their place in the request. */\n standIns: number[];\n /** objectIds out of sight because a stand-in took their place. */\n replaced: string[];\n /** Whether the bake's shadow plane is in the scene. */\n shadow: boolean;\n /**\n * The prebaked preset room applied under this generation, and how many of\n * its surfaces found a mesh. A bake in `room: 'preset'` mode covers only\n * the product; this is where the rest of the light came from.\n */\n room?: { name: string; lighting: string; applied: number; unmatched: number };\n /** Why the prebaked room is not on: it was wanted and did not load. The\n * product's own lightmaps applied regardless. */\n roomError?: string;\n /** Why the bundle's probe is on nothing: it was wanted and did not load.\n * The lightmaps applied regardless: a probe costs the product its\n * reflections of the room and nothing else. */\n probeError?: string;\n};\n\nexport type BakeSessionOptions = {\n scene: Scene | Object3D;\n /**\n * Where the preset library lives, for a bundle that stands its objects in\n * a prebaked room (`BakeBundle.room`). Defaults to the CDN the SDK ships\n * with; a test points it somewhere else.\n */\n presetBaseUrl?: string;\n /**\n * How a lightmap uri becomes a texture. Defaults to EXRLoader/TextureLoader\n * with the channel, color space and filtering the format requires.\n * Injected by tests, and by applications that need their own fetch.\n */\n textureFactory?: BakeTextureFactory;\n /** `lightMapIntensity` to write. Default 1: the bake is already in the\n * scene's own light units. */\n intensity?: number;\n /**\n * How the lightmap meets the lights that keep running. `'replace'` (the\n * default) makes it the only diffuse lighting while lamps and the\n * environment still supply specular, the combination that matches the\n * traced still. `'add'` is three's stock behavior, for a bake that\n * deliberately holds only part of the light. See shading.ts.\n */\n shading?: BakeShading;\n /**\n * Put the bake's reflection probe on the objects it did not light, as\n * `envMap`, so a product kept live in a baked room reflects that room\n * rather than the scene's own environment. Default `true`; `false` leaves\n * every material's environment as you set it. See probe.ts.\n */\n probe?: boolean;\n /** How many generations keep their textures. Default 3. */\n residentGenerations?: number;\n};\n\nexport type BakeSession = {\n readonly generations: readonly BakeGeneration[];\n /** Index of the applied generation, or -1 when none is (see `revert()`). */\n readonly current: number;\n /** The last apply's report, for the panel's \"what didn't match\" line. */\n readonly lastReport: BakeApplyReport | null;\n /** True while `compare(true)` is showing the live scene under an applied\n * generation: the applied state is still there, just switched off. */\n readonly comparing: boolean;\n readonly lightsMuted: boolean;\n /** Whether an applied bake puts its reflection probe on the objects it did\n * not light. The `probe` option, until `setProbe` changes it. */\n readonly probe: boolean;\n\n /** Which meshes could be baked, and why the others could not. */\n candidates(): BakeCandidate[];\n\n /** Remember a bundle. Textures are not fetched until it is applied. */\n addGeneration(\n bundle: BakeBundle,\n options?: { baseUrl?: string; label?: string },\n ): number;\n\n /** Revert to live, then apply generation `index`. `revert()` goes back to live. */\n apply(index: number): Promise<BakeApplyReport>;\n /** Back to your scene, exactly. */\n revert(): void;\n /** Hold-to-compare: `true` shows live, `false` puts the bake back. Neither\n * loses the applied patch, so both are instant and lossless. */\n compare(showLive: boolean): void;\n /**\n * The reflection probe on or off. With a generation applied this re-applies\n * it, so the change shows at once and the report says which objects carry\n * the probe; turning it on for the first time fetches the file.\n */\n setProbe(on: boolean): Promise<BakeApplyReport>;\n /**\n * Realtime lights to zero and back. Under the default `'replace'` shading\n * the lamps only add specular, so this shows the bake's diffuse on its own;\n * under `'add'` it is what stops the lamps being counted twice.\n */\n muteLights(on: boolean): void;\n\n on(event: 'change', listener: (session: BakeSession) => void): () => void;\n /** Revert, drop every texture, restore the lights. */\n dispose(): void;\n};\n\ntype LoadedGeneration = {\n textures: Map<string, Texture>;\n /** objectId → why its lightmap did not load. One unreachable artifact\n * costs one object, not the whole apply. */\n failures: Map<string, string>;\n /** Stand-in index → its maps. One that did not load is in `failures`\n * under `simplify[n]` and simply does not go in. */\n proxies: Map<number, ProxyTextures>;\n /** The shadow plane's ratio map. */\n shadow?: Texture;\n /** The prebaked room's own bundle and textures, fetched once. */\n room?: {\n bundle: BakeBundle;\n baseUrl: string;\n textures: Map<string, Texture>;\n };\n roomFailed?: string;\n /** For LRU eviction. */\n usedAt: number;\n /** The bundle's reflection probe, as an equirect environment map. */\n probe?: Texture;\n /** It was asked for and did not load; not asked for again. The reason,\n * for the report. */\n probeFailed?: string;\n};\n\nexport function createBakeSession(options: BakeSessionOptions): BakeSession {\n const scene = options.scene;\n const intensity = options.intensity ?? 1;\n const shading: BakeShading = options.shading ?? 'replace';\n const resident = Math.max(1, options.residentGenerations ?? 3);\n let useProbe = options.probe ?? true;\n const loadTexture = options.textureFactory ?? defaultTextureFactory();\n\n const generations: BakeGeneration[] = [];\n const loaded = new Map<number, LoadedGeneration>();\n const listeners = new Set<(session: BakeSession) => void>();\n\n let current = LIVE;\n let patch: BakePatch | null = null;\n let lastReport: BakeApplyReport | null = null;\n let comparing = false;\n let muted: Array<{ light: Light; intensity: number }> | null = null;\n let disposed = false;\n /** Guards against two applies racing over one scene: the later one wins and\n * the earlier one drops its result rather than half-applying under it. */\n let applyToken = 0;\n let clock = 0;\n /** Preset rooms lit by their own library lightmaps that the applied\n * generation lights over, switched off until it is released. */\n let suspendedRooms: Array<{ resume(): void }> = [];\n\n function emit() {\n for (const listener of listeners) listener(session);\n }\n\n function releasePatch() {\n patch?.dispose();\n patch = null;\n comparing = false;\n // After the patch is gone, so the room's own lightmaps go back on over\n // the materials they were first put on (see presets/roomPrebake.ts).\n for (const room of suspendedRooms) room.resume();\n suspendedRooms = [];\n }\n\n function disposeGeneration(index: number) {\n const entry = loaded.get(index);\n if (!entry) return;\n // Unique textures only: an atlas is one Texture shared by every object.\n for (const texture of new Set(entry.textures.values())) texture.dispose();\n for (const texture of new Set(entry.room?.textures.values() ?? []))\n texture.dispose();\n for (const maps of entry.proxies.values()) {\n if (maps.kind === 'billboard') maps.map.dispose();\n else if (maps.kind === 'decimated') maps.light.dispose();\n else\n for (const texture of [maps.color, maps.normal, maps.light])\n texture.dispose();\n }\n entry.probe?.dispose();\n entry.shadow?.dispose();\n loaded.delete(index);\n const generation = generations[index];\n if (generation) generation.loaded = false;\n }\n\n function evict(keep: number) {\n if (loaded.size <= resident) return;\n const ranked = [...loaded.entries()]\n .filter(([index]) => index !== keep)\n .sort((a, b) => a[1].usedAt - b[1].usedAt);\n while (loaded.size > resident && ranked.length) {\n disposeGeneration(ranked.shift()![0]);\n }\n }\n\n async function ensureLoaded(index: number): Promise<LoadedGeneration> {\n const existing = loaded.get(index);\n if (existing) {\n existing.usedAt = ++clock;\n return existing;\n }\n const generation = generations[index]!;\n const textures = new Map<string, Texture>();\n const failures = new Map<string, string>();\n // One texture per file: an atlas bundle names the same lightmap on every\n // object, and it must be fetched and decoded once and bound once, which\n // is the reason an atlas exists.\n const byUrl = new Map<string, Texture>();\n // Sequential rather than parallel: a twelve-object bundle at 2048² is a\n // lot of megabytes, and a browser that opens twelve HDR decodes at once\n // janks the frame you are watching.\n for (const baked of generation.bundle.objects) {\n try {\n const url = resolveBundleUri(baked.lightmap.uri, generation.baseUrl);\n let texture = byUrl.get(url);\n if (!texture) {\n texture = await loadTexture({\n url,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(url, texture);\n }\n textures.set(baked.objectId, texture);\n } catch (error) {\n // One unreachable artifact must not cost the other eleven objects\n // their lighting: it becomes a per-object skip with the reason\n // instead.\n failures.set(baked.objectId, describe(error));\n }\n }\n const proxies = new Map<number, ProxyTextures>();\n for (const proxy of generation.bundle.proxies ?? []) {\n const label = proxy.name ?? `stand-in ${proxy.index}`;\n const load = (\n uri: string,\n format: 'exr' | 'png',\n role: 'color' | 'normal' | 'billboard' | 'lightmap',\n size: number,\n ) =>\n loadTexture({\n url: resolveBundleUri(uri, generation.baseUrl),\n format,\n objectId: label,\n size,\n role,\n });\n try {\n if (proxy.kind === 'billboard') {\n proxies.set(proxy.index, {\n kind: 'billboard',\n map: await load(proxy.map.uri, 'exr', 'billboard', proxy.map.width),\n });\n } else if (proxy.kind === 'decimated') {\n proxies.set(proxy.index, {\n kind: 'decimated',\n light: await load(\n proxy.lightmap.uri,\n 'exr',\n 'lightmap',\n proxy.lightmap.size,\n ),\n });\n } else {\n const size = proxy.lightmap.size;\n proxies.set(proxy.index, {\n kind: 'mesh',\n color: await load(proxy.color.uri, 'png', 'color', size),\n normal: await load(proxy.normal.uri, 'png', 'normal', size),\n light: await load(proxy.lightmap.uri, 'exr', 'lightmap', size),\n });\n }\n } catch (error) {\n failures.set(`simplify[${proxy.index}]`, describe(error));\n }\n }\n let shadow: Texture | undefined;\n if (generation.bundle.shadow) {\n const shadowEntry = generation.bundle.shadow;\n try {\n shadow = configureShadow(\n await loadTexture({\n url: resolveBundleUri(shadowEntry.uri, generation.baseUrl),\n format: shadowEntry.format,\n objectId: 'shadow',\n size: shadowEntry.size,\n role: 'shadow',\n }),\n );\n } catch (error) {\n // A missing shadow costs the product its contact with the floor and\n // nothing else, so it is a note on the report, not a failed apply.\n failures.set('shadow', describe(error));\n }\n }\n // The prebaked room, when the bundle stands its objects in one. One\n // fetch for a library asset every page that shows this room shares, and\n // the reason a bundle of three objects can light a whole room.\n let room: LoadedGeneration['room'];\n let roomFailed: string | undefined;\n // A room the page shows BAKED is lit already: its own file carries the\n // light the library's lightmaps would bring, so there is nothing to fetch.\n const wantsRoom = findPresetRooms(scene).some(roomShownBaked)\n ? undefined\n : generation.bundle.room;\n if (wantsRoom) {\n const base = `${(options.presetBaseUrl ?? presetBaseUrl()).replace(/\\/$/, '')}/v${PRESETS_VERSION}/`;\n const url = new URL(wantsRoom.uri, base).toString();\n try {\n const response = await fetch(url);\n if (!response.ok)\n throw new Error(`${response.status} ${response.statusText}`);\n const bundle = (await response.json()) as BakeBundle;\n const roomTextures = new Map<string, Texture>();\n const byUrl = new Map<string, Texture>();\n for (const baked of bundle.objects) {\n const textureUrl = resolveBundleUri(baked.lightmap.uri, url);\n let texture = byUrl.get(textureUrl);\n if (!texture) {\n texture = await loadTexture({\n url: textureUrl,\n format: baked.lightmap.format,\n objectId: baked.objectId,\n size: baked.lightmap.size,\n });\n byUrl.set(textureUrl, texture);\n }\n roomTextures.set(baked.objectId, texture);\n }\n room = { bundle, baseUrl: url, textures: roomTextures };\n } catch (error) {\n // The product's own lightmaps still apply. What is lost is the room\n // around them, which is worth saying and not worth failing over.\n roomFailed = describe(error);\n }\n }\n\n const entry: LoadedGeneration = {\n textures,\n failures,\n proxies,\n usedAt: ++clock,\n ...(shadow ? { shadow } : {}),\n ...(room ? { room } : {}),\n ...(roomFailed ? { roomFailed } : {}),\n };\n loaded.set(index, entry);\n generation.loaded = true;\n return entry;\n }\n\n /**\n * The reflection probe, fetched the first time it is wanted, so a session\n * created with `probe: false` never downloads it, and one that turns it on\n * later (`setProbe`) gets it then. A probe that does not load costs the\n * product its reflections of the room and nothing else, so the failure is\n * remembered and the apply goes on without it.\n */\n async function ensureProbe(\n index: number,\n entry: LoadedGeneration,\n ): Promise<Texture | undefined> {\n if (entry.probe || entry.probeFailed) return entry.probe;\n const generation = generations[index]!;\n const probeEntry = generation.bundle.probe;\n if (!probeEntry) return undefined;\n try {\n entry.probe = configureProbe(\n await loadTexture({\n url: resolveBundleUri(probeEntry.uri, generation.baseUrl),\n format: probeEntry.format,\n objectId: 'probe',\n size: probeEntry.width,\n role: 'probe',\n }),\n );\n } catch (error) {\n entry.probeFailed = describe(error);\n }\n return entry.probe;\n }\n\n const session: BakeSession = {\n get generations() {\n return generations;\n },\n get current() {\n return current;\n },\n get lastReport() {\n return lastReport;\n },\n get comparing() {\n return comparing;\n },\n get lightsMuted() {\n return muted !== null;\n },\n get probe() {\n return useProbe;\n },\n\n candidates() {\n return bakeCandidates({ scene });\n },\n\n addGeneration(bundle, addOptions = {}) {\n if (disposed) throw disposedError('addGeneration');\n const index = generations.length;\n generations.push({\n index,\n label:\n addOptions.label ??\n `${bundle.settings.textureSize} · ${bundle.settings.quality}`,\n bundle,\n ...(addOptions.baseUrl !== undefined\n ? { baseUrl: addOptions.baseUrl }\n : {}),\n createdAt: Date.now(),\n loaded: false,\n });\n emit();\n return index;\n },\n\n async apply(index) {\n if (disposed) throw disposedError('apply');\n if (index === LIVE) {\n session.revert();\n return lastReport!;\n }\n const generation = generations[index];\n if (!generation) {\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `There is no bake generation ${index}.`,\n why: `This session has ${generations.length} generation(s).`,\n fix: 'Call addGeneration(bundle) with a BakeBundle first, or revert() to go back to live.',\n });\n }\n\n const token = ++applyToken;\n const entry = await ensureLoaded(index);\n const probe = useProbe ? await ensureProbe(index, entry) : undefined;\n if (token !== applyToken || disposed)\n return lastReport ?? emptyReport(index);\n\n // Always revert first. See the file header.\n releasePatch();\n\n const objects: Array<{\n baked: (typeof generation.bundle.objects)[number];\n texture: Texture;\n }> = [];\n const missingTextures: BakeApplySkip[] = [];\n for (const baked of generation.bundle.objects) {\n const texture = entry.textures.get(baked.objectId);\n if (!texture) {\n missingTextures.push({\n objectId: baked.objectId,\n ...(baked.name ? { name: baked.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The lightmap for \"${baked.name ?? baked.objectId}\" did not load.`,\n why:\n entry.failures.get(baked.objectId) ??\n 'Its texture is missing from this generation, so there is nothing to apply.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again.',\n });\n continue;\n }\n objects.push({ baked, texture });\n }\n\n // The prebaked room's objects are baked too, just not by this bake.\n const roomObjects = (entry.room?.bundle.objects ?? []).flatMap(\n (baked) => {\n const texture = entry.room!.textures.get(baked.objectId);\n return texture ? [{ baked, texture }] : [];\n },\n );\n const litIds = new Set(\n generation.bundle.objects.map((object) => object.objectId),\n );\n for (const { baked } of roomObjects) litIds.add(baked.objectId);\n const standIns = (generation.bundle.proxies ?? []).flatMap((proxy) => {\n const textures = entry.proxies.get(proxy.index);\n if (textures) return [{ proxy, textures }];\n missingTextures.push({\n objectId: `simplify[${proxy.index}]`,\n ...(proxy.name ? { name: proxy.name } : {}),\n code: 'BakeLightmapUnavailable',\n message: `The maps for the stand-in \"${proxy.name ?? proxy.index}\" did not load.`,\n why:\n entry.failures.get(`simplify[${proxy.index}]`) ??\n 'One of its textures is missing from this generation.',\n fix: 'Check the bundle uris are reachable from the browser, then apply again. The objects it replaces are left as they were.',\n });\n return [];\n });\n // What a stand-in replaces is out of sight: it is neither unbaked nor\n // something to put the reflection probe on.\n for (const { proxy } of standIns)\n for (const id of proxy.replaces) litIds.add(id);\n // One entry per object. The room's lightmaps go in first and this\n // bake's overwrite them, because a stand the product sits on is in\n // both and only one of the two was traced with the product on it.\n // Applying an id twice would also make revert restore the wrong state:\n // the second touch records the first's edit as the value to put back.\n const byObjectId = new Map<\n string,\n { baked: BakedObject; texture: Texture }\n >();\n for (const entry_ of [...roomObjects, ...objects])\n byObjectId.set(entry_.baked.objectId, entry_);\n const winners = [...byObjectId.values()];\n\n // A preset room already lit by its own library lightmaps: when this\n // generation lights any of its objects, that patch comes off first, so\n // this one records the room's own materials as the thing to restore.\n // The room's session is scoped to its group, which is how it tells\n // itself apart from a session over the whole scene.\n const touched = new Set([\n ...byObjectId.keys(),\n ...standIns.flatMap(({ proxy }) => proxy.replaces),\n ]);\n for (const { group, handle } of prebakedRoomsUnder(scene)) {\n if (group === scene) continue;\n let lightsIt = false;\n group.traverse((node) => {\n if (touched.has(node.userData.bakery3Id as string)) lightsIt = true;\n });\n if (!lightsIt) continue;\n handle.suspend();\n suspendedRooms.push(handle);\n }\n\n const built = buildPatch({\n scene,\n objects: winners,\n intensity,\n shading,\n ...(probe\n ? {\n probe: {\n texture: probe,\n meshes: probeTargets(session.candidates(), litIds),\n },\n }\n : {}),\n ...(standIns.length ? { proxies: standIns } : {}),\n ...(generation.bundle.shadow && entry.shadow\n ? {\n shadow: {\n shadow: generation.bundle.shadow,\n texture: entry.shadow,\n },\n }\n : {}),\n });\n built.patch.on();\n patch = built.patch;\n current = index;\n\n const bakedIds = new Set(litIds);\n for (const skip of generation.bundle.skipped) bakedIds.add(skip.objectId);\n const unbaked = session\n .candidates()\n .filter(\n (candidate) =>\n candidate.bakeable &&\n candidate.defaultInclude &&\n !bakedIds.has(candidate.objectId),\n )\n .map((candidate) => candidate.objectId);\n\n lastReport = {\n generation: index,\n applied: built.applied,\n unmatched: built.unmatched,\n unbaked,\n skipped: [...missingTextures, ...built.skipped],\n probed: built.probed,\n standIns: built.standIns,\n replaced: built.replaced,\n shadow: built.shadow,\n ...(entry.room\n ? {\n room: {\n name: generation.bundle.room!.name,\n lighting: generation.bundle.room!.lighting,\n applied: roomObjects.filter(({ baked }) =>\n built.applied.includes(baked.objectId),\n ).length,\n unmatched: roomObjects.filter(({ baked }) =>\n built.unmatched.includes(baked.objectId),\n ).length,\n },\n }\n : {}),\n ...(entry.roomFailed ? { roomError: entry.roomFailed } : {}),\n ...(useProbe && entry.probeFailed\n ? { probeError: entry.probeFailed }\n : {}),\n };\n evict(index);\n emit();\n return lastReport;\n },\n\n revert() {\n releasePatch();\n current = LIVE;\n lastReport = emptyReport(LIVE);\n emit();\n },\n\n compare(showLive) {\n if (!patch) return;\n if (showLive) patch.off();\n else patch.on();\n comparing = showLive;\n emit();\n },\n\n async setProbe(on) {\n if (disposed) throw disposedError('setProbe');\n if (on === useProbe) return lastReport ?? emptyReport(current);\n useProbe = on;\n // The probe is part of the applied patch, so changing it is an apply:\n // revert, then the same generation with or without it.\n if (current === LIVE) {\n emit();\n return lastReport ?? emptyReport(LIVE);\n }\n return session.apply(current);\n },\n\n muteLights(on) {\n if (on === (muted !== null)) return;\n if (on) {\n const touched: Array<{ light: Light; intensity: number }> = [];\n scene.traverse((object) => {\n const light = object as Light;\n if (!light.isLight) return;\n touched.push({ light, intensity: light.intensity });\n light.intensity = 0;\n });\n muted = touched;\n } else {\n for (const entry of muted!) entry.light.intensity = entry.intensity;\n muted = null;\n }\n emit();\n },\n\n on(_event, listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n dispose() {\n if (disposed) return;\n disposed = true;\n releasePatch();\n if (muted) {\n for (const entry of muted) entry.light.intensity = entry.intensity;\n muted = null;\n }\n for (const index of [...loaded.keys()]) disposeGeneration(index);\n current = LIVE;\n listeners.clear();\n },\n };\n\n return session;\n}\n\nfunction emptyReport(generation: number): BakeApplyReport {\n return {\n generation,\n applied: [],\n unmatched: [],\n unbaked: [],\n skipped: [],\n probed: [],\n standIns: [],\n replaced: [],\n shadow: false,\n };\n}\n\n/** The designed failure shape when there is one, the message otherwise. */\nfunction describe(error: unknown): string {\n if (error && typeof error === 'object' && 'toDisplayString' in error) {\n return (error as { toDisplayString(): string }).toDisplayString();\n }\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction disposedError(what: string): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message: `${what}() was called on a disposed bake session.`,\n why: 'dispose() reverts the scene and drops every texture, so there is nothing left to apply.',\n fix: 'Create a new session with createBakeSession({ scene }).',\n });\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { Bakery3Error } from './chunk-3G5QL4F4.js';
2
2
 
3
3
  // src/capture/camera.ts
4
+ var FOCUS_DOCS = "https://bakery3.com/docs/cameras#depth-of-field";
4
5
  function captureCamera(camera) {
5
6
  camera.updateMatrixWorld();
6
7
  const position = [0, 0, 0];
@@ -25,7 +26,8 @@ function captureCamera(camera) {
25
26
  zoom: anyCamera.zoom,
26
27
  position,
27
28
  quaternion,
28
- ...camera.name ? { name: camera.name } : {}
29
+ ...camera.name ? { name: camera.name } : {},
30
+ ...focusOf(camera, position)
29
31
  };
30
32
  }
31
33
  if (anyCamera.isOrthographicCamera) {
@@ -51,6 +53,59 @@ function captureCamera(camera) {
51
53
  docs: "https://bakery3.com/docs/cameras"
52
54
  });
53
55
  }
56
+ function focusOf(camera, position) {
57
+ const mark = camera.userData?.bakery3?.focus;
58
+ if (mark === void 0 || mark === null || mark === false) return {};
59
+ const focus = mark;
60
+ const fStop = focus.fStop;
61
+ if (typeof fStop !== "number" || !Number.isFinite(fStop) || fStop <= 0) {
62
+ throw focusError(
63
+ `camera.userData.bakery3.focus.fStop must be a positive number, got ${String(fStop)}.`,
64
+ "The f-number decides how much is blurred; without one there is no depth of field to render."
65
+ );
66
+ }
67
+ if (focus.target !== void 0) {
68
+ const t = focus.target;
69
+ const target = Array.isArray(t) ? [t[0], t[1], t[2]] : [
70
+ t.x,
71
+ t.y,
72
+ t.z
73
+ ];
74
+ if (!target.every((v) => typeof v === "number" && Number.isFinite(v))) {
75
+ throw focusError(
76
+ "camera.userData.bakery3.focus.target must be a point: [x, y, z] or a Vector3.",
77
+ "The target is the world point the render keeps sharp."
78
+ );
79
+ }
80
+ const e = camera.matrixWorld.elements;
81
+ const length = Math.hypot(e[8], e[9], e[10]) || 1;
82
+ const depth = -((target[0] - position[0]) * e[8] + (target[1] - position[1]) * e[9] + (target[2] - position[2]) * e[10]) / length;
83
+ if (!(depth > 0)) {
84
+ throw focusError(
85
+ "The focus target is behind the camera.",
86
+ "A lens can only focus on what is in front of it."
87
+ );
88
+ }
89
+ return { focus: { fStop, focalDistance: depth, target } };
90
+ }
91
+ const distance = focus.distance;
92
+ if (typeof distance !== "number" || !Number.isFinite(distance) || distance <= 0) {
93
+ throw focusError(
94
+ "camera.userData.bakery3.focus needs a target or a distance.",
95
+ "The render has to know where the sharp plane is: a world point to keep sharp, or a distance in metres from the camera."
96
+ );
97
+ }
98
+ return { focus: { fStop, focalDistance: distance } };
99
+ }
100
+ function focusError(message, why) {
101
+ return new Bakery3Error({
102
+ code: "InvalidRequest",
103
+ message,
104
+ why,
105
+ fix: "Set camera.userData.bakery3 = { focus: { fStop: 2.8, target: product.position } }, or remove the focus mark for a picture sharp throughout.",
106
+ docs: FOCUS_DOCS
107
+ });
108
+ }
54
109
  function worldQuaternion(object) {
55
110
  const e = object.matrixWorld.elements;
56
111
  const sx = Math.hypot(e[0], e[1], e[2]) || 1;
@@ -83,5 +138,5 @@ function worldQuaternion(object) {
83
138
  }
84
139
 
85
140
  export { captureCamera };
86
- //# sourceMappingURL=chunk-V3QINEEG.js.map
87
- //# sourceMappingURL=chunk-V3QINEEG.js.map
141
+ //# sourceMappingURL=chunk-62M6XXNX.js.map
142
+ //# sourceMappingURL=chunk-62M6XXNX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/capture/camera.ts"],"names":["s"],"mappings":"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","file":"chunk-62M6XXNX.js","sourcesContent":["/**\n * The active camera, in full.\n *\n * It is written out as data rather than referenced into the GLB by name\n * because the live camera is often not in the graph the exporter walks: R3F\n * holds the default camera outside the scene, drei's controls swap it, and a\n * configurator often animates a camera that was never added as a child of\n * anything.\n */\n\nimport type { Camera, OrthographicCamera, PerspectiveCamera } from 'three';\nimport type { CameraSpec, Quat, Vec3 } from '../protocol/index.js';\nimport { Bakery3Error } from '../errors.js';\n\n/**\n * Depth of field, marked on a perspective camera as\n * `camera.userData.bakery3 = { focus: { fStop: 2.8, target: [0, 0.4, 0] } }`.\n *\n * three has no aperture: its depth of field is a post-processing pass, so the\n * render cannot read it off the camera and the developer says it here.\n * `fStop` is a full-frame camera's f-number at the camera's own `fov`, so a\n * smaller number blurs more. `target` is the world point that stays sharp\n * and the render keeps it sharp through a clip as the camera moves;\n * `distance` is a fixed focus distance in metres instead. One of the two.\n */\nexport type CameraFocus = {\n fStop: number;\n target?: Vec3 | { x: number; y: number; z: number };\n distance?: number;\n};\n\nconst FOCUS_DOCS = 'https://bakery3.com/docs/cameras#depth-of-field';\n\nexport function captureCamera(camera: Camera): CameraSpec {\n // World, not local. A camera parented to a rig (an orbit pivot, a\n // turntable, a vehicle) has a local transform that means nothing on its\n // own, and that is exactly the case a configurator is in.\n camera.updateMatrixWorld();\n const position: Vec3 = [0, 0, 0];\n const quaternion: Quat = [0, 0, 0, 1];\n const elements = camera.matrixWorld.elements;\n position[0] = elements[12]!;\n position[1] = elements[13]!;\n position[2] = elements[14]!;\n const q = worldQuaternion(camera);\n quaternion[0] = q[0];\n quaternion[1] = q[1];\n quaternion[2] = q[2];\n quaternion[3] = q[3];\n\n const anyCamera = camera as PerspectiveCamera & OrthographicCamera;\n\n if (anyCamera.isPerspectiveCamera) {\n return {\n type: 'perspective',\n fov: anyCamera.fov,\n aspect: anyCamera.aspect,\n near: anyCamera.near,\n far: anyCamera.far,\n zoom: anyCamera.zoom,\n position,\n quaternion,\n ...(camera.name ? { name: camera.name } : {}),\n ...focusOf(camera, position),\n };\n }\n\n if (anyCamera.isOrthographicCamera) {\n return {\n type: 'orthographic',\n left: anyCamera.left,\n right: anyCamera.right,\n top: anyCamera.top,\n bottom: anyCamera.bottom,\n near: anyCamera.near,\n far: anyCamera.far,\n zoom: anyCamera.zoom,\n position,\n quaternion,\n ...(camera.name ? { name: camera.name } : {}),\n };\n }\n\n throw new Bakery3Error({\n code: 'InvalidRequest',\n message: `Unsupported camera type: ${camera.type}`,\n why: 'The renderer draws a pinhole or an orthographic projection. An array, cube or stereo camera has no single frustum to reproduce.',\n fix: 'Pass one PerspectiveCamera or OrthographicCamera to render().',\n docs: 'https://bakery3.com/docs/cameras',\n });\n}\n\n/**\n * The camera's focus mark as the manifest carries it. A target is sent as\n * the point and as its depth from the camera now: the depth is the focus of a\n * still, and the point is what a clip's focus follows.\n */\nfunction focusOf(\n camera: Camera,\n position: Vec3,\n): {\n focus?: NonNullable<Extract<CameraSpec, { type: 'perspective' }>['focus']>;\n} {\n const mark = (camera.userData?.bakery3 as { focus?: unknown } | undefined)\n ?.focus;\n if (mark === undefined || mark === null || mark === false) return {};\n const focus = mark as Partial<CameraFocus>;\n const fStop = focus.fStop;\n if (typeof fStop !== 'number' || !Number.isFinite(fStop) || fStop <= 0) {\n throw focusError(\n `camera.userData.bakery3.focus.fStop must be a positive number, got ${String(fStop)}.`,\n 'The f-number decides how much is blurred; without one there is no depth of field to render.',\n );\n }\n if (focus.target !== undefined) {\n const t = focus.target;\n const target: Vec3 = Array.isArray(t)\n ? [t[0], t[1], t[2]]\n : [\n (t as { x: number }).x,\n (t as { y: number }).y,\n (t as { z: number }).z,\n ];\n if (!target.every((v) => typeof v === 'number' && Number.isFinite(v))) {\n throw focusError(\n 'camera.userData.bakery3.focus.target must be a point: [x, y, z] or a Vector3.',\n 'The target is the world point the render keeps sharp.',\n );\n }\n // Depth along the view axis, which is what a lens focuses at: the\n // camera looks down its local -z, the third column of its world matrix.\n const e = camera.matrixWorld.elements;\n const length = Math.hypot(e[8]!, e[9]!, e[10]!) || 1;\n const depth =\n -(\n (target[0] - position[0]) * e[8]! +\n (target[1] - position[1]) * e[9]! +\n (target[2] - position[2]) * e[10]!\n ) / length;\n if (!(depth > 0)) {\n throw focusError(\n 'The focus target is behind the camera.',\n 'A lens can only focus on what is in front of it.',\n );\n }\n return { focus: { fStop, focalDistance: depth, target } };\n }\n const distance = focus.distance;\n if (\n typeof distance !== 'number' ||\n !Number.isFinite(distance) ||\n distance <= 0\n ) {\n throw focusError(\n 'camera.userData.bakery3.focus needs a target or a distance.',\n 'The render has to know where the sharp plane is: a world point to keep sharp, or a distance in metres from the camera.',\n );\n }\n return { focus: { fStop, focalDistance: distance } };\n}\n\nfunction focusError(message: string, why: string): Bakery3Error {\n return new Bakery3Error({\n code: 'InvalidRequest',\n message,\n why,\n fix: 'Set camera.userData.bakery3 = { focus: { fStop: 2.8, target: product.position } }, or remove the focus mark for a picture sharp throughout.',\n docs: FOCUS_DOCS,\n });\n}\n\n/**\n * The world-space rotation, decomposed by hand.\n *\n * `getWorldQuaternion` would allocate a `Quaternion` and pull three's class\n * into this module's import graph for one value; the matrix is already\n * up to date and the extraction is nine multiplies.\n */\nfunction worldQuaternion(object: Camera): Quat {\n const e = object.matrixWorld.elements;\n // Strip scale, or a camera under a scaled rig reads as a rotation it is not.\n const sx = Math.hypot(e[0]!, e[1]!, e[2]!) || 1;\n const sy = Math.hypot(e[4]!, e[5]!, e[6]!) || 1;\n const sz = Math.hypot(e[8]!, e[9]!, e[10]!) || 1;\n const m00 = e[0]! / sx;\n const m01 = e[4]! / sy;\n const m02 = e[8]! / sz;\n const m10 = e[1]! / sx;\n const m11 = e[5]! / sy;\n const m12 = e[9]! / sz;\n const m20 = e[2]! / sx;\n const m21 = e[6]! / sy;\n const m22 = e[10]! / sz;\n\n const trace = m00 + m11 + m22;\n if (trace > 0) {\n const s = 0.5 / Math.sqrt(trace + 1);\n return [(m21 - m12) * s, (m02 - m20) * s, (m10 - m01) * s, 0.25 / s];\n }\n if (m00 > m11 && m00 > m22) {\n const s = 2 * Math.sqrt(1 + m00 - m11 - m22);\n return [0.25 * s, (m01 + m10) / s, (m02 + m20) / s, (m21 - m12) / s];\n }\n if (m11 > m22) {\n const s = 2 * Math.sqrt(1 + m11 - m00 - m22);\n return [(m01 + m10) / s, 0.25 * s, (m12 + m21) / s, (m02 - m20) / s];\n }\n const s = 2 * Math.sqrt(1 + m22 - m00 - m11);\n return [(m02 + m20) / s, (m12 + m21) / s, 0.25 * s, (m10 - m01) / s];\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { record, defaultVariantId } from './chunk-WBIAFIHV.js';
2
- import { Bakery3Client, Batch, quoteKey, sampleOf, testSettings, PollFailures } from './chunk-25ZXSVQ3.js';
1
+ import { record, defaultVariantId } from './chunk-XK35ANPJ.js';
2
+ import { Bakery3Client, Batch, quoteKey, sampleOf, testSettings, PollFailures } from './chunk-X6GW43EX.js';
3
3
  import { RenderSet } from './chunk-ZEBVAIJJ.js';
4
- import { captureScene, bindTimelineContext, createTimeline, prepareBake, bakeQuoteOf, quoteBake, analyzeScene, resolveOutput, sceneComplexity, tracedTriangles } from './chunk-CX4WTVGH.js';
5
- import { SDK_VERSION, protocolVersionFor } from './chunk-APBOWWSV.js';
6
- import { findPresetRooms } from './chunk-AF5BIELI.js';
7
- import { shouldExclude, idOf, captureFog } from './chunk-HQTUFVMM.js';
4
+ import { captureScene, bindTimelineContext, createTimeline, prepareBake, bakeQuoteOf, quoteBake, analyzeScene, resolveOutput, sceneComplexity, tracedTriangles } from './chunk-WLEFNUOH.js';
5
+ import { SDK_VERSION, protocolVersionFor } from './chunk-R5IUPOWI.js';
6
+ import { shouldExclude, idOf, captureFog } from './chunk-NEK5TBEH.js';
7
+ import { findPresetRooms } from './chunk-EN4ROBYQ.js';
8
8
  import { Bakery3Error, RenderBudgetExceeded } from './chunk-3G5QL4F4.js';
9
9
 
10
10
  // src/protocol/job.ts
@@ -1153,5 +1153,5 @@ function inBrowser() {
1153
1153
  }
1154
1154
 
1155
1155
  export { BakeJob, RenderJob, createBakery3 };
1156
- //# sourceMappingURL=chunk-ARMTTZXZ.js.map
1157
- //# sourceMappingURL=chunk-ARMTTZXZ.js.map
1156
+ //# sourceMappingURL=chunk-6FAMQZXB.js.map
1157
+ //# sourceMappingURL=chunk-6FAMQZXB.js.map