@pascal-app/viewer 0.6.0 → 0.8.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 (107) hide show
  1. package/dist/components/error-boundary.d.ts +7 -3
  2. package/dist/components/error-boundary.d.ts.map +1 -1
  3. package/dist/components/error-boundary.js +3 -1
  4. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +1 -1
  5. package/dist/components/renderers/ceiling/ceiling-renderer.js +19 -3
  6. package/dist/components/renderers/column/column-renderer.d.ts +5 -0
  7. package/dist/components/renderers/column/column-renderer.d.ts.map +1 -0
  8. package/dist/components/renderers/column/column-renderer.js +597 -0
  9. package/dist/components/renderers/door/door-renderer.d.ts.map +1 -1
  10. package/dist/components/renderers/door/door-renderer.js +4 -9
  11. package/dist/components/renderers/fence/fence-renderer.d.ts.map +1 -1
  12. package/dist/components/renderers/fence/fence-renderer.js +2 -16
  13. package/dist/components/renderers/guide/guide-renderer.js +1 -1
  14. package/dist/components/renderers/item/item-renderer.d.ts.map +1 -1
  15. package/dist/components/renderers/item/item-renderer.js +2 -1
  16. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  17. package/dist/components/renderers/node-renderer.js +3 -1
  18. package/dist/components/renderers/roof/roof-renderer.d.ts.map +1 -1
  19. package/dist/components/renderers/roof/roof-renderer.js +1 -13
  20. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +1 -1
  21. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +5 -20
  22. package/dist/components/renderers/slab/slab-renderer.d.ts.map +1 -1
  23. package/dist/components/renderers/slab/slab-renderer.js +38 -26
  24. package/dist/components/renderers/spawn/spawn-renderer.d.ts +5 -0
  25. package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +1 -0
  26. package/dist/components/renderers/spawn/spawn-renderer.js +32 -0
  27. package/dist/components/renderers/stair/stair-renderer.d.ts.map +1 -1
  28. package/dist/components/renderers/stair/stair-renderer.js +7 -25
  29. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +1 -1
  30. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +4 -2
  31. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  32. package/dist/components/viewer/frame-limiter.js +5 -1
  33. package/dist/components/viewer/index.d.ts +3 -0
  34. package/dist/components/viewer/index.d.ts.map +1 -1
  35. package/dist/components/viewer/index.js +89 -19
  36. package/dist/components/viewer/post-processing.d.ts +13 -1
  37. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  38. package/dist/components/viewer/post-processing.js +71 -35
  39. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  40. package/dist/components/viewer/selection-manager.js +19 -2
  41. package/dist/hooks/use-node-events.d.ts +9 -1
  42. package/dist/hooks/use-node-events.d.ts.map +1 -1
  43. package/dist/index.d.ts +6 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +5 -2
  46. package/dist/lib/materials.d.ts +3 -0
  47. package/dist/lib/materials.d.ts.map +1 -1
  48. package/dist/lib/materials.js +16 -3
  49. package/dist/lib/merged-outline-node.d.ts +2 -0
  50. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  51. package/dist/lib/merged-outline-node.js +29 -16
  52. package/dist/store/use-viewer.d.ts +4 -4
  53. package/dist/store/use-viewer.d.ts.map +1 -1
  54. package/dist/store/use-viewer.js +2 -2
  55. package/dist/systems/ceiling/ceiling-system.d.ts +8 -0
  56. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -0
  57. package/dist/systems/ceiling/ceiling-system.js +91 -0
  58. package/dist/systems/column/column-geometry.d.ts +22 -0
  59. package/dist/systems/column/column-geometry.d.ts.map +1 -0
  60. package/dist/systems/column/column-geometry.js +108 -0
  61. package/dist/systems/door/door-animation-system.d.ts +2 -0
  62. package/dist/systems/door/door-animation-system.d.ts.map +1 -0
  63. package/dist/systems/door/door-animation-system.js +53 -0
  64. package/dist/systems/door/door-system.d.ts +2 -0
  65. package/dist/systems/door/door-system.d.ts.map +1 -0
  66. package/dist/systems/door/door-system.js +867 -0
  67. package/dist/systems/fence/fence-system.d.ts +2 -0
  68. package/dist/systems/fence/fence-system.d.ts.map +1 -0
  69. package/dist/systems/fence/fence-system.js +185 -0
  70. package/dist/systems/guide/guide-system.d.ts.map +1 -1
  71. package/dist/systems/guide/guide-system.js +1 -26
  72. package/dist/systems/item/item-system.d.ts +2 -0
  73. package/dist/systems/item/item-system.d.ts.map +1 -0
  74. package/dist/systems/item/item-system.js +44 -0
  75. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  76. package/dist/systems/roof/roof-materials.js +18 -1
  77. package/dist/systems/roof/roof-system.d.ts +16 -0
  78. package/dist/systems/roof/roof-system.d.ts.map +1 -0
  79. package/dist/systems/roof/roof-system.js +800 -0
  80. package/dist/systems/scan/scan-system.d.ts.map +1 -1
  81. package/dist/systems/scan/scan-system.js +1 -26
  82. package/dist/systems/slab/slab-system.d.ts +8 -0
  83. package/dist/systems/slab/slab-system.d.ts.map +1 -0
  84. package/dist/systems/slab/slab-system.js +155 -0
  85. package/dist/systems/stair/stair-materials.d.ts.map +1 -1
  86. package/dist/systems/stair/stair-materials.js +25 -2
  87. package/dist/systems/stair/stair-system.d.ts +2 -0
  88. package/dist/systems/stair/stair-system.d.ts.map +1 -0
  89. package/dist/systems/stair/stair-system.js +770 -0
  90. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  91. package/dist/systems/wall/wall-materials.js +2 -2
  92. package/dist/systems/wall/wall-system.d.ts +11 -0
  93. package/dist/systems/wall/wall-system.d.ts.map +1 -0
  94. package/dist/systems/wall/wall-system.js +595 -0
  95. package/dist/systems/window/window-animation-system.d.ts +2 -0
  96. package/dist/systems/window/window-animation-system.d.ts.map +1 -0
  97. package/dist/systems/window/window-animation-system.js +135 -0
  98. package/dist/systems/window/window-system.d.ts +12 -0
  99. package/dist/systems/window/window-system.d.ts.map +1 -0
  100. package/dist/systems/window/window-system.js +1430 -0
  101. package/package.json +6 -4
  102. package/dist/lib/suppress-three-clock-warning.d.ts +0 -25
  103. package/dist/lib/suppress-three-clock-warning.d.ts.map +0 -1
  104. package/dist/lib/suppress-three-clock-warning.js +0 -51
  105. package/dist/systems/export/export-system.d.ts +0 -2
  106. package/dist/systems/export/export-system.d.ts.map +0 -1
  107. package/dist/systems/export/export-system.js +0 -60
