@pascal-app/viewer 1.0.3 → 1.0.4

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 (164) hide show
  1. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  2. package/dist/components/renderers/node-renderer.js +8 -3
  3. package/dist/components/viewer/frame-limiter.d.ts +1 -0
  4. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  5. package/dist/components/viewer/frame-limiter.js +22 -3
  6. package/dist/components/viewer/glb-interactive.d.ts +25 -1
  7. package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
  8. package/dist/components/viewer/glb-interactive.js +252 -85
  9. package/dist/components/viewer/glb-mechanisms.d.ts +10 -0
  10. package/dist/components/viewer/glb-mechanisms.d.ts.map +1 -0
  11. package/dist/components/viewer/glb-mechanisms.js +19 -0
  12. package/dist/components/viewer/glb-scene.d.ts +45 -27
  13. package/dist/components/viewer/glb-scene.d.ts.map +1 -1
  14. package/dist/components/viewer/glb-scene.js +420 -506
  15. package/dist/components/viewer/glb-walkthrough-controller.d.ts +1 -1
  16. package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
  17. package/dist/components/viewer/glb-walkthrough-controller.js +12 -1
  18. package/dist/components/viewer/index.d.ts +14 -0
  19. package/dist/components/viewer/index.d.ts.map +1 -1
  20. package/dist/components/viewer/index.js +84 -26
  21. package/dist/components/viewer/lights.d.ts.map +1 -1
  22. package/dist/components/viewer/lights.js +6 -1
  23. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  24. package/dist/components/viewer/perf-monitor.js +6 -0
  25. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  26. package/dist/components/viewer/post-processing.js +8 -3
  27. package/dist/components/viewer/registered-systems.d.ts.map +1 -1
  28. package/dist/components/viewer/registered-systems.js +16 -2
  29. package/dist/components/viewer/render-error.d.ts +18 -0
  30. package/dist/components/viewer/render-error.d.ts.map +1 -0
  31. package/dist/components/viewer/render-error.js +29 -0
  32. package/dist/components/viewer/scene-ground-replacement.d.ts +6 -0
  33. package/dist/components/viewer/scene-ground-replacement.d.ts.map +1 -1
  34. package/dist/components/viewer/scene-ground-replacement.js +15 -0
  35. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  36. package/dist/components/viewer/selection-manager.js +10 -0
  37. package/dist/components/viewer/viewer-camera.d.ts +4 -0
  38. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  39. package/dist/components/viewer/viewer-camera.js +11 -1
  40. package/dist/index.d.ts +22 -11
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +20 -14
  43. package/dist/lib/asset-url.d.ts.map +1 -1
  44. package/dist/lib/asset-url.js +7 -1
  45. package/dist/lib/display-state.d.ts +25 -0
  46. package/dist/lib/display-state.d.ts.map +1 -0
  47. package/dist/lib/display-state.js +1 -0
  48. package/dist/lib/hero-pose.d.ts +12 -2
  49. package/dist/lib/hero-pose.d.ts.map +1 -1
  50. package/dist/lib/hero-pose.js +72 -5
  51. package/dist/lib/ink-edges.d.ts +4 -2
  52. package/dist/lib/ink-edges.d.ts.map +1 -1
  53. package/dist/lib/ink-edges.js +17 -7
  54. package/dist/lib/key-light-override.d.ts +11 -0
  55. package/dist/lib/key-light-override.d.ts.map +1 -0
  56. package/dist/lib/key-light-override.js +14 -0
  57. package/dist/lib/live-frame-hold.d.ts +14 -0
  58. package/dist/lib/live-frame-hold.d.ts.map +1 -0
  59. package/dist/lib/live-frame-hold.js +28 -0
  60. package/dist/lib/materials.d.ts +14 -7
  61. package/dist/lib/materials.d.ts.map +1 -1
  62. package/dist/lib/materials.js +31 -5
  63. package/dist/lib/node-top-surface-height.d.ts +6 -0
  64. package/dist/lib/node-top-surface-height.d.ts.map +1 -0
  65. package/dist/lib/node-top-surface-height.js +74 -0
  66. package/dist/lib/perf-probe-state.d.ts +39 -0
  67. package/dist/lib/perf-probe-state.d.ts.map +1 -0
  68. package/dist/lib/perf-probe-state.js +17 -0
  69. package/dist/lib/pointer-events.d.ts +8 -0
  70. package/dist/lib/pointer-events.d.ts.map +1 -1
  71. package/dist/lib/pointer-events.js +27 -4
  72. package/dist/lib/procedural-emission.d.ts +7 -0
  73. package/dist/lib/procedural-emission.d.ts.map +1 -0
  74. package/dist/lib/procedural-emission.js +54 -0
  75. package/dist/lib/scene-support-height.d.ts +4 -0
  76. package/dist/lib/scene-support-height.d.ts.map +1 -0
  77. package/dist/lib/scene-support-height.js +34 -0
  78. package/dist/lib/scene-visibility.d.ts +6 -0
  79. package/dist/lib/scene-visibility.d.ts.map +1 -1
  80. package/dist/lib/scene-visibility.js +15 -3
  81. package/dist/lib/scripted-opening.d.ts +11 -0
  82. package/dist/lib/scripted-opening.d.ts.map +1 -0
  83. package/dist/lib/scripted-opening.js +20 -0
  84. package/dist/lib/snapshot-pipeline.d.ts +32 -2
  85. package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
  86. package/dist/lib/snapshot-pipeline.js +215 -105
  87. package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -1
  88. package/dist/lib/terrain-perimeter-fill.js +22 -14
  89. package/dist/lib/zone-geometry.d.ts +11 -0
  90. package/dist/lib/zone-geometry.d.ts.map +1 -0
  91. package/dist/lib/zone-geometry.js +46 -0
  92. package/dist/store/use-item-light-pool.d.ts +14 -10
  93. package/dist/store/use-item-light-pool.d.ts.map +1 -1
  94. package/dist/store/use-item-light-pool.js +52 -26
  95. package/dist/store/use-viewer.d.ts +11 -0
  96. package/dist/store/use-viewer.d.ts.map +1 -1
  97. package/dist/store/use-viewer.js +13 -6
  98. package/dist/systems/ceiling/ceiling-system.d.ts +15 -1
  99. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  100. package/dist/systems/ceiling/ceiling-system.js +86 -6
  101. package/dist/systems/door/door-system.d.ts.map +1 -1
  102. package/dist/systems/door/door-system.js +55 -17
  103. package/dist/systems/floor-elevation/floor-elevation-system.d.ts +3 -1
  104. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
  105. package/dist/systems/floor-elevation/floor-elevation-system.js +33 -5
  106. package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
  107. package/dist/systems/geometry/geometry-system.js +71 -11
  108. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  109. package/dist/systems/interactive/interactive-system.js +40 -15
  110. package/dist/systems/interactive/procedural-controls.d.ts +13 -0
  111. package/dist/systems/interactive/procedural-controls.d.ts.map +1 -0
  112. package/dist/systems/interactive/procedural-controls.js +17 -0
  113. package/dist/systems/interactive/scripted-clips.d.ts +19 -0
  114. package/dist/systems/interactive/scripted-clips.d.ts.map +1 -0
  115. package/dist/systems/interactive/scripted-clips.js +134 -0
  116. package/dist/systems/item/item-system.d.ts.map +1 -1
  117. package/dist/systems/item/item-system.js +9 -3
  118. package/dist/systems/item/object-cut-invalidation.d.ts +3 -0
  119. package/dist/systems/item/object-cut-invalidation.d.ts.map +1 -0
  120. package/dist/systems/item/object-cut-invalidation.js +68 -0
  121. package/dist/systems/item-light/item-light-system.d.ts +1 -1
  122. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  123. package/dist/systems/item-light/item-light-system.js +47 -52
  124. package/dist/systems/level/level-system.d.ts.map +1 -1
  125. package/dist/systems/level/level-system.js +3 -5
  126. package/dist/systems/level/level-utils.d.ts +7 -4
  127. package/dist/systems/level/level-utils.d.ts.map +1 -1
  128. package/dist/systems/level/level-utils.js +17 -6
  129. package/dist/systems/level/shadow-only-levels.d.ts +9 -0
  130. package/dist/systems/level/shadow-only-levels.d.ts.map +1 -0
  131. package/dist/systems/level/shadow-only-levels.js +7 -0
  132. package/dist/systems/roof/roof-materials.d.ts +14 -2
  133. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  134. package/dist/systems/roof/roof-materials.js +54 -15
  135. package/dist/systems/roof/roof-system.d.ts +13 -3
  136. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  137. package/dist/systems/roof/roof-system.js +188 -13
  138. package/dist/systems/slab/slab-system.d.ts +1 -1
  139. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  140. package/dist/systems/slab/slab-system.js +49 -19
  141. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  142. package/dist/systems/stair/stair-system.js +133 -354
  143. package/dist/systems/wall/wall-cutout-cache.d.ts +7 -0
  144. package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
  145. package/dist/systems/wall/wall-cutout-cache.js +46 -17
  146. package/dist/systems/wall/wall-cutout.d.ts +6 -0
  147. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  148. package/dist/systems/wall/wall-cutout.js +42 -28
  149. package/dist/systems/wall/wall-finish-data.d.ts +22 -0
  150. package/dist/systems/wall/wall-finish-data.d.ts.map +1 -0
  151. package/dist/systems/wall/wall-finish-data.js +17 -0
  152. package/dist/systems/wall/wall-materials.d.ts +9 -4
  153. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  154. package/dist/systems/wall/wall-materials.js +99 -152
  155. package/dist/systems/wall/wall-system.d.ts +28 -2
  156. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  157. package/dist/systems/wall/wall-system.js +582 -143
  158. package/dist/systems/window/window-system.d.ts +1 -1
  159. package/dist/systems/window/window-system.d.ts.map +1 -1
  160. package/dist/systems/window/window-system.js +41 -22
  161. package/package.json +5 -5
  162. package/dist/systems/fence/fence-system.d.ts +0 -22
  163. package/dist/systems/fence/fence-system.d.ts.map +0 -1
  164. package/dist/systems/fence/fence-system.js +0 -357
