@pascal-app/viewer 0.7.0 → 0.9.1

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 (216) hide show
  1. package/dist/components/renderers/node-renderer.d.ts +1 -1
  2. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  3. package/dist/components/renderers/node-renderer.js +38 -22
  4. package/dist/components/renderers/parametric-node-renderer.d.ts +5 -0
  5. package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -0
  6. package/dist/components/renderers/parametric-node-renderer.js +34 -0
  7. package/dist/components/renderers/scene-renderer.d.ts +1 -1
  8. package/dist/components/renderers/scene-renderer.d.ts.map +1 -1
  9. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  10. package/dist/components/viewer/frame-limiter.js +5 -1
  11. package/dist/components/viewer/ground-occluder.d.ts +1 -1
  12. package/dist/components/viewer/ground-occluder.d.ts.map +1 -1
  13. package/dist/components/viewer/ground-occluder.js +12 -24
  14. package/dist/components/viewer/index.d.ts +38 -1
  15. package/dist/components/viewer/index.d.ts.map +1 -1
  16. package/dist/components/viewer/index.js +183 -60
  17. package/dist/components/viewer/lights.d.ts +1 -1
  18. package/dist/components/viewer/lights.d.ts.map +1 -1
  19. package/dist/components/viewer/lights.js +170 -43
  20. package/dist/components/viewer/perf-monitor.d.ts +1 -1
  21. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  22. package/dist/components/viewer/perf-monitor.js +99 -11
  23. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  24. package/dist/components/viewer/post-processing.js +217 -61
  25. package/dist/components/viewer/registered-systems.d.ts +12 -0
  26. package/dist/components/viewer/registered-systems.d.ts.map +1 -0
  27. package/dist/components/viewer/registered-systems.js +47 -0
  28. package/dist/components/viewer/scene-bvh.d.ts +17 -0
  29. package/dist/components/viewer/scene-bvh.d.ts.map +1 -0
  30. package/dist/components/viewer/scene-bvh.js +94 -0
  31. package/dist/components/viewer/selection-manager.d.ts +1 -1
  32. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  33. package/dist/components/viewer/selection-manager.js +20 -5
  34. package/dist/components/viewer/viewer-camera.d.ts +1 -1
  35. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  36. package/dist/components/viewer/walkthrough-controls.d.ts +1 -1
  37. package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
  38. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  39. package/dist/hooks/use-node-events.d.ts +5 -73
  40. package/dist/hooks/use-node-events.d.ts.map +1 -1
  41. package/dist/hooks/use-node-events.js +19 -7
  42. package/dist/index.d.ts +36 -4
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +67 -3
  45. package/dist/lib/csg-utils.d.ts +16 -0
  46. package/dist/lib/csg-utils.d.ts.map +1 -0
  47. package/dist/lib/csg-utils.js +33 -0
  48. package/dist/lib/drawable-geometry.d.ts +21 -0
  49. package/dist/lib/drawable-geometry.d.ts.map +1 -0
  50. package/dist/lib/drawable-geometry.js +22 -0
  51. package/dist/lib/edge-style.d.ts +3 -0
  52. package/dist/lib/edge-style.d.ts.map +1 -0
  53. package/dist/lib/edge-style.js +11 -0
  54. package/dist/lib/gpu-perf.d.ts +4 -0
  55. package/dist/lib/gpu-perf.d.ts.map +1 -0
  56. package/dist/lib/gpu-perf.js +23 -0
  57. package/dist/lib/ink-edges.d.ts +9 -0
  58. package/dist/lib/ink-edges.d.ts.map +1 -0
  59. package/dist/lib/ink-edges.js +43 -0
  60. package/dist/lib/isolation.d.ts +39 -0
  61. package/dist/lib/isolation.d.ts.map +1 -0
  62. package/dist/lib/isolation.js +103 -0
  63. package/dist/lib/layers.d.ts +18 -0
  64. package/dist/lib/layers.d.ts.map +1 -1
  65. package/dist/lib/layers.js +18 -0
  66. package/dist/lib/materials.d.ts +25 -15
  67. package/dist/lib/materials.d.ts.map +1 -1
  68. package/dist/lib/materials.js +277 -63
  69. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  70. package/dist/lib/merged-outline-node.js +11 -11
  71. package/dist/lib/polygon-union.d.ts +4 -0
  72. package/dist/lib/polygon-union.d.ts.map +1 -0
  73. package/dist/lib/polygon-union.js +289 -0
  74. package/dist/lib/polygon-union.test.d.ts +2 -0
  75. package/dist/lib/polygon-union.test.d.ts.map +1 -0
  76. package/dist/lib/polygon-union.test.js +105 -0
  77. package/dist/lib/scene-themes.d.ts +29 -0
  78. package/dist/lib/scene-themes.d.ts.map +1 -0
  79. package/dist/lib/scene-themes.js +193 -0
  80. package/dist/store/use-viewer.d.ts +42 -4
  81. package/dist/store/use-viewer.d.ts.map +1 -1
  82. package/dist/store/use-viewer.js +26 -3
  83. package/dist/systems/ceiling/ceiling-system.d.ts +6 -2
  84. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  85. package/dist/systems/ceiling/ceiling-system.js +62 -12
  86. package/dist/systems/door/door-system.d.ts.map +1 -1
  87. package/dist/systems/door/door-system.js +373 -22
  88. package/dist/systems/elevator/elevator-interaction-system.d.ts +2 -0
  89. package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -0
  90. package/dist/systems/elevator/elevator-interaction-system.js +62 -0
  91. package/dist/systems/fence/fence-system.d.ts +3 -0
  92. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  93. package/dist/systems/fence/fence-system.js +10 -6
  94. package/dist/systems/floor-elevation/floor-elevation-system.d.ts +20 -0
  95. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -0
  96. package/dist/systems/floor-elevation/floor-elevation-system.js +78 -0
  97. package/dist/systems/geometry/geometry-system.d.ts +34 -0
  98. package/dist/systems/geometry/geometry-system.d.ts.map +1 -0
  99. package/dist/systems/geometry/geometry-system.js +279 -0
  100. package/dist/systems/guide/guide-system.d.ts.map +1 -1
  101. package/dist/systems/guide/guide-system.js +1 -26
  102. package/dist/systems/interactive/interactive-system.d.ts +1 -1
  103. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  104. package/dist/systems/item/item-system.d.ts +7 -0
  105. package/dist/systems/item/item-system.d.ts.map +1 -1
  106. package/dist/systems/item/item-system.js +8 -11
  107. package/dist/systems/item-light/item-light-system.d.ts +1 -1
  108. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  109. package/dist/systems/item-light/item-light-system.js +18 -5
  110. package/dist/systems/roof/roof-materials.d.ts +3 -2
  111. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  112. package/dist/systems/roof/roof-materials.js +38 -14
  113. package/dist/systems/roof/roof-system.d.ts +27 -0
  114. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  115. package/dist/systems/roof/roof-system.js +411 -71
  116. package/dist/systems/scan/scan-system.d.ts.map +1 -1
  117. package/dist/systems/scan/scan-system.js +1 -26
  118. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  119. package/dist/systems/slab/slab-system.js +167 -49
  120. package/dist/systems/slab/slab-system.test.d.ts +2 -0
  121. package/dist/systems/slab/slab-system.test.d.ts.map +1 -0
  122. package/dist/systems/slab/slab-system.test.js +62 -0
  123. package/dist/systems/stair/stair-materials.d.ts +4 -3
  124. package/dist/systems/stair/stair-materials.d.ts.map +1 -1
  125. package/dist/systems/stair/stair-materials.js +30 -15
  126. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  127. package/dist/systems/stair/stair-system.js +58 -71
  128. package/dist/systems/surface-hole-geometry.d.ts +3 -0
  129. package/dist/systems/surface-hole-geometry.d.ts.map +1 -0
  130. package/dist/systems/surface-hole-geometry.js +4 -0
  131. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  132. package/dist/systems/wall/wall-cutout.js +18 -2
  133. package/dist/systems/wall/wall-materials.d.ts +4 -3
  134. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  135. package/dist/systems/wall/wall-materials.js +52 -28
  136. package/dist/systems/wall/wall-system.d.ts +1 -1
  137. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  138. package/dist/systems/wall/wall-system.js +179 -31
  139. package/dist/systems/window/window-system.d.ts.map +1 -1
  140. package/dist/systems/window/window-system.js +71 -7
  141. package/package.json +4 -5
  142. package/dist/components/renderers/building/building-renderer.d.ts +0 -5
  143. package/dist/components/renderers/building/building-renderer.d.ts.map +0 -1
  144. package/dist/components/renderers/building/building-renderer.js +0 -11
  145. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts +0 -5
  146. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +0 -1
  147. package/dist/components/renderers/ceiling/ceiling-renderer.js +0 -58
  148. package/dist/components/renderers/column/column-renderer.d.ts +0 -5
  149. package/dist/components/renderers/column/column-renderer.d.ts.map +0 -1
  150. package/dist/components/renderers/column/column-renderer.js +0 -594
  151. package/dist/components/renderers/door/door-renderer.d.ts +0 -5
  152. package/dist/components/renderers/door/door-renderer.d.ts.map +0 -1
  153. package/dist/components/renderers/door/door-renderer.js +0 -16
  154. package/dist/components/renderers/fence/fence-renderer.d.ts +0 -5
  155. package/dist/components/renderers/fence/fence-renderer.d.ts.map +0 -1
  156. package/dist/components/renderers/fence/fence-renderer.js +0 -29
  157. package/dist/components/renderers/guide/guide-renderer.d.ts +0 -5
  158. package/dist/components/renderers/guide/guide-renderer.d.ts.map +0 -1
  159. package/dist/components/renderers/guide/guide-renderer.js +0 -38
  160. package/dist/components/renderers/item/item-renderer.d.ts +0 -5
  161. package/dist/components/renderers/item/item-renderer.d.ts.map +0 -1
  162. package/dist/components/renderers/item/item-renderer.js +0 -172
  163. package/dist/components/renderers/level/level-renderer.d.ts +0 -5
  164. package/dist/components/renderers/level/level-renderer.d.ts.map +0 -1
  165. package/dist/components/renderers/level/level-renderer.js +0 -11
  166. package/dist/components/renderers/roof/roof-materials.d.ts +0 -4
  167. package/dist/components/renderers/roof/roof-materials.d.ts.map +0 -1
  168. package/dist/components/renderers/roof/roof-materials.js +0 -16
  169. package/dist/components/renderers/roof/roof-renderer.d.ts +0 -5
  170. package/dist/components/renderers/roof/roof-renderer.d.ts.map +0 -1
  171. package/dist/components/renderers/roof/roof-renderer.js +0 -32
  172. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts +0 -5
  173. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +0 -1
  174. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +0 -40
  175. package/dist/components/renderers/scan/scan-renderer.d.ts +0 -5
  176. package/dist/components/renderers/scan/scan-renderer.d.ts.map +0 -1
  177. package/dist/components/renderers/scan/scan-renderer.js +0 -54
  178. package/dist/components/renderers/site/site-renderer.d.ts +0 -5
  179. package/dist/components/renderers/site/site-renderer.d.ts.map +0 -1
  180. package/dist/components/renderers/site/site-renderer.js +0 -106
  181. package/dist/components/renderers/slab/slab-renderer.d.ts +0 -5
  182. package/dist/components/renderers/slab/slab-renderer.d.ts.map +0 -1
  183. package/dist/components/renderers/slab/slab-renderer.js +0 -58
  184. package/dist/components/renderers/spawn/spawn-renderer.d.ts +0 -5
  185. package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +0 -1
  186. package/dist/components/renderers/spawn/spawn-renderer.js +0 -32
  187. package/dist/components/renderers/stair/stair-renderer.d.ts +0 -5
  188. package/dist/components/renderers/stair/stair-renderer.d.ts.map +0 -1
  189. package/dist/components/renderers/stair/stair-renderer.js +0 -603
  190. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts +0 -5
  191. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +0 -1
  192. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +0 -32
  193. package/dist/components/renderers/wall/wall-renderer.d.ts +0 -5
  194. package/dist/components/renderers/wall/wall-renderer.d.ts.map +0 -1
  195. package/dist/components/renderers/wall/wall-renderer.js +0 -16
  196. package/dist/components/renderers/window/window-renderer.d.ts +0 -5
  197. package/dist/components/renderers/window/window-renderer.d.ts.map +0 -1
  198. package/dist/components/renderers/window/window-renderer.js +0 -21
  199. package/dist/components/renderers/zone/zone-renderer.d.ts +0 -5
  200. package/dist/components/renderers/zone/zone-renderer.d.ts.map +0 -1
  201. package/dist/components/renderers/zone/zone-renderer.js +0 -181
  202. package/dist/lib/suppress-three-clock-warning.d.ts +0 -25
  203. package/dist/lib/suppress-three-clock-warning.d.ts.map +0 -1
  204. package/dist/lib/suppress-three-clock-warning.js +0 -51
  205. package/dist/systems/export/export-system.d.ts +0 -2
  206. package/dist/systems/export/export-system.d.ts.map +0 -1
  207. package/dist/systems/export/export-system.js +0 -60
  208. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts +0 -14
  209. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.d.ts.map +0 -1
  210. package/dist/systems/item-mesh-metadata/compute-item-mesh-metadata.js +0 -155
  211. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts +0 -6
  212. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.d.ts.map +0 -1
  213. package/dist/systems/item-mesh-metadata/item-mesh-metadata-system.js +0 -75
  214. package/dist/systems/item-mesh-metadata/sync-request.d.ts +0 -7
  215. package/dist/systems/item-mesh-metadata/sync-request.d.ts.map +0 -1
  216. package/dist/systems/item-mesh-metadata/sync-request.js +0 -25
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { emitter, pointInPolygon, sceneRegistry, useScene, } from '@pascal-app/core';
3
+ import { emitter, getSelectableKinds, pointInPolygon, sceneRegistry, useScene, } from '@pascal-app/core';
4
4
  import { useThree } from '@react-three/fiber';