@@ -12,6 +12,18 @@ export declare const SSGI_PARAMS: {
12
12
  useScreenSpaceSampling: boolean;
13
13
  useTemporalFiltering: boolean;
14
14
  };
15
- declare const PostProcessingPasses: () => null;
15
+ export type HoverStyle = {
16
+ visibleColor: number;
17
+ hiddenColor: number;
18
+ strength: number;
19
+ pulse: boolean;
20
+ };
21
+ export type HoverStyles = {
22
+ default: HoverStyle;
23
+ } & Record<string, HoverStyle>;
24
+ export declare const DEFAULT_HOVER_STYLES: HoverStyles;
25
+ declare const PostProcessingPasses: ({ hoverStyles, }: {
26
+ hoverStyles?: HoverStyles;
27
+ }) => null;
16
28
  export default PostProcessingPasses;
17
29
  //# sourceMappingURL=post-processing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA4BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,CAAA;AAuBD,QAAA,MAAM,oBAAoB,YAoSzB,CAAA;AAED,eAAe,oBAAoB,CAAA"}
1
+ {"version":3,"file":"post-processing.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/post-processing.tsx"],"names":[],"mappings":"AA4BA,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAavB,CAAA;AAQD,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,UAAU,CAAA;CACpB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAS9B,eAAO,MAAM,oBAAoB,EAAE,WAElC,CAAA;AAiBD,QAAA,MAAM,oBAAoB,GAAI,kBAE3B;IACD,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,SAyTA,CAAA;AAED,eAAe,oBAAoB,CAAA"}
@@ -27,6 +27,15 @@ const MAX_PIPELINE_RETRIES = 3;
27
27
  const RETRY_DELAY_MS = 500;
28
28
  const DARK_BG = '#1f2433';
29
29
  const LIGHT_BG = '#ffffff';