@@ -13,6 +13,8 @@ export declare const glassMaterial: MeshLambertNodeMaterial;
13
13
  export declare function getMaterialTextureVersion(): number;
14
14
  export declare function resolveTextureRepeat(repeat: unknown, scale: unknown): [number, number];
15
15
  export declare function getTextureKey(material?: MaterialSchema): string;
16
+ /** Glass lets light through; shadow maps would otherwise treat it as a solid panel. */
17
+ export declare function materialCastsShadow(material: THREE.Material | THREE.Material[]): boolean;
16
18
  export declare function applyMaterialPresetToMaterials(materialInput: THREE.Material | THREE.Material[], preset: MaterialPresetPayload | null | undefined): void;
17
19
  export declare function createMaterialFromPreset(preset: MaterialPresetPayload, shading?: RenderShading): THREE.Material;
18
20
  export declare function createMaterialFromPresetRef(materialPreset?: string, shading?: RenderShading): THREE.Material | null;
@@ -26,17 +28,22 @@ export declare function createMaterial(material?: MaterialSchema, shading?: Rend
26
28
  */
27
29
  export declare function materialPresetRefSignature(ref: string): string;
28
30
  /**
29
- * Resolve a MaterialRef ('library:<id>' | 'scene:<id>') to a three.js material.
30
- * Returns null for an unknown / dangling ref so callers fall back to the
31
- * slot's default (authored material, then themed default). Never throws.
31
+ * Resolve a MaterialRef ('library:<id>' | 'scene:<id>') or a plain '#rrggbb'
32
+ * colour to a three.js material; the colour paints like
33
+ * `material: { properties: { color } }`. Returns null for an unknown / dangling
34
+ * ref so callers fall back to the slot's default (authored material, then
35
+ * themed default). Never throws.
32
36
  */
33
37
  export declare function resolveMaterialRef(ref: string | undefined, sceneMaterials: Record<SceneMaterialId, SceneMaterial> | undefined, shading?: RenderShading): THREE.Material | null;
34
38
  /**
35
- * Resolve a node kind's declared slot default — either a catalog `library:<id>`
36
- * finish or a flat `#rrggbb` colour — to a renderable material. Shared by the
37
- * procedural kinds whose colored-mode unpainted appearance comes from a
38
- * declarative default (slab, wall).
39
+ * Swaps declared slot DEFAULTS (never painted refs) for another finish, e.g.
40
+ * the worker thumbnail renders unpainted walls as plaster instead of the
41
+ * prepared-drywall default. Must be set before the scene builds its
42
+ * materials; `null` restores the declared defaults.
39
43
  */
44
+ export declare function setSlotDefaultOverrides(overrides: Readonly<Record<string, string>> | null): void;
45
+ /** A declared slot default after `setSlotDefaultOverrides`. */
46
+ export declare function resolveSlotDefaultRef(slotDefault: string): string;
40
47
  export declare function resolveSlotDefaultMaterial(slotDefault: string, shading?: RenderShading, roughness?: number): THREE.Material;
41
48
  export declare function createDefaultMaterial(color?: string, roughness?: number, shading?: RenderShading, side?: THREE.Side): THREE.Material;
42
49
  export declare function createSurfaceRoleMaterial(role: SurfaceRole, preset: ColorPreset, side?: THREE.Side, sceneThemeId?: string): THREE.Material;
@@ -1 +1 @@
1
- {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { getMaterialPresetByRef, parseMaterialRef, resolveMaterial, } from '@pascal-app/core';
1
+ import { getMaterialPresetByRef, materialColorPaint, parseMaterialColor, parseMaterialRef, resolveMaterial, } from '@pascal-app/core';
2
2
  import { addAfterEffect, invalidate } from '@react-three/fiber';
3
3
  import * as THREE from 'three';
4
4
  import { float, mix, positionViewDirection, transformedNormalView } from 'three/tsl';
@@ -346,6 +346,12 @@ function applyMaterialMapProperties(material, mapProperties) {
346
346
  // Glass-like transparency threshold: any standard material authored as
347
347
  // `transparent` with opacity below this gets the fresnel treatment.
348
348
  const GLASS_OPACITY_THRESHOLD = 0.6;
349
+ /** Glass lets light through; shadow maps would otherwise treat it as a solid panel. */
350
+ export function materialCastsShadow(material) {
351
+ const materials = Array.isArray(material) ? material : [material];
352
+ return !materials.some((entry) => entry.transmission > 0 ||
353
+ (entry.transparent && entry.opacity < GLASS_OPACITY_THRESHOLD));
354
+ }
349
355
  /**
350
356
  * Fresnel-driven opacity for glass: nearly the authored opacity head-on,
351
357
  * increasingly opaque (showing the environment reflection) at grazing angles.
@@ -446,14 +452,19 @@ export function createMaterial(material, shading = 'rendered') {
446
452
  * the dangling-ref fallback for the whole session.
447
453
  */
448
454
  export function materialPresetRefSignature(ref) {
449
- return getMaterialPresetByRef(ref) ? ref : `${ref}#unresolved`;
455
+ return getMaterialPresetByRef(ref) || parseMaterialColor(ref) ? ref : `${ref}#unresolved`;
450
456
  }
451
457
  /**
452
- * Resolve a MaterialRef ('library:<id>' | 'scene:<id>') to a three.js material.
453
- * Returns null for an unknown / dangling ref so callers fall back to the
454
- * slot's default (authored material, then themed default). Never throws.
458
+ * Resolve a MaterialRef ('library:<id>' | 'scene:<id>') or a plain '#rrggbb'
459
+ * colour to a three.js material; the colour paints like
460
+ * `material: { properties: { color } }`. Returns null for an unknown / dangling
461
+ * ref so callers fall back to the slot's default (authored material, then
462
+ * themed default). Never throws.
455
463
  */
456
464
  export function resolveMaterialRef(ref, sceneMaterials, shading = 'rendered') {
465
+ const color = parseMaterialColor(ref);
466
+ if (color)
467
+ return createMaterial(materialColorPaint(color), shading);
457
468
  const parsed = parseMaterialRef(ref);
458
469
  if (!parsed)
459
470
  return null;
@@ -470,7 +481,22 @@ export function resolveMaterialRef(ref, sceneMaterials, shading = 'rendered') {
470
481
  * procedural kinds whose colored-mode unpainted appearance comes from a
471
482
  * declarative default (slab, wall).
472
483
  */
484
+ let slotDefaultOverrides = null;
485
+ /**
486
+ * Swaps declared slot DEFAULTS (never painted refs) for another finish, e.g.
487
+ * the worker thumbnail renders unpainted walls as plaster instead of the
488
+ * prepared-drywall default. Must be set before the scene builds its
489
+ * materials; `null` restores the declared defaults.
490
+ */
491
+ export function setSlotDefaultOverrides(overrides) {
492
+ slotDefaultOverrides = overrides;
493
+ }
494
+ /** A declared slot default after `setSlotDefaultOverrides`. */
495
+ export function resolveSlotDefaultRef(slotDefault) {
496
+ return slotDefaultOverrides?.[slotDefault] ?? slotDefault;
497
+ }
473
498
  export function resolveSlotDefaultMaterial(slotDefault, shading = 'rendered', roughness = 0.9) {
499
+ slotDefault = resolveSlotDefaultRef(slotDefault);
474
500
  if (parseMaterialRef(slotDefault)?.kind === 'library') {
475
501
  return (createMaterialFromPresetRef(slotDefault, shading) ??
476
502
  cachedDefaultMaterial(`slot-#ffffff-${roughness}`, '#ffffff', roughness, shading));
@@ -0,0 +1,6 @@
1
+ import { type AnyNodeId } from '@pascal-app/core';
2
+ type HeightSampler = (x: number, z: number) => number | null;
3
+ /** Samples one locked node's upward-facing mesh in level-local coordinates. */
4
+ export declare function createNodeTopSurfaceHeightSampler(hostId: AnyNodeId, levelId: AnyNodeId): HeightSampler | null;
5
+ export {};
6
+ //# sourceMappingURL=node-top-surface-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-top-surface-height.d.ts","sourceRoot":"","sources":["../../src/lib/node-top-surface-height.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,kBAAkB,CAAA;AAKhE,KAAK,aAAa,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;AAS5D,+EAA+E;AAC/E,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,GACjB,aAAa,GAAG,IAAI,CAqEtB"}
@@ -0,0 +1,74 @@
1
+ import { sceneRegistry } from '@pascal-app/core';
2
+ import { Box3, Matrix3, Raycaster, Vector3 } from 'three';
3
+ import useViewer from '../store/use-viewer';
4
+ import { setSurfaceRaycastLayers } from './layers';
5
+ const samplerCache = new WeakMap();
6
+ /** Samples one locked node's upward-facing mesh in level-local coordinates. */
7
+ export function createNodeTopSurfaceHeightSampler(hostId, levelId) {
8
+ const host = sceneRegistry.nodes.get(hostId);
9
+ const level = sceneRegistry.nodes.get(levelId);
10
+ if (!(host && level))
11
+ return null;
12
+ host.updateWorldMatrix(true, false);
13
+ level.updateWorldMatrix(true, false);
14
+ const revision = useViewer.getState().geometryRevision;
15
+ const cached = samplerCache.get(host)?.get(level);
16
+ if (cached?.revision === revision &&
17
+ cached.hostMatrix.every((value, index) => value === host.matrixWorld.elements[index]) &&
18
+ cached.levelMatrix.every((value, index) => value === level.matrixWorld.elements[index])) {
19
+ return cached.sample;
20
+ }
21
+ host.updateWorldMatrix(true, true);
22
+ const bounds = new Box3().setFromObject(host);
23
+ if (bounds.isEmpty())
24
+ return null;
25
+ const raycaster = new Raycaster();
26
+ setSurfaceRaycastLayers(raycaster.layers);
27
+ raycaster.far = Math.max(4, bounds.max.y - bounds.min.y + 4);
28
+ const origin = new Vector3();
29
+ const direction = new Vector3(0, -1, 0);
30
+ const normal = new Vector3();
31
+ const normalMatrix = new Matrix3();
32
+ const registeredRoots = new Set(sceneRegistry.nodes.values());
33
+ const sample = (x, z) => {
34
+ origin.set(x, 0, z);
35
+ level.localToWorld(origin);
36
+ origin.y = bounds.max.y + 2;
37
+ raycaster.set(origin, direction);
38
+ for (const hit of raycaster.intersectObject(host, true)) {
39
+ if (!hit.face)
40
+ continue;
41
+ let owner = hit.object.parent;
42
+ let nestedNode = false;
43
+ while (owner && owner !== host) {
44
+ if (registeredRoots.has(owner)) {
45
+ nestedNode = true;
46
+ break;
47
+ }
48
+ owner = owner.parent;
49
+ }
50
+ if (nestedNode)
51
+ continue;
52
+ normalMatrix.getNormalMatrix(hit.object.matrixWorld);
53
+ normal.copy(hit.face.normal).applyMatrix3(normalMatrix).normalize();
54
+ if (normal.y < 0.1)
55
+ continue;
56
+ const point = hit.point.clone();
57
+ level.worldToLocal(point);
58
+ return point.y;
59
+ }
60
+ return null;
61
+ };
62
+ let byLevel = samplerCache.get(host);
63
+ if (!byLevel) {
64
+ byLevel = new WeakMap();
65
+ samplerCache.set(host, byLevel);
66
+ }
67
+ byLevel.set(level, {
68
+ revision,
69
+ hostMatrix: [...host.matrixWorld.elements],
70
+ levelMatrix: [...level.matrixWorld.elements],
71
+ sample,
72
+ });
73
+ return sample;
74
+ }
@@ -0,0 +1,39 @@
1
+ type TemporalLike = {
2
+ temporal: {
3
+ getState(): {
4
+ pastStates: readonly unknown[];
5
+ futureStates: readonly unknown[];
6
+ isTracking: boolean;
7
+ };
8
+ };
9
+ };
10
+ type SelectionLike = {
11
+ getState(): {
12
+ selection: {
13
+ buildingId: string | null;
14
+ levelId: string | null;
15
+ zoneId: string | null;
16
+ selectedIds: readonly string[];
17
+ };
18
+ };
19
+ };
20
+ export type PerfHistoryState = {
21
+ /** Undo entries. */
22
+ past: number;
23
+ /** Redo entries. */
24
+ future: number;
25
+ /** False while any owner has history paused. */
26
+ tracking: boolean;
27
+ /** Refcounted pause owners (`pauseSceneHistory` + leases); direct `temporal.pause()` is not counted. */
28
+ pauseDepth: number;
29
+ };
30
+ export type PerfSelectionState = {
31
+ buildingId: string | null;
32
+ levelId: string | null;
33
+ zoneId: string | null;
34
+ selectedIds: string[];
35
+ };
36
+ export declare function readPerfHistory(store: TemporalLike): PerfHistoryState;
37
+ export declare function readPerfSelection(store: SelectionLike): PerfSelectionState;
38
+ export {};
39
+ //# sourceMappingURL=perf-probe-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf-probe-state.d.ts","sourceRoot":"","sources":["../../src/lib/perf-probe-state.ts"],"names":[],"mappings":"AAMA,KAAK,YAAY,GAAG;IAClB,QAAQ,EAAE;QACR,QAAQ,IAAI;YACV,UAAU,EAAE,SAAS,OAAO,EAAE,CAAA;YAC9B,YAAY,EAAE,SAAS,OAAO,EAAE,CAAA;YAChC,UAAU,EAAE,OAAO,CAAA;SACpB,CAAA;KACF,CAAA;CACF,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,IAAI;QACV,SAAS,EAAE;YACT,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;YACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;YACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;YACrB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;SAC/B,CAAA;KACF,CAAA;CACF,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAA;IACjB,wGAAwG;IACxG,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,CAQrE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,kBAAkB,CAG1E"}
@@ -0,0 +1,17 @@
1
+ // Read-only state for scripted `?perf` receipts (bench/next-house, scripts/perf): the scene
2
+ // history and the viewer selection, so production builds can report undo entries and
3
+ // history pauses without dev-only store handles.
4
+ import { getSceneHistoryPauseDepth } from '@pascal-app/core';
5
+ export function readPerfHistory(store) {
6
+ const temporal = store.temporal.getState();
7
+ return {
8
+ past: temporal.pastStates.length,
9
+ future: temporal.futureStates.length,
10
+ tracking: temporal.isTracking,
11
+ pauseDepth: getSceneHistoryPauseDepth(),
12
+ };
13
+ }
14
+ export function readPerfSelection(store) {
15
+ const { buildingId, levelId, zoneId, selectedIds } = store.getState().selection;
16
+ return { buildingId, levelId, zoneId, selectedIds: [...selectedIds] };
17
+ }
@@ -3,5 +3,13 @@ import * as THREE from 'three';
3
3
  /** Opt in only when the raycast appends hits without reading prior hits or mutating scene/query state. */
4
4
  export declare function markPureRaycast<T extends THREE.Object3D['raycast']>(raycast: T): T;
5
5
  export declare function choosePointerEvents(search?: string): typeof createWebEvents;
6
+ /**
7
+ * Whether a mesh has a material for everything a raycast reads: three indexes
8
+ * a material array by each geometry group, and one with no entry throws on
9
+ * `material.side`. A mesh caught mid-swap (a preview restored an older array
10
+ * over a rebuilt geometry) is skipped for this move instead of taking the whole
11
+ * pointer event down; its children are still tested.
12
+ */
13
+ export declare function hasMaterialsForGroups(object: THREE.Object3D): boolean;
6
14
  export declare function createPascalPointerEvents(store: RootStore): EventManager<HTMLElement>;
7
15
  //# sourceMappingURL=pointer-events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pointer-events.d.ts","sourceRoot":"","sources":["../../src/lib/pointer-events.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,MAAM,IAAI,eAAe,EAGzB,KAAK,YAAY,EAMjB,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqC9B,0GAA0G;AAC1G,wBAAgB,eAAe,CAAC,CAAC,SAAS,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAGlF;AAYD,wBAAgB,mBAAmB,CACjC,MAAM,SAA8D,GACnE,OAAO,eAAe,CAIxB;AAiLD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,CAmBrF"}
1
+ {"version":3,"file":"pointer-events.d.ts","sourceRoot":"","sources":["../../src/lib/pointer-events.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,MAAM,IAAI,eAAe,EAGzB,KAAK,YAAY,EAMjB,KAAK,SAAS,EAEf,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqC9B,0GAA0G;AAC1G,wBAAgB,eAAe,CAAC,CAAC,SAAS,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAGlF;AAYD,wBAAgB,mBAAmB,CACjC,MAAM,SAA8D,GACnE,OAAO,eAAe,CAIxB;AAiED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,GAAG,OAAO,CAUrE;AAkHD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,CAmBrF"}
@@ -21,8 +21,8 @@
21
21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  * SOFTWARE.
23
23
  *
24
- * Vendored from R3F 9.6.1:
25
- * https://raw.githubusercontent.com/pmndrs/react-three-fiber/v9.6.1/packages/fiber/src/core/events.ts
24
+ * Vendored from R3F 9.8.1:
25
+ * https://raw.githubusercontent.com/pmndrs/react-three-fiber/v9.8.1/packages/fiber/src/core/events.ts
26
26
  * Ray collection is cached; camera-drag moves are throttled before stock dispatch.
27
27
  * The throttle is a vendored-manager policy; dev ?stockEvents uses untouched R3F.
28
28
  */
@@ -112,6 +112,28 @@ function querySnapshot(raycaster) {
112
112
  }
113
113
  return snapshot;
114
114
  }
115
+ /**
116
+ * Whether a mesh has a material for everything a raycast reads: three indexes
117
+ * a material array by each geometry group, and one with no entry throws on
118
+ * `material.side`. A mesh caught mid-swap (a preview restored an older array
119
+ * over a rebuilt geometry) is skipped for this move instead of taking the whole
120
+ * pointer event down; its children are still tested.
121
+ */
122
+ export function hasMaterialsForGroups(object) {
123
+ const mesh = object;
124
+ if (!mesh.isMesh)
125
+ return true;
126
+ const material = mesh.material;
127
+ if (!material)
128
+ return false;
129
+ if (!Array.isArray(material))
130
+ return true;
131
+ for (const group of mesh.geometry?.groups ?? []) {
132
+ if (!material[group.materialIndex ?? 0])
133
+ return false;
134
+ }
135
+ return true;
136
+ }
115
137
  function distanceOrder(a, b) {
116
138
  return a.distance - b.distance;
117
139
  }
@@ -140,7 +162,8 @@ function createCachedRaycast() {
140
162
  unsupportedObject = object;
141
163
  return false;
142
164
  }
143
- result = object.raycast(raycaster, hits);
165
+ if (hasMaterialsForGroups(object))
166
+ result = object.raycast(raycaster, hits);
144
167
  }
145
168
  if (result !== false) {
146
169
  const children = object.children;
@@ -246,7 +269,7 @@ export function createPascalPointerEvents(store) {
246
269
  return manager;
247
270
  }
248
271
  function makeId(event) {
249
- // biome-ignore lint/style/useTemplate: Keep the vendored dispatch identical to R3F 9.6.1.
272
+ // biome-ignore lint/style/useTemplate: Keep the vendored dispatch identical to R3F 9.8.1.
250
273
  return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
251
274
  }
252
275
  /**
@@ -0,0 +1,7 @@
1
+ import type { EvaluatedLight } from '@pascal-app/core/procedural-items';
2
+ import type { Material, Mesh, Object3D } from 'three';
3
+ export declare function cloneWithProceduralEmission(material: Material, color: string, on: boolean): Material;
4
+ export declare function setProceduralEmission(material: Material, on: boolean): void;
5
+ export declare function proceduralSlotMeshes(root: Object3D, slots: Set<string>): Mesh[];
6
+ export declare function decorateProceduralEmission(root: Object3D, lights: EvaluatedLight[], on: boolean): () => void;
7
+ //# sourceMappingURL=procedural-emission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedural-emission.d.ts","sourceRoot":"","sources":["../../src/lib/procedural-emission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACvE,OAAO,KAAK,EAAS,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAQ5D,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,OAAO,GACV,QAAQ,CAQV;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAG3E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAW/E;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,cAAc,EAAE,EACxB,EAAE,EAAE,OAAO,GACV,MAAM,IAAI,CAwBZ"}
@@ -0,0 +1,54 @@
1
+ export function cloneWithProceduralEmission(material, color, on) {
2
+ const clone = material.clone();
3
+ clone.userData = { ...clone.userData, __pascalCachedMaterial: false };
4
+ if (clone.emissive)
5
+ clone.emissive.set(color);
6
+ if ('emissiveIntensity' in clone)
7
+ clone.emissiveIntensity = on ? 1 : 0;
8
+ if ('emissiveMap' in clone)
9
+ clone.emissiveMap = null;
10
+ clone.needsUpdate = true;
11
+ return clone;
12
+ }
13
+ export function setProceduralEmission(material, on) {
14
+ const controlled = material;
15
+ if ('emissiveIntensity' in controlled)
16
+ controlled.emissiveIntensity = on ? 1 : 0;
17
+ }
18
+ export function proceduralSlotMeshes(root, slots) {
19
+ const meshes = [];
20
+ const owner = root.userData.pascalId;
21
+ const visit = (object) => {
22
+ if (object !== root && object.userData.pascalId && object.userData.pascalId !== owner)
23
+ return;
24
+ const mesh = object;
25
+ if (mesh.isMesh && slots.has(mesh.userData.slotId))
26
+ meshes.push(mesh);
27
+ for (const child of object.children)
28
+ visit(child);
29
+ };
30
+ visit(root);
31
+ return meshes;
32
+ }
33
+ export function decorateProceduralEmission(root, lights, on) {
34
+ const colors = new Map(lights.flatMap((light) => light.emissiveSlot ? [[light.emissiveSlot, light.color]] : []));
35
+ const restores = [];
36
+ for (const mesh of proceduralSlotMeshes(root, new Set(colors.keys()))) {
37
+ const slot = mesh.userData.slotId;
38
+ const color = colors.get(slot);
39
+ if (!color)
40
+ continue;
41
+ const previous = mesh.material;
42
+ const clones = (Array.isArray(previous) ? previous : [previous]).map((material) => cloneWithProceduralEmission(material, color, on));
43
+ mesh.material = Array.isArray(previous) ? clones : clones[0];
44
+ restores.push(() => {
45
+ mesh.material = previous;
46
+ for (const clone of clones)
47
+ clone.dispose();
48
+ });
49
+ }
50
+ return () => {
51
+ for (const restore of restores)
52
+ restore();
53
+ };
54
+ }
@@ -0,0 +1,4 @@
1
+ import { type AnyNode, type AnyNodeId } from '@pascal-app/core';
2
+ /** The highest walkable surface at a level-local point, including rendered shaped tops. */
3
+ export declare function createSceneSupportHeightSampler(nodes: Readonly<Record<AnyNodeId, AnyNode>>, levelId: AnyNodeId, selectedHostId?: AnyNodeId): (x: number, z: number) => number;
4
+ //# sourceMappingURL=scene-support-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-support-height.d.ts","sourceRoot":"","sources":["../../src/lib/scene-support-height.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AAGzB,2FAA2F;AAC3F,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAC3C,OAAO,EAAE,SAAS,EAClB,cAAc,CAAC,EAAE,SAAS,GACzB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAiClC"}
@@ -0,0 +1,34 @@
1
+ import { findLevelAncestorId, levelBaseElevationAt, nodeRegistry, } from '@pascal-app/core';
2
+ import { createNodeTopSurfaceHeightSampler } from './node-top-surface-height';
3
+ /** The highest walkable surface at a level-local point, including rendered shaped tops. */
4
+ export function createSceneSupportHeightSampler(nodes, levelId, selectedHostId) {
5
+ const supports = Object.values(nodes)
6
+ .filter((node) => node.visible !== false &&
7
+ (!selectedHostId || node.id === selectedHostId) &&
8
+ findLevelAncestorId(node.id, nodes) === levelId &&
9
+ !!nodeRegistry.get(node.type)?.capabilities.surfaces?.top)
10
+ .map((node) => {
11
+ const top = nodeRegistry.get(node.type)?.capabilities.surfaces?.top;
12
+ const resolveSupportHeight = top?.supportHeight;
13
+ return {
14
+ node,
15
+ resolveDataHeight: resolveSupportHeight
16
+ ? (x, z) => resolveSupportHeight(node, x, z, { nodes })
17
+ : null,
18
+ sampleRenderedHeight: resolveSupportHeight
19
+ ? null
20
+ : createNodeTopSurfaceHeightSampler(node.id, levelId),
21
+ };
22
+ });
23
+ return (x, z) => {
24
+ let height = levelBaseElevationAt(nodes, levelId, x, z);
25
+ for (const support of supports) {
26
+ const top = support.resolveDataHeight
27
+ ? support.resolveDataHeight(x, z)
28
+ : (support.sampleRenderedHeight?.(x, z) ?? null);
29
+ if (top !== null)
30
+ height = Math.max(height, top);
31
+ }
32
+ return height;
33
+ };
34
+ }
@@ -12,4 +12,10 @@ export declare function hideFromScene(obj: Object3D, reason: HiddenReason): void
12
12
  /** Drops `reason`, restoring the mask `obj` had before the first one arrived. */
13
13
  export declare function showInScene(obj: Object3D, reason: HiddenReason): void;
14
14
  export declare function temporarilyShowShadowOnly(root: Object3D): () => void;
15
+ /**
16
+ * Lifts what the user's view holds back under `root` — solo's shadow-only
17
+ * levels and isolation — for one capture: an interior view shows its floor
18
+ * whole, whatever the user isolated.
19
+ */
20
+ export declare function temporarilyShowPresentation(root: Object3D): () => void;
15
21
  //# sourceMappingURL=scene-visibility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scene-visibility.d.ts","sourceRoot":"","sources":["../../src/lib/scene-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGrC;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,cAAc,CAAA;AAmBlF,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAMvE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAarE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAgBpE"}
1
+ {"version":3,"file":"scene-visibility.d.ts","sourceRoot":"","sources":["../../src/lib/scene-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGrC;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,cAAc,CAAA;AAmBlF,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAMvE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAarE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAEtE"}
@@ -34,16 +34,28 @@ export function showInScene(obj, reason) {
34
34
  delete holder[HOLD];
35
35
  }
36
36
  export function temporarilyShowShadowOnly(root) {
37
+ return temporarilyShowHeld(root, ['shadow-only']);
38
+ }
39
+ /**
40
+ * Lifts what the user's view holds back under `root` — solo's shadow-only
41
+ * levels and isolation — for one capture: an interior view shows its floor
42
+ * whole, whatever the user isolated.
43
+ */
44
+ export function temporarilyShowPresentation(root) {
45
+ return temporarilyShowHeld(root, ['shadow-only', 'isolated']);
46
+ }
47
+ function temporarilyShowHeld(root, lifted) {
37
48
  const masks = new Map();
38
49
  root.traverse((obj) => {
39
50
  const hold = obj[HOLD];
40
- if (!hold?.reasons.has('shadow-only'))
51
+ if (!hold || !lifted.some((reason) => hold.reasons.has(reason)))
41
52
  return;
42
53
  masks.set(obj, obj.layers.mask);
43
54
  const reasons = new Set(hold.reasons);
44
- reasons.delete('shadow-only');
55
+ for (const reason of lifted)
56
+ reasons.delete(reason);
45
57
  // A capture needs the original scene geometry, while editor overlays and
46
- // objects hidden by isolation or batching must retain their own masks.
58
+ // the reasons not lifted (batching) must retain their own masks.
47
59
  if (reasons.size === 0)
48
60
  obj.layers.mask = hold.original;
49
61
  else
@@ -0,0 +1,11 @@
1
+ import type * as THREE from 'three';
2
+ /** The group a scripted window or door renders its artifact into; the opening's system leaves it alone. */
3
+ export declare const SCRIPTED_MODEL_FLAG = "scriptedModel";
4
+ /**
5
+ * A window or door built from a script renders its artifact, not the
6
+ * parametric frame: drop what an earlier parametric build left under the
7
+ * mesh, and report whether the artifact has loaded (until then the node
8
+ * stays dirty, so scene-ready and bakes wait for it, as for items).
9
+ */
10
+ export declare function settleScriptedOpening(mesh: THREE.Object3D): boolean;
11
+ //# sourceMappingURL=scripted-opening.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripted-opening.d.ts","sourceRoot":"","sources":["../../src/lib/scripted-opening.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AAEnC,2GAA2G;AAC3G,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,GAAG,OAAO,CAWnE"}
@@ -0,0 +1,20 @@
1
+ /** The group a scripted window or door renders its artifact into; the opening's system leaves it alone. */
2
+ export const SCRIPTED_MODEL_FLAG = 'scriptedModel';
3
+ /**
4
+ * A window or door built from a script renders its artifact, not the
5
+ * parametric frame: drop what an earlier parametric build left under the
6
+ * mesh, and report whether the artifact has loaded (until then the node
7
+ * stays dirty, so scene-ready and bakes wait for it, as for items).
8
+ */
9
+ export function settleScriptedOpening(mesh) {
10
+ let settled = false;
11
+ for (const child of [...mesh.children]) {
12
+ if (child.userData[SCRIPTED_MODEL_FLAG]) {
13
+ settled = child.userData.itemModelSettled === true;
14
+ continue;
15
+ }
16
+ mesh.remove(child);
17
+ child.traverse((object) => object.geometry?.dispose());
18
+ }
19
+ return settled;
20
+ }
@@ -29,6 +29,21 @@ export type SnapshotCaptureResult = {
29
29
  outW: number;
30
30
  outH: number;
31
31
  };
32
+ /**
33
+ * An opaque studio backdrop in place of the theme sky: a radial gradient in
34
+ * exact sRGB (never tone mapped, so the hexes land as authored). Fixed at
35
+ * pipeline creation — callers without one get the untouched theme-backdrop
36
+ * pipeline. Ground shadows come from the caller's own shadow catcher, which
37
+ * composites over it through the scene alpha.
38
+ */
39
+ export type StudioBackdrop = {
40
+ /** sRGB hex at `center`. */
41
+ inner: string;
42
+ /** sRGB hex at the frame corner farthest from `center`. */
43
+ outer: string;
44
+ /** Gradient centre in screen UV (0,0 = top-left). */
45
+ center: [number, number];
46
+ };
32
47
  export type SnapshotPipeline = {
33
48
  applyEnvironment: ({ theme, transparent, grade, edges, camera, }: {
34
49
  theme: string;
@@ -37,17 +52,32 @@ export type SnapshotPipeline = {
37
52
  edges: EdgeMode;
38
53
  camera: Camera;
39
54
  }) => void;
40
- capture: ({ captureMode, cropRegion, standardSize, }: {
55
+ capture: ({ captureMode, cropRegion, standardSize, mime, }: {
41
56
  captureMode?: SnapshotCaptureMode;
42
57
  cropRegion?: SnapshotCropRegion;
43
58
  standardSize?: SnapshotSize;
59
+ /** The encoding, when not the snapshot default (a print picture wants a lossless `image/png`). */
60
+ mime?: string;
44
61
  }) => Promise<SnapshotCaptureResult>;
45
62
  dispose: () => void;
46
63
  };
47
- export declare function createSnapshotPipeline({ renderer, scene, camera, atmosphere, }: {
64
+ export declare function createSnapshotPipeline({ renderer, scene, camera, atmosphere, studioBackdrop, }: {
48
65
  renderer: WebGPURenderer;
49
66
  scene: Scene;
50
67
  camera: Camera;
51
68
  atmosphere?: SceneAtmosphereSource | null;
69
+ studioBackdrop?: StudioBackdrop;
70
+ }): Promise<SnapshotPipeline | null>;
71
+ /**
72
+ * A capture WITHOUT the post-processing stack: the scene as the renderer
73
+ * draws it, into an offscreen target, read back and encoded like the
74
+ * post-processed frames. The sheets' orthographic elevation captures use
75
+ * it (2026-09-10): an SSGI pass built for a second, orthographic camera
76
+ * never delivered a frame and held the generator's guard forever.
77
+ */
78
+ export declare function createPlainSnapshotPipeline({ renderer, scene, camera, }: {
79
+ renderer: WebGPURenderer;
80
+ scene: Scene;
81
+ camera: Camera;
52
82
  }): Promise<SnapshotPipeline | null>;
53
83
  //# sourceMappingURL=snapshot-pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAkB,KAAK,KAAK,EAAoB,MAAM,OAAO,CAAA;AAoBjF,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,EAAE,KAAK,QAAQ,EAAqC,MAAM,cAAc,CAAA;AAK/E,eAAO,MAAM,eAAe,OAAO,CAAA;AACnC,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC;;;;;GAKG;AACH,eAAO,MAAM,aAAa,eAAe,CAAA;AACzC,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAUrC,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAA;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,EAAE,CAAC,EACjB,KAAK,EACL,WAAW,EACX,KAAK,EACL,KAAK,EACL,MAAM,GACP,EAAE;QACD,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,OAAO,CAAA;QACpB,KAAK,EAAE,OAAO,CAAA;QACd,KAAK,EAAE,QAAQ,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;KACf,KAAK,IAAI,CAAA;IACV,OAAO,EAAE,CAAC,EACR,WAAW,EACX,UAAU,EACV,YAAY,GACb,EAAE;QACD,WAAW,CAAC,EAAE,mBAAmB,CAAA;QACjC,UAAU,CAAC,EAAE,kBAAkB,CAAA;QAC/B,YAAY,CAAC,EAAE,YAAY,CAAA;KAC5B,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACpC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAgBD,wBAAsB,sBAAsB,CAAC,EAC3C,QAAQ,EACR,KAAK,EACL,MAAM,EACN,UAAiB,GAClB,EAAE;IACD,QAAQ,EAAE,cAAc,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAA;CAC1C,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA0SnC"}
1
+ {"version":3,"file":"snapshot-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot-pipeline.ts"],"names":[],"mappings":"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"}