5
5
  import { useEffect, useRef } from 'react';
6
6
  import { Vector3 } from 'three';
@@ -236,6 +236,12 @@ export const SelectionManager = () => {
236
236
  const strategy = getStrategy();
237
237
  if (!strategy)
238
238
  return;
239
+ // Ceilings are selected via their floor-plan helper and the
240
+ // boundary-editor vertex handles, never via a direct 3D click on
241
+ // the polygon. Skipping selection routing here means a click on a
242
+ // ceiling falls through to the item / wall / floor below it.
243
+ if (event.node.type === 'ceiling')
244
+ return;
239
245
  if (strategy.isValid(event.node)) {
240
246
  event.stopPropagation();
241
247
  if (event.node.type === 'slab') {
@@ -249,6 +255,8 @@ export const SelectionManager = () => {
249
255
  const strategy = getStrategy();
250
256
  if (!strategy)
251
257
  return;
258
+ if (event.node.type === 'ceiling')
259
+ return;
252
260
  if (strategy.isValid(event.node)) {
253
261
  event.stopPropagation();
254
262
  useViewer.setState({ hoveredId: null });
@@ -258,6 +266,8 @@ export const SelectionManager = () => {
258
266
  const strategy = getStrategy();
259
267
  if (!strategy)
260
268
  return;
269
+ if (event.node.type === 'ceiling')
270
+ return;
261
271
  if (!strategy.isValid(event.node))
262
272
  return;
263
273
  event.stopPropagation();
@@ -266,7 +276,9 @@ export const SelectionManager = () => {
266
276
  // Clear hover immediately after clicking on building/level/zone
267
277
  useViewer.setState({ hoveredId: null });
268
278
  };
269
- // Subscribe to all node types
279
+ // Subscribe to all node types. Hardcoded kinds + registry-supplied kinds
280
+ // (any NodeDefinition declaring `capabilities.selectable`). Phase 6
281
+ // collapses these into a single registry-driven list.
270
282
  const allTypes = [
271
283
  'building',
272
284
  'level',
@@ -282,13 +294,15 @@ export const SelectionManager = () => {
282
294
  'window',
283
295
  'door',
284
296
  ];
285
- for (const type of allTypes) {
297
+ const registryKinds = getSelectableKinds().filter((k) => !allTypes.includes(k));
298
+ const subscribedKinds = [...allTypes, ...registryKinds];
299
+ for (const type of subscribedKinds) {
286
300
  emitter.on(`${type}:enter`, onEnter);
287
301
  emitter.on(`${type}:leave`, onLeave);
288
302
  emitter.on(`${type}:click`, onClick);
289
303
  }
290
304
  return () => {
291
- for (const type of allTypes) {
305
+ for (const type of subscribedKinds) {
292
306
  emitter.off(`${type}:enter`, onEnter);
293
307
  emitter.off(`${type}:leave`, onLeave);
294
308
  emitter.off(`${type}:click`, onClick);
@@ -302,7 +316,8 @@ const PointerMissedHandler = ({ clickHandledRef, }) => {
302
316
  useEffect(() => {
303
317
  const handleClick = (event) => {
304
318
  // Only handle left clicks
305
- if (useViewer.getState().cameraDragging)
319
+ const viewerState = useViewer.getState();
320
+ if (viewerState.cameraDragging || viewerState.inputDragging)
306
321
  return;
307
322
  if (event.button !== 0)
308
323
  return;
@@ -1,2 +1,2 @@
1
- export declare const ViewerCamera: () => import("react/jsx-runtime").JSX.Element;
1
+ export declare const ViewerCamera: () => import("react").JSX.Element;
2
2
  //# sourceMappingURL=viewer-camera.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewer-camera.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/viewer-camera.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,+CAQxB,CAAA"}
1
+ {"version":3,"file":"viewer-camera.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/viewer-camera.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,mCAQxB,CAAA"}
@@ -1,2 +1,2 @@
1
- export declare const WalkthroughControls: () => import("react/jsx-runtime").JSX.Element | null;
1
+ export declare const WalkthroughControls: () => import("react").JSX.Element | null;
2
2
  //# sourceMappingURL=walkthrough-controls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"walkthrough-controls.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/walkthrough-controls.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,mBAAmB,sDAwH/B,CAAA"}
1
+ {"version":3,"file":"walkthrough-controls.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/walkthrough-controls.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,mBAAmB,0CAwH/B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-gltf-ktx2.d.ts","sourceRoot":"","sources":["../../src/hooks/use-gltf-ktx2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAU3C,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,OAAO,OAAO,CA2B5D,CAAA;AACD,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"use-gltf-ktx2.d.ts","sourceRoot":"","sources":["../../src/hooks/use-gltf-ktx2.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAU3C,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,OAAO,OAAO,CA2B5D,CAAA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1,77 +1,9 @@
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';
1
+ import { type AnyNode, type AnyNodeType } from '@pascal-app/core';
2
2
  import type { ThreeEvent } from '@react-three/fiber';
3
- type NodeConfig = {
4
- site: {
5
- node: SiteNode;
6
- event: SiteEvent;
7
- };
8
- item: {
9
- node: ItemNode;
10
- event: ItemEvent;
11
- };
12
- wall: {
13
- node: WallNode;
14
- event: WallEvent;
15
- };
16
- fence: {
17
- node: FenceNode;
18
- event: FenceEvent;
19
- };
20
- building: {
21
- node: BuildingNode;
22
- event: BuildingEvent;
23
- };
24
- level: {
25
- node: LevelNode;
26
- event: LevelEvent;
27
- };
28
- zone: {
29
- node: ZoneNode;
30
- event: ZoneEvent;
31
- };
32
- slab: {
33
- node: SlabNode;
34
- event: SlabEvent;
35
- };
36
- spawn: {
37
- node: SpawnNode;
38
- event: SpawnEvent;
39
- };
40
- ceiling: {
41
- node: CeilingNode;
42
- event: CeilingEvent;
43
- };
44
- column: {
45
- node: ColumnNode;
46
- event: ColumnEvent;
47
- };
48
- roof: {
49
- node: RoofNode;
50
- event: RoofEvent;
51
- };
52
- 'roof-segment': {
53
- node: RoofSegmentNode;
54
- event: RoofSegmentEvent;
55
- };
56
- stair: {
57
- node: StairNode;
58
- event: StairEvent;
59
- };
60
- 'stair-segment': {
61
- node: StairSegmentNode;
62
- event: StairSegmentEvent;
63
- };
64
- window: {
65
- node: WindowNode;
66
- event: WindowEvent;
67
- };
68
- door: {
69
- node: DoorNode;
70
- event: DoorEvent;
71
- };
72
- };
73
- type NodeType = keyof NodeConfig;
74
- export declare function useNodeEvents<T extends NodeType>(node: NodeConfig[T]['node'], type: T): {
3
+ type NodeByKind<K extends AnyNodeType> = Extract<AnyNode, {
4
+ type: K;
5
+ }>;
6
+ export declare function useNodeEvents<K extends AnyNodeType>(node: NodeByKind<K>, type: K): {
75
7
  onPointerDown: (e: ThreeEvent<PointerEvent>) => void;
76
8
  onPointerUp: (e: ThreeEvent<PointerEvent>) => void;
77
9
  onClick: (e: ThreeEvent<PointerEvent>) => void;
@@ -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":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAQpD,KAAK,UAAU,CAAC,CAAC,SAAS,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAA;AAEtE,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;uBAgC1D,UAAU,CAAC,YAAY,CAAC;qBAK1B,UAAU,CAAC,YAAY,CAAC;iBAQ5B,UAAU,CAAC,YAAY,CAAC;wBAIjB,UAAU,CAAC,YAAY,CAAC;wBAIxB,UAAU,CAAC,YAAY,CAAC;uBAIzB,UAAU,CAAC,YAAY,CAAC;uBAIxB,UAAU,CAAC,YAAY,CAAC;uBAIxB,UAAU,CAAC,YAAY,CAAC;EAK9C"}
@@ -14,18 +14,30 @@ export function useNodeEvents(node, type) {
14
14
  stopPropagation: () => e.stopPropagation(),
15
15
  nativeEvent: e,
16
16
  };
17
+ // `emitter.emit` is typed over a fixed union of `${kind}:${suffix}`
18
+ // keys; the `as never` cast lets us emit a kind-specific payload
19
+ // through that generic surface without enumerating every kind.
17
20
  emitter.emit(eventKey, payload);
18
21
  };
22
+ // Suppress node pointer events while an interaction drag is in
23
+ // progress. `cameraDragging` covers orbit/pan/dolly; `inputDragging`
24
+ // covers host-driven drags (editor handle arrows etc.). Without
25
+ // this, the synthesized click on pointerup would reroute selection
26
+ // to whatever mesh the cursor lands on at release.
27
+ const isInteractionActive = () => {
28
+ const s = useViewer.getState();
29
+ return s.cameraDragging || s.inputDragging;
30
+ };
19
31
  return {
20
32
  onPointerDown: (e) => {
21
- if (useViewer.getState().cameraDragging)
33
+ if (isInteractionActive())
22
34
  return;
23
35
  if (e.button !== 0)
24
36
  return;
25
37
  emit('pointerdown', e);
26
38
  },
27
39
  onPointerUp: (e) => {
28
- if (useViewer.getState().cameraDragging)
40
+ if (isInteractionActive())
29
41
  return;
30
42
  if (e.button !== 0)
31
43
  return;
@@ -39,27 +51,27 @@ export function useNodeEvents(node, type) {
39
51
  // This prevents double-clicks from firing twice.
40
52
  },
41
53
  onPointerEnter: (e) => {
42
- if (useViewer.getState().cameraDragging)
54
+ if (isInteractionActive())
43
55
  return;
44
56
  emit('enter', e);
45
57
  },
46
58
  onPointerLeave: (e) => {
47
- if (useViewer.getState().cameraDragging)
59
+ if (isInteractionActive())
48
60
  return;
49
61
  emit('leave', e);
50
62
  },
51
63
  onPointerMove: (e) => {
52
- if (useViewer.getState().cameraDragging)
64
+ if (isInteractionActive())
53
65
  return;
54
66
  emit('move', e);
55
67
  },
56
68
  onDoubleClick: (e) => {
57
- if (useViewer.getState().cameraDragging)
69
+ if (isInteractionActive())
58
70
  return;
59
71
  emit('double-click', e);
60
72
  },
61
73
  onContextMenu: (e) => {
62
- if (useViewer.getState().cameraDragging)
74
+ if (isInteractionActive())
63
75
  return;
64
76
  emit('context-menu', e);
65
77
  },
package/dist/index.d.ts CHANGED
@@ -1,15 +1,47 @@
1
- export { default as Viewer } from './components/viewer';
1
+ export type { SurfaceRole } from '@pascal-app/core';
2
+ export { ErrorBoundary } from './components/error-boundary';
3
+ export { NodeRenderer } from './components/renderers/node-renderer';
4
+ export { default as Viewer, type ViewerHandle } from './components/viewer';
2
5
  export type { HoverStyle, HoverStyles } from './components/viewer/post-processing';
3
6
  export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
4
7
  export { WalkthroughControls } from './components/viewer/walkthrough-controls';
8
+ export { useAssetUrl } from './hooks/use-asset-url';
9
+ export { useGLTFKTX2 } from './hooks/use-gltf-ktx2';
10
+ export { useNodeEvents } from './hooks/use-node-events';
5
11
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
6
- export { SCENE_LAYER, ZONE_LAYER } from './lib/layers';
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, } from './lib/materials';
12
+ export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
13
+ export type { EdgeMode } from './lib/edge-style';
14
+ export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, } from './lib/isolation';
15
+ export { GRID_LAYER, OVERLAY_LAYER, SCENE_LAYER, ZONE_LAYER } from './lib/layers';
16
+ export { applyMaterialPresetToMaterials, BLUEPRINT_PALETTE, baseMaterial, CLAY_PALETTE, type ColorPreset, clearMaterialCache, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SHELF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_STAIR_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, glassMaterial, MONO_PALETTE, PRESET_PALETTES, type RenderShading, resolveSurfaceColor, WHITE_PALETTE, } from './lib/materials';
8
17
  export { mergedOutline } from './lib/merged-outline-node';
18
+ export { unionPolygons } from './lib/polygon-union';
19
+ export { getSceneTheme, SCENE_THEME_IDS, SCENE_THEMES, type SceneTheme, } from './lib/scene-themes';
20
+ export { useItemLightPool } from './store/use-item-light-pool';
9
21
  export { default as useViewer } from './store/use-viewer';
22
+ export { CeilingSystem } from './systems/ceiling/ceiling-system';
23
+ export { createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, } from './systems/column/column-geometry';
24
+ export { DoorAnimationSystem } from './systems/door/door-animation-system';
25
+ export { DoorSystem } from './systems/door/door-system';
26
+ export { ElevatorInteractionSystem } from './systems/elevator/elevator-interaction-system';
27
+ export { FenceSystem, generateFenceGeometry } from './systems/fence/fence-system';
28
+ export { FloorElevationSystem } from './systems/floor-elevation/floor-elevation-system';
29
+ export { GuideSystem } from './systems/guide/guide-system';
10
30
  export { InteractiveSystem } from './systems/interactive/interactive-system';
31
+ export { ItemSystem } from './systems/item/item-system';
32
+ export { ItemLightSystem } from './systems/item-light/item-light-system';
33
+ export { LevelSystem } from './systems/level/level-system';
11
34
  export { snapLevelsToTruePositions } from './systems/level/level-utils';
12
35
  export { getRoofMaterialArray } from './systems/roof/roof-materials';
13
- export { getStairBodyMaterials, getStairRailingMaterial } from './systems/stair/stair-materials';
36
+ export { getRoofOuterSurfaceFrameAtPoint, getRoofSegmentBrushes, mapRoofGroupMaterialIndex, ROOF_MATERIAL_SLOT_COUNT, RoofSystem, remapRoofShellFaces, roofCsgDummyMats, type SurfaceFrame, } from './systems/roof/roof-system';
37
+ export { ScanSystem } from './systems/scan/scan-system';
38
+ export { generateSlabGeometry, SlabSystem } from './systems/slab/slab-system';
39
+ export { getStairBodyMaterials, getStairRailingMaterial, getStraightStairSegmentBodyMaterials, type StairBodyMaterials, } from './systems/stair/stair-materials';
40
+ export { StairSystem } from './systems/stair/stair-system';
41
+ export { WallCutout } from './systems/wall/wall-cutout';
14
42
  export { getVisibleWallMaterials } from './systems/wall/wall-materials';
43
+ export { WallSystem } from './systems/wall/wall-system';
44
+ export { WindowAnimationSystem } from './systems/window/window-animation-system';
45
+ export { WindowSystem } from './systems/window/window-system';
46
+ export { ZoneSystem } from './systems/zone/zone-system';
15
47
  //# 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,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,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;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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,13 +1,77 @@
1
+ // `NodeRenderer` is the recursive dispatch component used by parent
2
+ // renderers (wall renders doors/windows, slab renders hosted items).
3
+ // Public so registry-driven kinds can compose children without reaching
4
+ // into viewer's internal paths.
5
+ export { ErrorBoundary } from './components/error-boundary';
6
+ // Stage A wrap-exports for the rest of the kinds — `@pascal-app/nodes`
7
+ // registers each via `def.renderer` (and `def.system` when present)
8
+ // Generic dispatch component used by recursive renderers (e.g. level →
9
+ // children, building → children). The per-kind renderers live in
10
+ // `@pascal-app/nodes/<kind>/renderer.tsx` and are loaded by the registry
11
+ // — no per-kind re-exports needed.
12
+ export { NodeRenderer } from './components/renderers/node-renderer';
1
13
  export { default as Viewer } from './components/viewer';
2
14
  export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
3
15
  export { WalkthroughControls } from './components/viewer/walkthrough-controls';
16
+ export { useAssetUrl } from './hooks/use-asset-url';
17
+ export { useGLTFKTX2 } from './hooks/use-gltf-ktx2';
18
+ export { useNodeEvents } from './hooks/use-node-events';
4
19
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
5
- export { SCENE_LAYER, ZONE_LAYER } from './lib/layers';
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, } from './lib/materials';
20
+ // CSG primitives — used by chimney's roof-trim and other kinds whose
21
+ // geometry subtracts pieces against their host. Lives in viewer
22
+ // because three-bvh-csg / three-mesh-bvh are viewer-only deps.
23
+ export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
24
+ export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, } from './lib/isolation';
25
+ export { GRID_LAYER, OVERLAY_LAYER, SCENE_LAYER, ZONE_LAYER } from './lib/layers';
26
+ export { applyMaterialPresetToMaterials, BLUEPRINT_PALETTE, baseMaterial, CLAY_PALETTE, clearMaterialCache, createDefaultMaterial, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, DEFAULT_CEILING_MATERIAL, DEFAULT_DOOR_MATERIAL, DEFAULT_ROOF_MATERIAL, DEFAULT_SHELF_MATERIAL, DEFAULT_SLAB_MATERIAL, DEFAULT_STAIR_MATERIAL, DEFAULT_WALL_MATERIAL, DEFAULT_WINDOW_MATERIAL, disposeMaterial, glassMaterial, MONO_PALETTE, PRESET_PALETTES, resolveSurfaceColor, WHITE_PALETTE, } from './lib/materials';
7
27
  export { mergedOutline } from './lib/merged-outline-node';
28
+ export { unionPolygons } from './lib/polygon-union';
29
+ export { getSceneTheme, SCENE_THEME_IDS, SCENE_THEMES, } from './lib/scene-themes';
30
+ export { useItemLightPool } from './store/use-item-light-pool';
8
31
  export { default as useViewer } from './store/use-viewer';
32
+ export { CeilingSystem } from './systems/ceiling/ceiling-system';
33
+ export { createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, } from './systems/column/column-geometry';
34
+ export { DoorAnimationSystem } from './systems/door/door-animation-system';
35
+ export { DoorSystem } from './systems/door/door-system';
36
+ export { ElevatorInteractionSystem } from './systems/elevator/elevator-interaction-system';
37
+ // Fence system follows the wall re-export pattern — composed into the
38
+ // registry-driven fence definition's `def.system`. Removed in Phase 6
39
+ // alongside the legacy fence mount point.
40
+ export { FenceSystem, generateFenceGeometry } from './systems/fence/fence-system';
41
+ // Generic floor-elevation system. Lifts the rendered mesh of any kind
42
+ // whose definition declares `capabilities.floorPlaced` by the slab
43
+ // elevation under its footprint. Replaces the per-kind elevation block
44
+ // that used to live inside `ItemSystem`.
45
+ export { FloorElevationSystem } from './systems/floor-elevation/floor-elevation-system';
46
+ export { GuideSystem } from './systems/guide/guide-system';
9
47
  export { InteractiveSystem } from './systems/interactive/interactive-system';
48
+ // Item systems for the registry-driven item definition. ItemSystem
49
+ // applies attachTo-driven transforms each frame; ItemLightSystem
50
+ // manages item-mounted light sources.
51
+ export { ItemSystem } from './systems/item/item-system';
52
+ export { ItemLightSystem } from './systems/item-light/item-light-system';
53
+ export { LevelSystem } from './systems/level/level-system';
10
54
  export { snapLevelsToTruePositions } from './systems/level/level-utils';
11
55
  export { getRoofMaterialArray } from './systems/roof/roof-materials';
12
- export { getStairBodyMaterials, getStairRailingMaterial } from './systems/stair/stair-materials';
56
+ // Generic roof-segment primitives. Kinds that compose CSG against
57
+ // the roof shell (chimney's self-trim, dormer's virtual-segment cut)
58
+ // read these through the public surface. No kind-specific helpers
59
+ // belong here — those live in `@pascal-app/nodes/<kind>/`.
60
+ export { getRoofOuterSurfaceFrameAtPoint, getRoofSegmentBrushes, mapRoofGroupMaterialIndex, ROOF_MATERIAL_SLOT_COUNT, RoofSystem, remapRoofShellFaces, roofCsgDummyMats, } from './systems/roof/roof-system';
61
+ export { ScanSystem } from './systems/scan/scan-system';
62
+ // Slab system follows the wall + fence re-export pattern — composed into
63
+ // the registry-driven slab definition's `def.system`. Removed in Phase 6
64
+ // alongside the legacy slab mount point.
65
+ export { generateSlabGeometry, SlabSystem } from './systems/slab/slab-system';
66
+ export { getStairBodyMaterials, getStairRailingMaterial, getStraightStairSegmentBodyMaterials, } from './systems/stair/stair-materials';
67
+ export { StairSystem } from './systems/stair/stair-system';
68
+ export { WallCutout } from './systems/wall/wall-cutout';
13
69
  export { getVisibleWallMaterials } from './systems/wall/wall-materials';
70
+ // Wall internals re-exported so `@pascal-app/nodes`' registry-driven wall
71
+ // definition can compose them into `def.system` without duplicating the
72
+ // 800+ lines of CSG / mitering logic during Phase 3. These exports are
73
+ // removed in Phase 6 when the legacy mount points are deleted.
74
+ export { WallSystem } from './systems/wall/wall-system';
75
+ export { WindowAnimationSystem } from './systems/window/window-animation-system';
76
+ export { WindowSystem } from './systems/window/window-system';
77
+ export { ZoneSystem } from './systems/zone/zone-system';
@@ -0,0 +1,16 @@
1
+ import type * as THREE from 'three';
2
+ import { type Brush, Evaluator } from 'three-bvh-csg';
3
+ /**
4
+ * Shared CSG primitives used by kinds whose geometry subtracts pieces
5
+ * against their host (chimney trimmed by the roof shell, skylight
6
+ * frame as a ring cut from a box, etc.). Lives in viewer because
7
+ * three-bvh-csg + three-mesh-bvh are viewer-only deps; kinds living
8
+ * in `@pascal-app/nodes` import these through the public surface.
9
+ */
10
+ export declare function csgGeometry(brush: Brush): THREE.BufferGeometry;
11
+ export declare function csgMaterials(brush: Brush): THREE.Material[];
12
+ export declare const csgEvaluator: Evaluator;
13
+ export declare function computeGeometryBoundsTree(geometry: THREE.BufferGeometry): void;
14
+ export declare function prepareBrushForCSG(brush: Brush): void;
15
+ export { ADDITION, Brush, SUBTRACTION } from 'three-bvh-csg';
16
+ //# sourceMappingURL=csg-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csg-utils.d.ts","sourceRoot":"","sources":["../../src/lib/csg-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,KAAK,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAGrD;;;;;;GAMG;AAEH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,cAAc,CAE9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAG3D;AAED,eAAO,MAAM,YAAY,WAAkB,CAAA;AAK3C,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,QAMvE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,QAG9C;AAID,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,33 @@
1
+ import { Evaluator } from 'three-bvh-csg';
2
+ import { computeBoundsTree } from 'three-mesh-bvh';
3
+ /**
4
+ * Shared CSG primitives used by kinds whose geometry subtracts pieces
5
+ * against their host (chimney trimmed by the roof shell, skylight
6
+ * frame as a ring cut from a box, etc.). Lives in viewer because
7
+ * three-bvh-csg + three-mesh-bvh are viewer-only deps; kinds living
8
+ * in `@pascal-app/nodes` import these through the public surface.
9
+ */
10
+ export function csgGeometry(brush) {
11
+ return brush.geometry;
12
+ }
13
+ export function csgMaterials(brush) {
14
+ const mat = brush.material;
15
+ return Array.isArray(mat) ? mat : [mat];
16
+ }
17
+ export const csgEvaluator = new Evaluator();
18
+ csgEvaluator.useGroups = true;
19
+ csgEvaluator.consolidateGroups = false;
20
+ csgEvaluator.attributes = ['position', 'normal', 'uv'];
21
+ export function computeGeometryBoundsTree(geometry) {
22
+ ;
23
+ geometry.computeBoundsTree =
24
+ computeBoundsTree;
25
+ geometry.computeBoundsTree({ maxLeafSize: 10 });
26
+ }
27
+ export function prepareBrushForCSG(brush) {
28
+ computeGeometryBoundsTree(brush.geometry);
29
+ brush.updateMatrixWorld();
30
+ }
31
+ // Re-export Brush + SUBTRACTION + ADDITION so kinds don't need a direct
32
+ // `three-bvh-csg` dependency.
33
+ export { ADDITION, Brush, SUBTRACTION } from 'three-bvh-csg';
@@ -0,0 +1,21 @@
1
+ import type { BufferGeometry } from 'three';
2
+ /**
3
+ * True when `geometry` has a bound, non-empty `position` attribute — i.e. it is
4
+ * safe to submit to the WebGPU renderer.
5
+ *
6
+ * A geometry whose `position` attribute has `count === 0` (or no `position` at
7
+ * all) leaves WebGPU **vertex buffer slot 0 unbound**. The validator rejects the
8
+ * draw with "Vertex buffer slot 0 … was not set", and — critically — that single
9
+ * rejected draw **poisons the entire command encoder**: every other draw in the
10
+ * frame (the whole scene + every editor overlay) is discarded on the next queue
11
+ * submit ("Invalid CommandBuffer"). The visible result is the whole canvas
12
+ * flickering/garbling, not just the offending mesh.
13
+ *
14
+ * Individual call-sites guard against *creating* empty geometry (see
15
+ * `createPlaceholderGeometry`, the ceiling/door degenerate fallbacks, etc.), but
16
+ * transient/derived geometries can still slip through. This predicate is the
17
+ * renderer-level safety net: skipping a count-0 draw is a no-op visually (it
18
+ * would draw nothing anyway) while keeping the command encoder healthy.
19
+ */
20
+ export declare function hasDrawableGeometry(geometry: BufferGeometry | undefined | null): boolean;
21
+ //# sourceMappingURL=drawable-geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawable-geometry.d.ts","sourceRoot":"","sources":["../../src/lib/drawable-geometry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAE3C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAGxF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * True when `geometry` has a bound, non-empty `position` attribute — i.e. it is
3
+ * safe to submit to the WebGPU renderer.
4
+ *
5
+ * A geometry whose `position` attribute has `count === 0` (or no `position` at
6
+ * all) leaves WebGPU **vertex buffer slot 0 unbound**. The validator rejects the
7
+ * draw with "Vertex buffer slot 0 … was not set", and — critically — that single
8
+ * rejected draw **poisons the entire command encoder**: every other draw in the
9
+ * frame (the whole scene + every editor overlay) is discarded on the next queue
10
+ * submit ("Invalid CommandBuffer"). The visible result is the whole canvas
11
+ * flickering/garbling, not just the offending mesh.
12
+ *
13
+ * Individual call-sites guard against *creating* empty geometry (see
14
+ * `createPlaceholderGeometry`, the ceiling/door degenerate fallbacks, etc.), but
15
+ * transient/derived geometries can still slip through. This predicate is the
16
+ * renderer-level safety net: skipping a count-0 draw is a no-op visually (it
17
+ * would draw nothing anyway) while keeping the command encoder healthy.
18
+ */
19
+ export function hasDrawableGeometry(geometry) {
20
+ const position = geometry?.attributes?.position;
21
+ return Boolean(position && position.count > 0);
22
+ }
@@ -0,0 +1,3 @@
1
+ export type EdgeMode = 'off' | 'soft' | 'strong';
2
+ export declare function edgeColorFor(background: string): string;
3
+ //# sourceMappingURL=edge-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-style.d.ts","sourceRoot":"","sources":["../../src/lib/edge-style.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAKhD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAOvD"}
@@ -0,0 +1,11 @@
1
+ // Ink line colour follows background luminance — light backgrounds get
2
+ // near-black lines, dark backgrounds get near-white. Same rule Mapbox uses for
3
+ // label outlines, so edges stay legible across every scene theme.
4
+ export function edgeColorFor(background) {
5
+ const hex = background.replace('#', '');
6
+ const r = Number.parseInt(hex.slice(0, 2), 16) / 255;
7
+ const g = Number.parseInt(hex.slice(2, 4), 16) / 255;
8
+ const b = Number.parseInt(hex.slice(4, 6), 16) / 255;
9
+ const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;
10
+ return luma > 0.5 ? '#1a1d24' : '#dde2eb';
11
+ }
@@ -0,0 +1,4 @@
1
+ export declare const PERF_OVERLAY_ENABLED: boolean;
2
+ export declare function pushGpuSample(ms: number): void;
3
+ export declare function drainGpuSamples(): number[];
4
+ //# sourceMappingURL=gpu-perf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu-perf.d.ts","sourceRoot":"","sources":["../../src/lib/gpu-perf.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,oBAAoB,SACyD,CAAA;AAK1F,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAK1C"}
@@ -0,0 +1,23 @@
1
+ // GPU work-time measurement, gated by `?perf` in the URL.
2
+ //
3
+ // We can't use WebGPU timestamp queries here because the editor renders via
4
+ // a custom `RenderPipeline.render()` path that bypasses three.js's built-in
5
+ // timestamp infrastructure. Instead we use `device.queue.onSubmittedWorkDone()`,
6
+ // which resolves when the GPU finishes all submitted work — measuring the
7
+ // CPU→GPU-done delta gives a clean approximation of per-frame GPU duration
8
+ // regardless of which render path produced it.
9
+ export const PERF_OVERLAY_ENABLED = typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('perf');
10
+ const MAX_SAMPLES = 256;
11
+ const samples = [];
12
+ export function pushGpuSample(ms) {
13
+ samples.push(ms);
14
+ if (samples.length > MAX_SAMPLES)
15
+ samples.shift();
16
+ }
17
+ export function drainGpuSamples() {
18
+ if (samples.length === 0)
19
+ return [];
20
+ const out = samples.slice();
21
+ samples.length = 0;
22
+ return out;
23
+ }
@@ -0,0 +1,9 @@
1
+ export declare function inkedEdges({ depthTex, normalTex, inkColor, radius, opacity, sceneRgb, }: {
2
+ depthTex: any;
3
+ normalTex: any;
4
+ inkColor: any;
5
+ radius: number;
6
+ opacity: number;
7
+ sceneRgb: any;
8
+ }): any;
9
+ //# sourceMappingURL=ink-edges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ink-edges.d.ts","sourceRoot":"","sources":["../../src/lib/ink-edges.ts"],"names":[],"mappings":"AA6BA,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAO,EACP,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,GAAG,CAAA;IACb,SAAS,EAAE,GAAG,CAAA;IACd,QAAQ,EAAE,GAAG,CAAA;IAIb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,GAAG,CAAA;CACd,OAgCA"}