30
+ const DEFAULT_HOVER_STYLE = {
31
+ visibleColor: 0x00_aa_ff,
32
+ hiddenColor: 0xf3_ff_47,
33
+ strength: 5,
34
+ pulse: true,
35
+ };
36
+ export const DEFAULT_HOVER_STYLES = {
37
+ default: DEFAULT_HOVER_STYLE,
38
+ };
30
39
  function sanitizeOutlineObjects(objects) {
31
40
  let nextIndex = 0;
32
41
  for (const object of objects) {
@@ -38,8 +47,8 @@ function sanitizeOutlineObjects(objects) {
38
47
  }
39
48
  objects.length = nextIndex;
40
49
  }
41
- const PostProcessingPasses = () => {
42
- const { gl: renderer, scene, camera } = useThree();
50
+ const PostProcessingPasses = ({ hoverStyles = DEFAULT_HOVER_STYLES, }) => {
51
+ const { gl: renderer, invalidate, scene, camera } = useThree();
43
52
  const renderPipelineRef = useRef(null);
44
53
  const hasPipelineErrorRef = useRef(false);
45
54
  const retryCountRef = useRef(0);
@@ -57,6 +66,10 @@ const PostProcessingPasses = () => {
57
66
  return l;
58
67
  }, []);
59
68
  const hoverHighlightMode = useViewer((s) => s.hoverHighlightMode);
69
+ const hoverVisibleColor = useMemo(() => uniform(new Color(DEFAULT_HOVER_STYLE.visibleColor)), []);
70
+ const hoverHiddenColor = useMemo(() => uniform(new Color(DEFAULT_HOVER_STYLE.hiddenColor)), []);
71
+ const hoverStrength = useMemo(() => uniform(DEFAULT_HOVER_STYLE.strength), []);
72
+ const hoverPulseMix = useMemo(() => uniform(DEFAULT_HOVER_STYLE.pulse ? 0 : 1), []);
60
73
  // Subscribe to projectId so the pipeline rebuilds on project switch
61
74
  const projectId = useViewer((s) => s.projectId);
62
75
  // Bump this to force a pipeline rebuild (used by retry logic)
@@ -70,8 +83,6 @@ const PostProcessingPasses = () => {
70
83
  }, []);
71
84
  // Reset retry state when project changes
72
85
  useEffect(() => {
73
- // Intentionally touch projectId so the effect reruns on project switches.
74
- void projectId;
75
86
  retryCountRef.current = 0;
76
87
  if (rebuildTimeoutRef.current !== null) {
77
88
  clearTimeout(rebuildTimeoutRef.current);
@@ -86,31 +97,40 @@ const PostProcessingPasses = () => {
86
97
  }
87
98
  };
88
99
  }, []);
100
+ useEffect(() => {
101
+ const style = hoverStyles[hoverHighlightMode] ?? hoverStyles.default;
102
+ hoverVisibleColor.value.setHex(style.visibleColor);
103
+ hoverHiddenColor.value.setHex(style.hiddenColor);
104
+ hoverStrength.value = style.strength;
105
+ hoverPulseMix.value = style.pulse ? 0 : 1;
106
+ invalidate();
107
+ }, [
108
+ hoverHiddenColor,
109
+ hoverHighlightMode,
110
+ hoverPulseMix,
111
+ hoverStrength,
112
+ hoverStyles,
113
+ hoverVisibleColor,
114
+ invalidate,
115
+ ]);
89
116
  // Build / rebuild the post-processing pipeline
90
117
  useEffect(() => {
91
- // Intentionally touch these so React/biome treat project switches and retry bumps
92
- // as explicit rebuild triggers instead of accidental extra dependencies.
93
- void projectId;
94
- void pipelineVersion;
95
118
  if (!(renderer && scene && camera)) {
119
+ console.warn('[viewer/post-processing] Skipping pipeline build — missing dependency.', {
120
+ hasRenderer: !!renderer,
121
+ hasScene: !!scene,
122
+ hasCamera: !!camera,
123
+ });
96
124
  return;
97
125
  }
126
+ console.log('[viewer/post-processing] Building pipeline', {
127
+ version: pipelineVersion,
128
+ ssgi: SSGI_PARAMS.enabled,
129
+ hoverHighlightMode,
130
+ projectId,
131
+ rendererCtor: renderer.constructor?.name,
132
+ });
98
133
  hasPipelineErrorRef.current = false;
99
- // WebGPU availability check: SSGI, denoise, and RenderPipeline are all
100
- // WebGPU-only APIs. When the browser falls back to WebGL2 (no
101
- // `navigator.gpu`, or the device couldn't be created), building the
102
- // pipeline either throws silently or produces a broken output where
103
- // the scene renders for a few frames and then goes black as the retry
104
- // loop fights the direct-render fallback path. Short-circuit here so
105
- // `useFrame` uses the direct `renderer.render(scene, camera)` path
106
- // exclusively and never attempts the TSL pipeline.
107
- const hasWebGPU = typeof navigator !== 'undefined' && 'gpu' in navigator;
108
- if (!hasWebGPU) {
109
- console.warn('[viewer] WebGPU unavailable — rendering without post-processing (SSGI, outlines, denoise).');
110
- hasPipelineErrorRef.current = true;
111
- renderPipelineRef.current = null;
112
- return;
113
- }
114
134
  // Clear outliner arrays synchronously to prevent stale Object3D refs
115
135
  // from the previous project leaking into the new pipeline's outline passes.
116
136
  const outliner = useViewer.getState().outliner;
@@ -188,13 +208,9 @@ const PostProcessingPasses = () => {
188
208
  .add(outlineNode.primaryHiddenEdge.mul(selectedHiddenColor))
189
209
  .mul(selectedStrength);
190
210
  // Hovered: blue visible, yellow hidden, pulsing
191
- const hoverVisibleColor = uniform(new Color(hoverHighlightMode === 'delete' ? 0xef_44_44 : 0x00_aa_ff));
192
- const hoverHiddenColor = uniform(new Color(hoverHighlightMode === 'delete' ? 0x99_1b_1b : 0xf3_ff_47));
193
- const hoverStrength = uniform(hoverHighlightMode === 'delete' ? 6 : 5);
194
211
  const pulsePeriod = uniform(3);
195
- const osc = hoverHighlightMode === 'delete'
196
- ? float(1)
197
- : oscSine(time.div(pulsePeriod).mul(2)).mul(0.5).add(0.5); // [ 0.5, 1.0 ]
212
+ const oscillating = oscSine(time.div(pulsePeriod).mul(2)).mul(0.5).add(0.5);
213
+ const osc = mix(oscillating, float(1), hoverPulseMix);
198
214
  const hoverOutline = outlineNode.secondaryVisibleEdge
199
215
  .mul(hoverVisibleColor)
200
216
  .add(outlineNode.secondaryHiddenEdge.mul(hoverHiddenColor))
@@ -206,10 +222,15 @@ const PostProcessingPasses = () => {
206
222
  renderPipeline.outputNode = finalOutput;
207
223
  renderPipelineRef.current = renderPipeline;
208
224
  retryCountRef.current = 0;
225
+ console.log('[viewer/post-processing] Pipeline built OK', { version: pipelineVersion });
209
226
  }
210
227
  catch (error) {
211
228
  hasPipelineErrorRef.current = true;
212
- console.error('[viewer] Failed to set up post-processing pipeline. Rendering without post FX.', error);
229
+ console.error('[viewer/post-processing] Failed to set up post-processing pipeline. Rendering without post FX.', {
230
+ version: pipelineVersion,
231
+ ssgi: SSGI_PARAMS.enabled,
232
+ rendererCtor: renderer.constructor?.name,
233
+ }, error);
213
234
  if (renderPipelineRef.current) {
214
235
  renderPipelineRef.current.dispose();
215
236
  }
@@ -221,7 +242,18 @@ const PostProcessingPasses = () => {
221
242
  }
222
243
  renderPipelineRef.current = null;
223
244
  };
224
- }, [renderer, scene, camera, hoverHighlightMode, zoneLayers, projectId, pipelineVersion]);
245
+ }, [
246
+ camera,
247
+ hoverHiddenColor,
248
+ hoverPulseMix,
249
+ hoverStrength,
250
+ hoverVisibleColor,
251
+ pipelineVersion,
252
+ projectId,
253
+ renderer,
254
+ scene,
255
+ zoneLayers,
256
+ ]);
225
257
  useFrame((_, delta) => {
226
258
  // Animate background colour toward the current theme target (same lerp as AnimatedBackground)
227
259
  bgTarget.current.set(useViewer.getState().theme === 'dark' ? DARK_BG : LIGHT_BG);
@@ -240,7 +272,7 @@ const PostProcessingPasses = () => {
240
272
  renderer.render(scene, camera);
241
273
  }
242
274
  catch (fallbackError) {
243
- console.error('[viewer] Fallback render failed.', fallbackError);
275
+ console.error('[viewer/post-processing] Fallback render failed.', fallbackError);
244
276
  }
245
277
  return;
246
278
  }
@@ -253,7 +285,11 @@ const PostProcessingPasses = () => {
253
285
  }
254
286
  catch (error) {
255
287
  hasPipelineErrorRef.current = true;
256
- console.error('[viewer] Post-processing render pass failed.', error);
288
+ console.error('[viewer/post-processing] Render pass failed.', {
289
+ retryCount: retryCountRef.current,
290
+ rendererCtor: renderer.constructor?.name,
291
+ error,
292
+ });
257
293
  if (renderPipelineRef.current) {
258
294
  renderPipelineRef.current.dispose();
259
295
  }
@@ -261,14 +297,14 @@ const PostProcessingPasses = () => {
261
297
  if (retryCountRef.current < MAX_PIPELINE_RETRIES) {
262
298
  // Auto-retry: schedule a pipeline rebuild if we haven't exceeded the retry limit
263
299
  retryCountRef.current++;
264
- console.warn(`[viewer] Scheduling post-processing rebuild (attempt ${retryCountRef.current}/${MAX_PIPELINE_RETRIES})`);
300
+ console.warn(`[viewer/post-processing] Scheduling pipeline rebuild (attempt ${retryCountRef.current}/${MAX_PIPELINE_RETRIES})`);
265
301
  if (rebuildTimeoutRef.current !== null) {
266
302
  clearTimeout(rebuildTimeoutRef.current);
267
303
  }
268
304
  rebuildTimeoutRef.current = setTimeout(requestPipelineRebuild, RETRY_DELAY_MS);
269
305
  }
270
306
  else {
271
- console.error('[viewer] Post-processing retries exhausted. Rendering without post FX for this session.');
307
+ console.error('[viewer/post-processing] Retries exhausted. Rendering without post FX for this session.');
272
308
  }
273
309
  }
274
310
  }, 1);
@@ -1 +1 @@
1
- {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAiRA,eAAO,MAAM,gBAAgB,+CA2E5B,CAAA"}
1
+ {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAoSA,eAAO,MAAM,gBAAgB,+CA4E5B,CAAA"}
@@ -82,6 +82,10 @@ const isNodeInZone = (node, levelId, zoneId) => {
82
82
  const item = node;
83
83
  return pointInPolygonWithTolerance(item.position[0], item.position[2], zone.polygon);
84
84
  }
85
+ if (node.type === 'column') {
86
+ const column = node;
87
+ return pointInPolygonWithTolerance(column.position[0], column.position[2], zone.polygon);
88
+ }
85
89
  if (node.type === 'wall') {
86
90
  const wall = node;
87
91
  const startIn = pointInPolygonWithTolerance(wall.start[0], wall.start[1], zone.polygon);
@@ -168,9 +172,20 @@ const getStrategy = () => {
168
172
  isValid: (node) => node.type === 'zone' && node.parentId === levelId,
169
173
  };
170
174
  }
171
- // Zone selected -> can select/hover contents (walls, items, slabs, ceilings, roofs, windows, doors)
175
+ // Zone selected -> can select/hover contents (walls, items, columns, slabs, ceilings, roofs, windows, doors)
172
176
  return {
173
- types: ['wall', 'fence', 'item', 'slab', 'ceiling', 'roof', 'roof-segment', 'window', 'door'],
177
+ types: [
178
+ 'wall',
179
+ 'fence',
180
+ 'item',
181
+ 'column',
182
+ 'slab',
183
+ 'ceiling',
184
+ 'roof',
185
+ 'roof-segment',
186
+ 'window',
187
+ 'door',
188
+ ],
174
189
  handleClick: (node, nativeEvent) => {
175
190
  let nodeToSelect = node;
176
191
  if (node.type === 'roof-segment' && node.parentId) {
@@ -199,6 +214,7 @@ const getStrategy = () => {
199
214
  'wall',
200
215
  'fence',
201
216
  'item',
217
+ 'column',
202
218
  'slab',
203
219
  'ceiling',
204
220
  'roof',
@@ -258,6 +274,7 @@ export const SelectionManager = () => {
258
274
  'wall',
259
275
  'fence',
260
276
  'item',
277
+ 'column',
261
278
  'slab',
262
279
  'ceiling',
263
280
  'roof',
@@ -1,4 +1,4 @@
1
- import { type BuildingEvent, type BuildingNode, type CeilingEvent, type CeilingNode, type DoorEvent, type DoorNode, type FenceEvent, type FenceNode, type ItemEvent, type ItemNode, type LevelEvent, type LevelNode, type RoofEvent, type RoofNode, type RoofSegmentEvent, type RoofSegmentNode, type SiteEvent, type SiteNode, type SlabEvent, type SlabNode, type StairEvent, type StairNode, type StairSegmentEvent, type StairSegmentNode, type WallEvent, type WallNode, type WindowEvent, type WindowNode, type ZoneEvent, type ZoneNode } from '@pascal-app/core';
1
+ import { type BuildingEvent, type BuildingNode, type CeilingEvent, type CeilingNode, type ColumnEvent, type ColumnNode, type DoorEvent, type DoorNode, type FenceEvent, type FenceNode, type ItemEvent, type ItemNode, type LevelEvent, type LevelNode, type RoofEvent, type RoofNode, type RoofSegmentEvent, type RoofSegmentNode, type SiteEvent, type SiteNode, type SlabEvent, type SlabNode, type SpawnEvent, type SpawnNode, type StairEvent, type StairNode, type StairSegmentEvent, type StairSegmentNode, type WallEvent, type WallNode, type WindowEvent, type WindowNode, type ZoneEvent, type ZoneNode } from '@pascal-app/core';
2
2
  import type { ThreeEvent } from '@react-three/fiber';
3
3
  type NodeConfig = {
4
4
  site: {
@@ -33,10 +33,18 @@ type NodeConfig = {
33
33
  node: SlabNode;
34
34
  event: SlabEvent;
35
35
  };
36
+ spawn: {
37
+ node: SpawnNode;
38
+ event: SpawnEvent;
39
+ };
36
40
  ceiling: {
37
41
  node: CeilingNode;
38
42
  event: CeilingEvent;
39
43
  };
44
+ column: {
45
+ node: ColumnNode;
46
+ event: ColumnEvent;
47
+ };
40
48
  roof: {
41
49
  node: RoofNode;
42
50
  event: RoofEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-node-events.d.ts","sourceRoot":"","sources":["../../src/hooks/use-node-events.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  export { default as Viewer } from './components/viewer';
2
- export { SSGI_PARAMS } from './components/viewer/post-processing';
2
+ export type { HoverStyle, HoverStyles } from './components/viewer/post-processing';
3
+ export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
3
4
  export { WalkthroughControls } from './components/viewer/walkthrough-controls';
4
5
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
5
6
  export { SCENE_LAYER, ZONE_LAYER } from './lib/layers';
6
- export { clearMaterialCache, createDefaultMaterial, createMaterial, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, } from './lib/materials';
7
+ export { applyMaterialPresetToMaterials, clearMaterialCache, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, glassMaterial, } from './lib/materials';
7
8
  export { mergedOutline } from './lib/merged-outline-node';
8
9
  export { default as useViewer } from './store/use-viewer';
9
10
  export { InteractiveSystem } from './systems/interactive/interactive-system';
10
11
  export { snapLevelsToTruePositions } from './systems/level/level-utils';
12
+ export { getRoofMaterialArray } from './systems/roof/roof-materials';
13
+ export { getStairBodyMaterials, getStairRailingMaterial } from './systems/stair/stair-materials';
14
+ export { getVisibleWallMaterials } from './systems/wall/wall-materials';
11
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,GAChB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAA;AAClF,OAAO,EACL,oBAAoB,EACpB,WAAW,GACZ,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACtD,OAAO,EACL,8BAA8B,EAC9B,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,aAAa,GACd,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAA"}
package/dist/index.js CHANGED
@@ -1,10 +1,13 @@
1
1
  export { default as Viewer } from './components/viewer';
2
- export { SSGI_PARAMS } from './components/viewer/post-processing';
2
+ export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
3
3
  export { WalkthroughControls } from './components/viewer/walkthrough-controls';
4
4
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
5
5
  export { SCENE_LAYER, ZONE_LAYER } from './lib/layers';
6
- export { clearMaterialCache, createDefaultMaterial, createMaterial, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, } from './lib/materials';
6
+ export { applyMaterialPresetToMaterials, clearMaterialCache, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, glassMaterial, } from './lib/materials';
7
7
  export { mergedOutline } from './lib/merged-outline-node';
8
8
  export { default as useViewer } from './store/use-viewer';
9
9
  export { InteractiveSystem } from './systems/interactive/interactive-system';
10
10
  export { snapLevelsToTruePositions } from './systems/level/level-utils';
11
+ export { getRoofMaterialArray } from './systems/roof/roof-materials';
12
+ export { getStairBodyMaterials, getStairRailingMaterial } from './systems/stair/stair-materials';
13
+ export { getVisibleWallMaterials } from './systems/wall/wall-materials';
@@ -1,5 +1,8 @@
1
1
  import { type MaterialPresetPayload, type MaterialSchema } from '@pascal-app/core';
2
2
  import * as THREE from 'three';
3
+ import { MeshStandardNodeMaterial } from 'three/webgpu';
4
+ export declare const baseMaterial: MeshStandardNodeMaterial;
5
+ export declare const glassMaterial: MeshStandardNodeMaterial;
3
6
  export declare function applyMaterialPresetToMaterials(materialInput: THREE.Material | THREE.Material[], preset: MaterialPresetPayload | null | undefined): void;
4
7
  export declare function createMaterialFromPreset(preset: MaterialPresetPayload): THREE.MeshStandardMaterial;
5
8
  export declare function createMaterialFromPresetRef(materialPreset?: string): THREE.MeshStandardMaterial | null;
@@ -1 +1 @@
1
- {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA2M9B,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,EAChD,MAAM,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,QAcjD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,GAAG,KAAK,CAAC,oBAAoB,CAWlG;AAED,wBAAgB,2BAA2B,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAItG;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,KAAK,CAAC,oBAAoB,CAsBpF;AAED,wBAAgB,qBAAqB,CACnC,KAAK,SAAY,EACjB,SAAS,SAAM,GACd,KAAK,CAAC,oBAAoB,CAO5B;AAED,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,uBAAuB,4BAOlC,CAAA;AACF,eAAO,MAAM,wBAAwB,4BAAyC,CAAA;AAC9E,eAAO,MAAM,qBAAqB,4BAAyC,CAAA;AAC3E,eAAO,MAAM,sBAAsB,4BAAwC,CAAA;AAE3E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAE9D;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAWzC"}
1
+ {"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,qBAAqB,EAE1B,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAEvD,eAAO,MAAM,YAAY,0BAIvB,CAAA;AAEF,eAAO,MAAM,aAAa,0BAOxB,CAAA;AAkNF,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,EAChD,MAAM,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,QAcjD;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,qBAAqB,GAC5B,KAAK,CAAC,oBAAoB,CAW5B;AAED,wBAAgB,2BAA2B,CACzC,cAAc,CAAC,EAAE,MAAM,GACtB,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAInC;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,KAAK,CAAC,oBAAoB,CAsBpF;AAED,wBAAgB,qBAAqB,CACnC,KAAK,SAAY,EACjB,SAAS,SAAM,GACd,KAAK,CAAC,oBAAoB,CAO5B;AAED,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,qBAAqB,4BAAwC,CAAA;AAC1E,eAAO,MAAM,uBAAuB,4BAOlC,CAAA;AACF,eAAO,MAAM,wBAAwB,4BAAyC,CAAA;AAC9E,eAAO,MAAM,qBAAqB,4BAAyC,CAAA;AAC3E,eAAO,MAAM,sBAAsB,4BAAwC,CAAA;AAE3E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAE9D;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAWzC"}
@@ -1,5 +1,19 @@
1
1
  import { getMaterialPresetByRef, resolveMaterial, } from '@pascal-app/core';
2
2
  import * as THREE from 'three';
3
+ import { MeshStandardNodeMaterial } from 'three/webgpu';
4
+ export const baseMaterial = new MeshStandardNodeMaterial({
5
+ color: '#f2f0ed',
6
+ roughness: 0.5,
7
+ metalness: 0.0,
8
+ });
9
+ export const glassMaterial = new MeshStandardNodeMaterial({
10
+ color: '#e0f2fe',
11
+ roughness: 0.05,
12
+ metalness: 0.0,
13
+ transparent: true,
14
+ opacity: 0.35,
15
+ side: THREE.DoubleSide,
16
+ });
3
17
  const sideMap = {
4
18
  front: THREE.FrontSide,
5
19
  back: THREE.BackSide,
@@ -45,8 +59,7 @@ function getTexture(material) {
45
59
  return texture;
46
60
  }
47
61
  function isStandardMaterial(material) {
48
- return (material instanceof THREE.MeshStandardMaterial ||
49
- material instanceof THREE.MeshPhysicalMaterial);
62
+ return (material instanceof THREE.MeshStandardMaterial || material instanceof THREE.MeshPhysicalMaterial);
50
63
  }
51
64
  function applyTextureProperties(texture, props, slot) {
52
65
  texture.wrapS = wrapMap[props.wrapS];
@@ -109,7 +122,7 @@ function queueTextureAssignment(material, slot, path, props) {
109
122
  return;
110
123
  }
111
124
  material[slot] = null;
112
- void loadPresetTexture(path, props, slot).then((texture) => {
125
+ loadPresetTexture(path, props, slot).then((texture) => {
113
126
  if (!texture)
114
127
  return;
115
128
  material[slot] = texture;
@@ -62,6 +62,8 @@ export declare class MergedOutlineNode extends TempNode {
62
62
  private readonly _compositeMatB;
63
63
  private readonly _cacheA;
64
64
  private readonly _cacheB;
65
+ private _wroteGroupALastFrame;
66
+ private _wroteGroupBLastFrame;
65
67
  private readonly _textureNodeA;
66
68
  private readonly _textureNodeB;
67
69
  constructor(scene: any, camera: any, params?: {
@@ -1 +1 @@
1
- {"version":3,"file":"merged-outline-node.d.ts","sourceRoot":"","sources":["../../src/lib/merged-outline-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merged-outline-node.d.ts","sourceRoot":"","sources":["../../src/lib/merged-outline-node.ts"],"names":[],"mappings":"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"}
@@ -120,6 +120,13 @@ export class MergedOutlineNode extends TempNode {
120
120
  _compositeMatB;
121
121
  _cacheA = new Set();
122
122
  _cacheB = new Set();
123
+ // Tracks whether either group rendered last frame. We use this to decide
124
+ // when it's safe to skip renderer state manipulation entirely — touching
125
+ // the renderer (resetRendererAndSceneState + setRenderTarget + clearColor)
126
+ // corrupts the FBO state on the WebGL2 backend (iOS Chrome fallback) and
127
+ // the subsequent scene render comes out blank.
128
+ _wroteGroupALastFrame = false;
129
+ _wroteGroupBLastFrame = false;
123
130
  _textureNodeA;
124
131
  _textureNodeB;
125
132
  constructor(scene, camera, params = {}) {
@@ -213,27 +220,40 @@ export class MergedOutlineNode extends TempNode {
213
220
  updateBefore(frame) {
214
221
  const hasPrimary = this.primaryObjects.length > 0;
215
222
  const hasSecondary = this.secondaryObjects.length > 0;
223
+ const hasAny = hasPrimary || hasSecondary;
224
+ // Fast-path: nothing to render and nothing was rendered last frame either,
225
+ // so there are no stale composites to clear. Touch nothing — on the WebGL2
226
+ // backend (iOS Chrome fallback) even an empty reset/setRenderTarget cycle
227
+ // corrupts the framebuffer state and the next scene render goes blank.
228
+ const needsCleanupA = !hasPrimary && this._wroteGroupALastFrame;
229
+ const needsCleanupB = !hasSecondary && this._wroteGroupBLastFrame;
230
+ if (!(hasAny || needsCleanupA || needsCleanupB)) {
231
+ return;
232
+ }
216
233
  const { renderer } = frame;
217
234
  const { camera, scene } = this;
218
235
  _rendererState = RendererUtils.resetRendererAndSceneState(renderer, scene, _rendererState);
219
236
  const size = renderer.getDrawingBufferSize(_size);
220
237
  this.setSize(size.width, size.height);
221
- // Clear composites for inactive groups so stale outlines don't persist on GPU.
222
- // Must happen inside resetRendererAndSceneState to avoid MSAA state corruption.
223
- if (!hasPrimary) {
238
+ // Clear composites for groups that just transitioned from "has content"
239
+ // to "empty" — without this, the previous outline lingers on the GPU.
240
+ if (needsCleanupA) {
224
241
  renderer.setRenderTarget(this._groupA.composite);
225
242
  renderer.clearColor();
243
+ this._wroteGroupALastFrame = false;
226
244
  }
227
- if (!hasSecondary) {
245
+ if (needsCleanupB) {
228
246
  renderer.setRenderTarget(this._groupB.composite);
229
247
  renderer.clearColor();
248
+ this._wroteGroupBLastFrame = false;
230
249
  }
231
- const hasAny = hasPrimary || hasSecondary;
232
250
  if (!hasAny) {
233
251
  RendererUtils.restoreRendererAndSceneState(renderer, scene, _rendererState);
234
252
  return;
235
253
  }
236
254
  renderer.setClearColor(0xff_ff_ff, 1);
255
+ this._wroteGroupALastFrame = hasPrimary;
256
+ this._wroteGroupBLastFrame = hasSecondary;
237
257
  if (hasPrimary)
238
258
  this._buildCache(this.primaryObjects, this._cacheA);
239
259
  if (hasSecondary)
@@ -440,17 +460,10 @@ export class MergedOutlineNode extends TempNode {
440
460
  }
441
461
  _buildCache(objects, cache) {
442
462
  for (const obj of objects) {
443
- if (!obj || !obj.traverse)
444
- continue;
445
- try {
446
- obj.traverse((child) => {
447
- if (child.isMesh || child.isSprite)
448
- cache.add(child);
449
- });
450
- }
451
- catch {
452
- // Skip objects that were disposed or removed from the scene graph
453
- }
463
+ obj.traverse((child) => {
464
+ if (child.isMesh || child.isSprite)
465
+ cache.add(child);
466
+ });
454
467
  }
455
468
  }
456
469
  }
@@ -14,8 +14,8 @@ type ViewerState = {
14
14
  selection: SelectionPath;
15
15
  previewSelectedIds: BaseNode['id'][];
16
16
  setPreviewSelectedIds: (ids: BaseNode['id'][]) => void;
17
- hoverHighlightMode: 'default' | 'delete';
18
- setHoverHighlightMode: (mode: 'default' | 'delete') => void;
17
+ hoverHighlightMode: string;
18
+ setHoverHighlightMode: (mode: string) => void;
19
19
  hoveredId: AnyNode['id'] | ZoneNode['id'] | null;
20
20
  setHoveredId: (id: AnyNode['id'] | ZoneNode['id'] | null) => void;
21
21
  cameraMode: 'perspective' | 'orthographic';
@@ -62,7 +62,7 @@ declare const useViewer: import("zustand").UseBoundStore<Omit<import("zustand").
62
62
  theme: "light" | "dark";
63
63
  unit: "metric" | "imperial";
64
64
  levelMode: "manual" | "stacked" | "exploded" | "solo";
65
- wallMode: "up" | "cutaway" | "down";
65
+ wallMode: "up" | "down" | "cutaway";
66
66
  projectPreferences: Record<string, {
67
67
  showScans?: boolean;
68
68
  showGuides?: boolean;
@@ -79,7 +79,7 @@ declare const useViewer: import("zustand").UseBoundStore<Omit<import("zustand").
79
79
  theme: "light" | "dark";
80
80
  unit: "metric" | "imperial";
81
81
  levelMode: "manual" | "stacked" | "exploded" | "solo";
82
- wallMode: "up" | "cutaway" | "down";
82
+ wallMode: "up" | "down" | "cutaway";
83
83
  projectPreferences: Record<string, {
84
84
  showScans?: boolean;
85
85
  showGuides?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"use-viewer.d.ts","sourceRoot":"","sources":["../../src/store/use-viewer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-viewer.d.ts","sourceRoot":"","sources":["../../src/store/use-viewer.ts"],"names":[],"mappings":"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"}
@@ -6,9 +6,9 @@ const useViewer = create()(persist((set) => ({
6
6
  previewSelectedIds: [],
7
7
  setPreviewSelectedIds: (ids) => set({ previewSelectedIds: ids }),
8
8
  hoverHighlightMode: 'default',
9
- setHoverHighlightMode: (mode) => set({ hoverHighlightMode: mode }),
9
+ setHoverHighlightMode: (mode) => set((state) => (state.hoverHighlightMode === mode ? state : { hoverHighlightMode: mode })),
10
10
  hoveredId: null,
11
- setHoveredId: (id) => set({ hoveredId: id }),
11
+ setHoveredId: (id) => set((state) => (state.hoveredId === id ? state : { hoveredId: id })),
12
12
  cameraMode: 'perspective',
13
13
  setCameraMode: (mode) => set({ cameraMode: mode }),
14
14
  theme: 'light',
@@ -0,0 +1,8 @@
1
+ import { type CeilingNode } from '@pascal-app/core';
2
+ import * as THREE from 'three';
3
+ export declare const CeilingSystem: () => null;
4
+ /**
5
+ * Generates flat ceiling geometry from polygon (no extrusion)
6
+ */
7
+ export declare function generateCeilingGeometry(ceilingNode: CeilingNode): THREE.BufferGeometry;
8
+ //# sourceMappingURL=ceiling-system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ceiling-system.d.ts","sourceRoot":"","sources":["../../../src/systems/ceiling/ceiling-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,WAAW,EAA2B,MAAM,kBAAkB,CAAA;AAE5F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAa9B,eAAO,MAAM,aAAa,YAuBzB,CAAA;AAqBD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,KAAK,CAAC,cAAc,CAgDtF"}