@pascal-app/viewer 0.9.1 → 1.0.0-beta.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 (206) hide show
  1. package/README.md +20 -5
  2. package/dist/components/error-boundary.d.ts +6 -0
  3. package/dist/components/error-boundary.d.ts.map +1 -1
  4. package/dist/components/error-boundary.js +6 -0
  5. package/dist/components/renderers/node-renderer.d.ts +5 -1
  6. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  7. package/dist/components/renderers/node-renderer.js +5 -2
  8. package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -1
  9. package/dist/components/renderers/parametric-node-renderer.js +7 -4
  10. package/dist/components/viewer/bvh-ecctrl.d.ts +77 -0
  11. package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -0
  12. package/dist/components/viewer/bvh-ecctrl.js +552 -0
  13. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  14. package/dist/components/viewer/frame-limiter.js +59 -4
  15. package/dist/components/viewer/glb-interactive.d.ts +41 -0
  16. package/dist/components/viewer/glb-interactive.d.ts.map +1 -0
  17. package/dist/components/viewer/glb-interactive.js +394 -0
  18. package/dist/components/viewer/glb-reference-nodes.d.ts +29 -0
  19. package/dist/components/viewer/glb-reference-nodes.d.ts.map +1 -0
  20. package/dist/components/viewer/glb-reference-nodes.js +80 -0
  21. package/dist/components/viewer/glb-replace-instances.d.ts +18 -0
  22. package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -0
  23. package/dist/components/viewer/glb-replace-instances.js +61 -0
  24. package/dist/components/viewer/glb-scene.d.ts +54 -0
  25. package/dist/components/viewer/glb-scene.d.ts.map +1 -0
  26. package/dist/components/viewer/glb-scene.js +920 -0
  27. package/dist/components/viewer/glb-walkthrough-controller.d.ts +22 -0
  28. package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -0
  29. package/dist/components/viewer/glb-walkthrough-controller.js +445 -0
  30. package/dist/components/viewer/index.d.ts +19 -2
  31. package/dist/components/viewer/index.d.ts.map +1 -1
  32. package/dist/components/viewer/index.js +113 -12
  33. package/dist/components/viewer/lights.d.ts.map +1 -1
  34. package/dist/components/viewer/lights.js +36 -5
  35. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  36. package/dist/components/viewer/perf-monitor.js +17 -2
  37. package/dist/components/viewer/post-processing.d.ts +7 -1
  38. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  39. package/dist/components/viewer/post-processing.js +180 -24
  40. package/dist/components/viewer/registered-systems.d.ts.map +1 -1
  41. package/dist/components/viewer/registered-systems.js +6 -4
  42. package/dist/components/viewer/scene-bvh.d.ts +2 -1
  43. package/dist/components/viewer/scene-bvh.d.ts.map +1 -1
  44. package/dist/components/viewer/scene-bvh.js +3 -0
  45. package/dist/components/viewer/scene-bvh.test.d.ts +2 -0
  46. package/dist/components/viewer/scene-bvh.test.d.ts.map +1 -0
  47. package/dist/components/viewer/scene-bvh.test.js +13 -0
  48. package/dist/components/viewer/scene-environment.d.ts +2 -0
  49. package/dist/components/viewer/scene-environment.d.ts.map +1 -0
  50. package/dist/components/viewer/scene-environment.js +79 -0
  51. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  52. package/dist/components/viewer/selection-manager.js +23 -12
  53. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  54. package/dist/hooks/use-gltf-ktx2.js +2 -24
  55. package/dist/hooks/use-node-events.d.ts +1 -1
  56. package/dist/hooks/use-node-events.d.ts.map +1 -1
  57. package/dist/hooks/use-node-events.js +22 -14
  58. package/dist/index.d.ts +24 -10
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +29 -13
  61. package/dist/lib/backdrop.d.ts +33 -0
  62. package/dist/lib/backdrop.d.ts.map +1 -0
  63. package/dist/lib/backdrop.js +92 -0
  64. package/dist/lib/box-uv.d.ts +13 -0
  65. package/dist/lib/box-uv.d.ts.map +1 -0
  66. package/dist/lib/box-uv.js +32 -0
  67. package/dist/lib/csg-utils.d.ts +3 -9
  68. package/dist/lib/csg-utils.d.ts.map +1 -1
  69. package/dist/lib/csg-utils.js +65 -5
  70. package/dist/lib/csg-utils.test.d.ts +2 -0
  71. package/dist/lib/csg-utils.test.d.ts.map +1 -0
  72. package/dist/lib/csg-utils.test.js +45 -0
  73. package/dist/lib/edge-style.d.ts +1 -0
  74. package/dist/lib/edge-style.d.ts.map +1 -1
  75. package/dist/lib/edge-style.js +26 -6
  76. package/dist/lib/hero-pose.d.ts +47 -0
  77. package/dist/lib/hero-pose.d.ts.map +1 -0
  78. package/dist/lib/hero-pose.js +227 -0
  79. package/dist/lib/ink-edges.d.ts +1 -1
  80. package/dist/lib/ink-edges.d.ts.map +1 -1
  81. package/dist/lib/ink-edges.js +13 -7
  82. package/dist/lib/ktx2-loader.d.ts +46 -0
  83. package/dist/lib/ktx2-loader.d.ts.map +1 -0
  84. package/dist/lib/ktx2-loader.js +142 -0
  85. package/dist/lib/layers.d.ts +10 -0
  86. package/dist/lib/layers.d.ts.map +1 -1
  87. package/dist/lib/layers.js +10 -0
  88. package/dist/lib/materials.d.ts +16 -1
  89. package/dist/lib/materials.d.ts.map +1 -1
  90. package/dist/lib/materials.js +158 -34
  91. package/dist/lib/materials.test.d.ts +2 -0
  92. package/dist/lib/materials.test.d.ts.map +1 -0
  93. package/dist/lib/materials.test.js +25 -0
  94. package/dist/lib/merged-outline-node.test.d.ts +2 -0
  95. package/dist/lib/merged-outline-node.test.d.ts.map +1 -0
  96. package/dist/lib/merged-outline-node.test.js +22 -0
  97. package/dist/lib/scene-themes.d.ts +1 -0
  98. package/dist/lib/scene-themes.d.ts.map +1 -1
  99. package/dist/lib/scene-themes.js +25 -16
  100. package/dist/lib/shadow-only.d.ts +4 -0
  101. package/dist/lib/shadow-only.d.ts.map +1 -0
  102. package/dist/lib/shadow-only.js +36 -0
  103. package/dist/lib/snapshot-pipeline.d.ts +42 -0
  104. package/dist/lib/snapshot-pipeline.d.ts.map +1 -0
  105. package/dist/lib/snapshot-pipeline.js +254 -0
  106. package/dist/lib/terrain-perimeter-fill.d.ts +7 -0
  107. package/dist/lib/terrain-perimeter-fill.d.ts.map +1 -0
  108. package/dist/lib/terrain-perimeter-fill.js +75 -0
  109. package/dist/lib/texture-node-guard.d.ts +13 -0
  110. package/dist/lib/texture-node-guard.d.ts.map +1 -0
  111. package/dist/lib/texture-node-guard.js +39 -0
  112. package/dist/lib/texture-reference.d.ts +31 -0
  113. package/dist/lib/texture-reference.d.ts.map +1 -0
  114. package/dist/lib/texture-reference.js +139 -0
  115. package/dist/lib/texture-reference.test.d.ts +2 -0
  116. package/dist/lib/texture-reference.test.d.ts.map +1 -0
  117. package/dist/lib/texture-reference.test.js +86 -0
  118. package/dist/lib/tsl-compat.d.ts +12 -0
  119. package/dist/lib/tsl-compat.d.ts.map +1 -0
  120. package/dist/lib/tsl-compat.js +13 -0
  121. package/dist/store/use-viewer.d.ts +73 -18
  122. package/dist/store/use-viewer.d.ts.map +1 -1
  123. package/dist/store/use-viewer.js +191 -4
  124. package/dist/store/use-viewer.test.d.ts +2 -0
  125. package/dist/store/use-viewer.test.d.ts.map +1 -0
  126. package/dist/store/use-viewer.test.js +61 -0
  127. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  128. package/dist/systems/ceiling/ceiling-system.js +12 -5
  129. package/dist/systems/door/door-animation.test.d.ts +2 -0
  130. package/dist/systems/door/door-animation.test.d.ts.map +1 -0
  131. package/dist/systems/door/door-animation.test.js +51 -0
  132. package/dist/systems/door/door-floor-alignment.test.d.ts +2 -0
  133. package/dist/systems/door/door-floor-alignment.test.d.ts.map +1 -0
  134. package/dist/systems/door/door-floor-alignment.test.js +50 -0
  135. package/dist/systems/door/door-system.d.ts +24 -0
  136. package/dist/systems/door/door-system.d.ts.map +1 -1
  137. package/dist/systems/door/door-system.js +494 -161
  138. package/dist/systems/fence/fence-system.d.ts +17 -0
  139. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  140. package/dist/systems/fence/fence-system.js +221 -53
  141. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -1
  142. package/dist/systems/floor-elevation/floor-elevation-system.js +30 -7
  143. package/dist/systems/geometry/geometry-system.d.ts +7 -0
  144. package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
  145. package/dist/systems/geometry/geometry-system.js +95 -26
  146. package/dist/systems/geometry/geometry-system.test.d.ts +2 -0
  147. package/dist/systems/geometry/geometry-system.test.d.ts.map +1 -0
  148. package/dist/systems/geometry/geometry-system.test.js +30 -0
  149. package/dist/systems/interactive/control-widget.d.ts +10 -0
  150. package/dist/systems/interactive/control-widget.d.ts.map +1 -0
  151. package/dist/systems/interactive/control-widget.js +35 -0
  152. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  153. package/dist/systems/interactive/interactive-system.js +55 -56
  154. package/dist/systems/item/item-system.d.ts.map +1 -1
  155. package/dist/systems/item/item-system.js +20 -6
  156. package/dist/systems/level/level-system.d.ts.map +1 -1
  157. package/dist/systems/level/level-system.js +34 -9
  158. package/dist/systems/level/level-utils.d.ts +0 -3
  159. package/dist/systems/level/level-utils.d.ts.map +1 -1
  160. package/dist/systems/level/level-utils.js +7 -45
  161. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  162. package/dist/systems/roof/roof-materials.js +29 -8
  163. package/dist/systems/roof/roof-system.d.ts +21 -8
  164. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  165. package/dist/systems/roof/roof-system.js +1079 -221
  166. package/dist/systems/slab/slab-system.d.ts +7 -4
  167. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  168. package/dist/systems/slab/slab-system.js +31 -83
  169. package/dist/systems/slab/slab-system.test.js +54 -14
  170. package/dist/systems/stair/stair-system.js +7 -4
  171. package/dist/systems/wall/opening-cutout-geometry.d.ts +31 -0
  172. package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -0
  173. package/dist/systems/wall/opening-cutout-geometry.js +167 -0
  174. package/dist/systems/wall/opening-cutout-geometry.test.d.ts +2 -0
  175. package/dist/systems/wall/opening-cutout-geometry.test.d.ts.map +1 -0
  176. package/dist/systems/wall/opening-cutout-geometry.test.js +172 -0
  177. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  178. package/dist/systems/wall/wall-cutout.js +49 -17
  179. package/dist/systems/wall/wall-materials.d.ts +11 -7
  180. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  181. package/dist/systems/wall/wall-materials.js +244 -35
  182. package/dist/systems/wall/wall-opening-cutout.test.d.ts +2 -0
  183. package/dist/systems/wall/wall-opening-cutout.test.d.ts.map +1 -0
  184. package/dist/systems/wall/wall-opening-cutout.test.js +59 -0
  185. package/dist/systems/wall/wall-support-extension.test.d.ts +2 -0
  186. package/dist/systems/wall/wall-support-extension.test.d.ts.map +1 -0
  187. package/dist/systems/wall/wall-support-extension.test.js +116 -0
  188. package/dist/systems/wall/wall-system.d.ts +4 -8
  189. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  190. package/dist/systems/wall/wall-system.js +397 -177
  191. package/dist/systems/wall/wall-terrain-bottom.test.d.ts +2 -0
  192. package/dist/systems/wall/wall-terrain-bottom.test.d.ts.map +1 -0
  193. package/dist/systems/wall/wall-terrain-bottom.test.js +34 -0
  194. package/dist/systems/window/window-animation-system.d.ts +12 -0
  195. package/dist/systems/window/window-animation-system.d.ts.map +1 -1
  196. package/dist/systems/window/window-animation-system.js +16 -5
  197. package/dist/systems/window/window-system.d.ts +7 -0
  198. package/dist/systems/window/window-system.d.ts.map +1 -1
  199. package/dist/systems/window/window-system.js +240 -14
  200. package/package.json +4 -4
  201. package/dist/components/viewer/ground-occluder.d.ts +0 -2
  202. package/dist/components/viewer/ground-occluder.d.ts.map +0 -1
  203. package/dist/components/viewer/ground-occluder.js +0 -67
  204. package/dist/components/viewer/walkthrough-controls.d.ts +0 -2
  205. package/dist/components/viewer/walkthrough-controls.d.ts.map +0 -1
  206. package/dist/components/viewer/walkthrough-controls.js +0 -131
@@ -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, getSelectableKinds, pointInPolygon, sceneRegistry, useScene, } from '@pascal-app/core';
3
+ import { emitter, getSelectableKinds, pointInPolygon, resolveSelectionProxyId, 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';
@@ -122,16 +122,18 @@ const isNodeInZone = (node, levelId, zoneId) => {
122
122
  };
123
123
  const getStrategy = () => {
124
124
  const { buildingId, levelId, zoneId } = useViewer.getState().selection;
125
- const computeNextIds = (node, selectedIds, event) => {
125
+ const computeNextIds = (nodeId, selectedIds, event) => {
126
126
  const isMeta = event?.metaKey || event?.nativeEvent?.metaKey;
127
127
  const isCtrl = event?.ctrlKey || event?.nativeEvent?.ctrlKey;
128
- if (isMeta || isCtrl) {
129
- if (selectedIds.includes(node.id)) {
130
- return selectedIds.filter((id) => id !== node.id);
128
+ // Shift toggles membership like Cmd/Ctrl.
129
+ const isShift = event?.shiftKey || event?.nativeEvent?.shiftKey;
130
+ if (isMeta || isCtrl || isShift) {
131
+ if (selectedIds.includes(nodeId)) {
132
+ return selectedIds.filter((id) => id !== nodeId);
131
133
  }
132
- return [...selectedIds, node.id];
134
+ return [...selectedIds, nodeId];
133
135
  }
134
- return [node.id];
136
+ return [nodeId];
135
137
  };
136
138
  // No building selected -> can select buildings
137
139
  if (!buildingId) {
@@ -195,9 +197,10 @@ const getStrategy = () => {
195
197
  }
196
198
  }
197
199
  const { selectedIds } = useViewer.getState().selection;
200
+ const proxyId = resolveSelectionProxyId(nodeToSelect, useScene.getState().nodes);
198
201
  useViewer
199
202
  .getState()
200
- .setSelection({ selectedIds: computeNextIds(nodeToSelect, selectedIds, nativeEvent) });
203
+ .setSelection({ selectedIds: computeNextIds(proxyId, selectedIds, nativeEvent) });
201
204
  },
202
205
  handleDeselect: () => {
203
206
  const { selectedIds } = useViewer.getState().selection;
@@ -248,7 +251,9 @@ export const SelectionManager = () => {
248
251
  useViewer.setState({ hoveredId: null });
249
252
  return;
250
253
  }
251
- useViewer.setState({ hoveredId: event.node.id });
254
+ useViewer.setState({
255
+ hoveredId: resolveSelectionProxyId(event.node, useScene.getState().nodes),
256
+ });
252
257
  }
253
258
  };
254
259
  const onLeave = (event) => {
@@ -259,7 +264,10 @@ export const SelectionManager = () => {
259
264
  return;
260
265
  if (strategy.isValid(event.node)) {
261
266
  event.stopPropagation();
262
- useViewer.setState({ hoveredId: null });
267
+ const targetId = resolveSelectionProxyId(event.node, useScene.getState().nodes);
268
+ if (useViewer.getState().hoveredId === targetId) {
269
+ useViewer.setState({ hoveredId: null });
270
+ }
263
271
  }
264
272
  };
265
273
  const onClick = (event) => {
@@ -345,13 +353,16 @@ const PointerMissedHandler = ({ clickHandledRef, }) => {
345
353
  };
346
354
  const OutlinerSync = () => {
347
355
  const selection = useViewer((s) => s.selection);
356
+ const externalSelectedIds = useViewer((s) => s.externalSelectedIds);
348
357
  const hoveredId = useViewer((s) => s.hoveredId);
349
358
  const outliner = useViewer((s) => s.outliner);
359
+ const geometryRevision = useViewer((s) => s.geometryRevision);
350
360
  const nodes = useScene((s) => s.nodes);
351
361
  useEffect(() => {
362
+ void geometryRevision;
352
363
  // Sync selected objects
353
364
  outliner.selectedObjects.length = 0;
354
- for (const id of selection.selectedIds) {
365
+ for (const id of new Set([...selection.selectedIds, ...externalSelectedIds])) {
355
366
  const node = nodes[id];
356
367
  if (node?.type === 'slab')
357
368
  continue;
@@ -369,6 +380,6 @@ const OutlinerSync = () => {
369
380
  if (obj)
370
381
  outliner.hoveredObjects.push(obj);
371
382
  }
372
- }, [selection, hoveredId, outliner, nodes]);
383
+ }, [selection, externalSelectedIds, hoveredId, outliner, nodes, geometryRevision]);
373
384
  return null;
374
385
  };
@@ -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;AAED,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;AAK3C,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,OAAO,OAAO,CAO5D,CAAA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1,33 +1,11 @@
1
1
  import { useGLTF } from '@react-three/drei';
2
2
  import { useThree } from '@react-three/fiber';
3
- import { KTX2Loader } from 'three/examples/jsm/Addons.js';
4
3
  import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
5
- const ktx2LoaderInstance = new KTX2Loader();
6
- ktx2LoaderInstance.setTranscoderPath('https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/basis/');
7
- const ktx2ConfiguredRenderers = new WeakSet();
8
- const ktx2WarningLoggedRenderers = new WeakSet();
4
+ import { configureKtx2Support } from '../lib/ktx2-loader';
9
5
  const useGLTFKTX2 = (path) => {
10
6
  const gl = useThree((state) => state.gl);
11
7
  return useGLTF(path, true, true, (loader) => {
12
- const renderer = gl;
13
- if (!ktx2ConfiguredRenderers.has(renderer)) {
14
- try {
15
- ktx2LoaderInstance.detectSupport(gl);
16
- ktx2ConfiguredRenderers.add(renderer);
17
- }
18
- catch (error) {
19
- // Some WebGPU flows can transiently call this before backend init.
20
- // Avoid crashing the whole scene; scans may render without KTX2 on this pass.
21
- if (!ktx2WarningLoggedRenderers.has(renderer)) {
22
- console.warn('[viewer] Skipping KTX2 support detection for now.', error);
23
- ktx2WarningLoggedRenderers.add(renderer);
24
- }
25
- }
26
- }
27
- if (ktx2ConfiguredRenderers.has(renderer)) {
28
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
- loader.setKTX2Loader(ktx2LoaderInstance);
30
- }
8
+ configureKtx2Support(loader, gl);
31
9
  loader.setMeshoptDecoder(MeshoptDecoder);
32
10
  });
33
11
  };
@@ -6,7 +6,7 @@ type NodeByKind<K extends AnyNodeType> = Extract<AnyNode, {
6
6
  export declare function useNodeEvents<K extends AnyNodeType>(node: NodeByKind<K>, type: K): {
7
7
  onPointerDown: (e: ThreeEvent<PointerEvent>) => void;
8
8
  onPointerUp: (e: ThreeEvent<PointerEvent>) => void;
9
- onClick: (e: ThreeEvent<PointerEvent>) => void;
9
+ onClick: (_e: ThreeEvent<PointerEvent>) => void;
10
10
  onPointerEnter: (e: ThreeEvent<PointerEvent>) => void;
11
11
  onPointerLeave: (e: ThreeEvent<PointerEvent>) => void;
12
12
  onPointerMove: (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":"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"}
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;uBAwC1D,UAAU,CAAC,YAAY,CAAC;qBAK1B,UAAU,CAAC,YAAY,CAAC;kBAQ3B,UAAU,CAAC,YAAY,CAAC;wBAIlB,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"}
@@ -19,25 +19,33 @@ export function useNodeEvents(node, type) {
19
19
  // through that generic surface without enumerating every kind.
20
20
  emitter.emit(eventKey, payload);
21
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 = () => {
22
+ // Camera drags (orbit / pan / dolly) suppress ALL node pointer events.
23
+ //
24
+ // `inputDragging` (host-driven drags: handle arrows, press-drag moves)
25
+ // additionally suppresses the SELECTION events — without it the click
26
+ // synthesized on pointer-release would reroute selection to whatever mesh
27
+ // sits under the cursor at release. It must NOT suppress the SPATIAL events
28
+ // (`enter` / `move` / `leave`): a surface-following move tool — a door /
29
+ // window sliding along a wall — runs WITH `inputDragging` set and depends on
30
+ // those events to track the cursor. Consumers that should ignore drag-time
31
+ // spatial events gate on `inputDragging` themselves (the editor's hover and
32
+ // paint paths, box-select), so emitting them during a drag only reaches the
33
+ // active move tool that wants them.
34
+ const spatialSuppressed = () => useViewer.getState().cameraDragging;
35
+ const selectionSuppressed = () => {
28
36
  const s = useViewer.getState();
29
37
  return s.cameraDragging || s.inputDragging;
30
38
  };
31
39
  return {
32
40
  onPointerDown: (e) => {
33
- if (isInteractionActive())
41
+ if (selectionSuppressed())
34
42
  return;
35
43
  if (e.button !== 0)
36
44
  return;
37
45
  emit('pointerdown', e);
38
46
  },
39
47
  onPointerUp: (e) => {
40
- if (isInteractionActive())
48
+ if (selectionSuppressed())
41
49
  return;
42
50
  if (e.button !== 0)
43
51
  return;
@@ -46,32 +54,32 @@ export function useNodeEvents(node, type) {
46
54
  // which often fails if the mouse moves even 1 pixel.
47
55
  emit('click', e);
48
56
  },
49
- onClick: (e) => {
57
+ onClick: (_e) => {
50
58
  // Disable default R3F click since we synthesize it on pointerup
51
59
  // This prevents double-clicks from firing twice.
52
60
  },
53
61
  onPointerEnter: (e) => {
54
- if (isInteractionActive())
62
+ if (spatialSuppressed())
55
63
  return;
56
64
  emit('enter', e);
57
65
  },
58
66
  onPointerLeave: (e) => {
59
- if (isInteractionActive())
67
+ if (spatialSuppressed())
60
68
  return;
61
69
  emit('leave', e);
62
70
  },
63
71
  onPointerMove: (e) => {
64
- if (isInteractionActive())
72
+ if (spatialSuppressed())
65
73
  return;
66
74
  emit('move', e);
67
75
  },
68
76
  onDoubleClick: (e) => {
69
- if (isInteractionActive())
77
+ if (selectionSuppressed())
70
78
  return;
71
79
  emit('double-click', e);
72
80
  },
73
81
  onContextMenu: (e) => {
74
- if (isInteractionActive())
82
+ if (selectionSuppressed())
75
83
  return;
76
84
  emit('context-menu', e);
77
85
  },
package/dist/index.d.ts CHANGED
@@ -2,29 +2,42 @@ export type { SurfaceRole } from '@pascal-app/core';
2
2
  export { ErrorBoundary } from './components/error-boundary';
3
3
  export { NodeRenderer } from './components/renderers/node-renderer';
4
4
  export { default as Viewer, type ViewerHandle } from './components/viewer';
5
+ export { type BVHEcctrlApi, default as BVHEcctrl, type MovementInput, } from './components/viewer/bvh-ecctrl';
6
+ export { buildGlbInteractiveItems, GlbInteractive, type GlbInteractiveItem, } from './components/viewer/glb-interactive';
7
+ export { buildGlbReferenceNodes, buildGlbReplaceNodes, } from './components/viewer/glb-reference-nodes';
8
+ export { type GlbHover, type GlbIdentity, type GlbLevel, GlbScene, type GlbWalkthrough, } from './components/viewer/glb-scene';
9
+ export { CROUCH_CAPSULE, CROUCH_EYE_OFFSET, CROUCH_FLOAT_HEIGHT, CROUCH_RUN_SPEED, CROUCH_WALK_SPEED, EYE_LERP_SPEED, GlbWalkthroughController, STAND_CAPSULE, STAND_CLEARANCE, STAND_FLOAT_HEIGHT, WALKTHROUGH_FOV, } from './components/viewer/glb-walkthrough-controller';
5
10
  export type { HoverStyle, HoverStyles } from './components/viewer/post-processing';
6
11
  export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
7
- export { WalkthroughControls } from './components/viewer/walkthrough-controls';
12
+ export { SceneEnvironment } from './components/viewer/scene-environment';
8
13
  export { useAssetUrl } from './hooks/use-asset-url';
9
14
  export { useGLTFKTX2 } from './hooks/use-gltf-ktx2';
10
15
  export { useNodeEvents } from './hooks/use-node-events';
11
16
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
12
- export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
17
+ export { backdropGradient, deepSkyColor, horizonHazeColor } from './lib/backdrop';
18
+ export { applyWorldScaleBoxUVs } from './lib/box-uv';
19
+ export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, INTERSECTION, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
13
20
  export type { EdgeMode } from './lib/edge-style';
21
+ export { computeHeroFraming, DEFAULT_FRAMING_EXCLUDED_TYPES, type HeroFraming, heroCameraPose, temporarilyHideNodeTypes, unionRegisteredNodeBounds, } from './lib/hero-pose';
14
22
  export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, } from './lib/isolation';
23
+ export { configureKtx2Support, ensureKtx2Support } from './lib/ktx2-loader';
15
24
  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';
25
+ 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, resolveMaterialRef, resolveSlotDefaultMaterial, resolveSurfaceColor, WHITE_PALETTE, } from './lib/materials';
17
26
  export { mergedOutline } from './lib/merged-outline-node';
18
27
  export { unionPolygons } from './lib/polygon-union';
19
28
  export { getSceneTheme, SCENE_THEME_IDS, SCENE_THEMES, type SceneTheme, } from './lib/scene-themes';
29
+ export { createSnapshotPipeline, type SnapshotCaptureMode, type SnapshotCaptureResult, type SnapshotCropRegion, type SnapshotPipeline, type SnapshotSize, THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH, } from './lib/snapshot-pipeline';
30
+ export { buildTerrainPerimeterFillGeometry, type TerrainPerimeterPoint, } from './lib/terrain-perimeter-fill';
31
+ export { getPascalTextureRef, type PascalTextureColorSpace, type PascalTextureMap, type PascalTextureRef, stampPascalTextureRef, textureMapForSlot, } from './lib/texture-reference';
32
+ export { packNormalToRGB, unpackRGBToNormal } from './lib/tsl-compat';
20
33
  export { useItemLightPool } from './store/use-item-light-pool';
21
- export { default as useViewer } from './store/use-viewer';
34
+ export { applyCountryUnitDefault, default as useViewer, type MetricNotation, } from './store/use-viewer';
22
35
  export { CeilingSystem } from './systems/ceiling/ceiling-system';
23
36
  export { createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, } from './systems/column/column-geometry';
24
37
  export { DoorAnimationSystem } from './systems/door/door-animation-system';
25
- export { DoorSystem } from './systems/door/door-system';
38
+ export { buildDoorPreviewMesh, DoorSystem, poseDoorMovingParts } from './systems/door/door-system';
26
39
  export { ElevatorInteractionSystem } from './systems/elevator/elevator-interaction-system';
27
- export { FenceSystem, generateFenceGeometry } from './systems/fence/fence-system';
40
+ export { FenceSystem, generateFenceGeometry, generateFenceSlotGeometries, } from './systems/fence/fence-system';
28
41
  export { FloorElevationSystem } from './systems/floor-elevation/floor-elevation-system';
29
42
  export { GuideSystem } from './systems/guide/guide-system';
30
43
  export { InteractiveSystem } from './systems/interactive/interactive-system';
@@ -33,15 +46,16 @@ export { ItemLightSystem } from './systems/item-light/item-light-system';
33
46
  export { LevelSystem } from './systems/level/level-system';
34
47
  export { snapLevelsToTruePositions } from './systems/level/level-utils';
35
48
  export { getRoofMaterialArray } from './systems/roof/roof-materials';
36
- export { getRoofOuterSurfaceFrameAtPoint, getRoofSegmentBrushes, mapRoofGroupMaterialIndex, ROOF_MATERIAL_SLOT_COUNT, RoofSystem, remapRoofShellFaces, roofCsgDummyMats, type SurfaceFrame, } from './systems/roof/roof-system';
49
+ export { clipGeometryBySegmentTrim, generateRoofSegmentGeometry, getRoofOuterSurfaceFrameAtPoint, getRoofSegmentBrushes, mapRoofGroupMaterialIndex, ROOF_MATERIAL_SLOT_COUNT, RoofSystem, remapRoofShellFaces, roofCsgDummyMats, type SurfaceFrame, } from './systems/roof/roof-system';
37
50
  export { ScanSystem } from './systems/scan/scan-system';
38
- export { generateSlabGeometry, SlabSystem } from './systems/slab/slab-system';
51
+ export { generateSlabGeometry } from './systems/slab/slab-system';
39
52
  export { getStairBodyMaterials, getStairRailingMaterial, getStraightStairSegmentBodyMaterials, type StairBodyMaterials, } from './systems/stair/stair-materials';
40
53
  export { StairSystem } from './systems/stair/stair-system';
54
+ export { buildOpeningCutoutGeometry, getOpeningCutoutBottomPadding, hasFlatOpeningCutoutBottom, } from './systems/wall/opening-cutout-geometry';
41
55
  export { WallCutout } from './systems/wall/wall-cutout';
42
56
  export { getVisibleWallMaterials } from './systems/wall/wall-materials';
43
57
  export { WallSystem } from './systems/wall/wall-system';
44
- export { WindowAnimationSystem } from './systems/window/window-animation-system';
45
- export { WindowSystem } from './systems/window/window-system';
58
+ export { poseWindowMovingParts, WindowAnimationSystem, } from './systems/window/window-animation-system';
59
+ export { buildWindowPreviewMesh, WindowSystem } from './systems/window/window-system';
46
60
  export { ZoneSystem } from './systems/zone/zone-system';
47
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -11,33 +11,46 @@ export { ErrorBoundary } from './components/error-boundary';
11
11
  // — no per-kind re-exports needed.
12
12
  export { NodeRenderer } from './components/renderers/node-renderer';
13
13
  export { default as Viewer } from './components/viewer';
14
+ export { default as BVHEcctrl, } from './components/viewer/bvh-ecctrl';
15
+ export { buildGlbInteractiveItems, GlbInteractive, } from './components/viewer/glb-interactive';
16
+ export { buildGlbReferenceNodes, buildGlbReplaceNodes, } from './components/viewer/glb-reference-nodes';
17
+ export { GlbScene, } from './components/viewer/glb-scene';
18
+ export { CROUCH_CAPSULE, CROUCH_EYE_OFFSET, CROUCH_FLOAT_HEIGHT, CROUCH_RUN_SPEED, CROUCH_WALK_SPEED, EYE_LERP_SPEED, GlbWalkthroughController, STAND_CAPSULE, STAND_CLEARANCE, STAND_FLOAT_HEIGHT, WALKTHROUGH_FOV, } from './components/viewer/glb-walkthrough-controller';
14
19
  export { DEFAULT_HOVER_STYLES, SSGI_PARAMS, } from './components/viewer/post-processing';
15
- export { WalkthroughControls } from './components/viewer/walkthrough-controls';
20
+ export { SceneEnvironment } from './components/viewer/scene-environment';
16
21
  export { useAssetUrl } from './hooks/use-asset-url';
17
22
  export { useGLTFKTX2 } from './hooks/use-gltf-ktx2';
18
23
  export { useNodeEvents } from './hooks/use-node-events';
19
24
  export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url';
25
+ export { backdropGradient, deepSkyColor, horizonHazeColor } from './lib/backdrop';
26
+ export { applyWorldScaleBoxUVs } from './lib/box-uv';
20
27
  // CSG primitives — used by chimney's roof-trim and other kinds whose
21
28
  // geometry subtracts pieces against their host. Lives in viewer
22
29
  // 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';
30
+ export { ADDITION, Brush, computeGeometryBoundsTree, csgEvaluator, csgGeometry, csgMaterials, INTERSECTION, prepareBrushForCSG, SUBTRACTION, } from './lib/csg-utils';
31
+ export { computeHeroFraming, DEFAULT_FRAMING_EXCLUDED_TYPES, heroCameraPose, temporarilyHideNodeTypes, unionRegisteredNodeBounds, } from './lib/hero-pose';
24
32
  export { applyIsolation, clearIsolation, collectIsolationSubtree, isIsolationActive, } from './lib/isolation';
33
+ export { configureKtx2Support, ensureKtx2Support } from './lib/ktx2-loader';
25
34
  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';
35
+ 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, resolveMaterialRef, resolveSlotDefaultMaterial, resolveSurfaceColor, WHITE_PALETTE, } from './lib/materials';
27
36
  export { mergedOutline } from './lib/merged-outline-node';
28
37
  export { unionPolygons } from './lib/polygon-union';
29
38
  export { getSceneTheme, SCENE_THEME_IDS, SCENE_THEMES, } from './lib/scene-themes';
39
+ export { createSnapshotPipeline, THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH, } from './lib/snapshot-pipeline';
40
+ export { buildTerrainPerimeterFillGeometry, } from './lib/terrain-perimeter-fill';
41
+ export { getPascalTextureRef, stampPascalTextureRef, textureMapForSlot, } from './lib/texture-reference';
42
+ export { packNormalToRGB, unpackRGBToNormal } from './lib/tsl-compat';
30
43
  export { useItemLightPool } from './store/use-item-light-pool';
31
- export { default as useViewer } from './store/use-viewer';
44
+ export { applyCountryUnitDefault, default as useViewer, } from './store/use-viewer';
32
45
  export { CeilingSystem } from './systems/ceiling/ceiling-system';
33
46
  export { createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, } from './systems/column/column-geometry';
34
47
  export { DoorAnimationSystem } from './systems/door/door-animation-system';
35
- export { DoorSystem } from './systems/door/door-system';
48
+ export { buildDoorPreviewMesh, DoorSystem, poseDoorMovingParts } from './systems/door/door-system';
36
49
  export { ElevatorInteractionSystem } from './systems/elevator/elevator-interaction-system';
37
50
  // Fence system follows the wall re-export pattern — composed into the
38
51
  // registry-driven fence definition's `def.system`. Removed in Phase 6
39
52
  // alongside the legacy fence mount point.
40
- export { FenceSystem, generateFenceGeometry } from './systems/fence/fence-system';
53
+ export { FenceSystem, generateFenceGeometry, generateFenceSlotGeometries, } from './systems/fence/fence-system';
41
54
  // Generic floor-elevation system. Lifts the rendered mesh of any kind
42
55
  // whose definition declares `capabilities.floorPlaced` by the slab
43
56
  // elevation under its footprint. Replaces the per-kind elevation block
@@ -57,14 +70,17 @@ export { getRoofMaterialArray } from './systems/roof/roof-materials';
57
70
  // the roof shell (chimney's self-trim, dormer's virtual-segment cut)
58
71
  // read these through the public surface. No kind-specific helpers
59
72
  // 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';
73
+ export { clipGeometryBySegmentTrim, generateRoofSegmentGeometry, getRoofOuterSurfaceFrameAtPoint, getRoofSegmentBrushes, mapRoofGroupMaterialIndex, ROOF_MATERIAL_SLOT_COUNT, RoofSystem, remapRoofShellFaces, roofCsgDummyMats, } from './systems/roof/roof-system';
61
74
  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';
75
+ // Pure slab geometry generator — composed into the registry-driven slab
76
+ // definition's `def.geometry` in `@pascal-app/nodes`.
77
+ export { generateSlabGeometry } from './systems/slab/slab-system';
66
78
  export { getStairBodyMaterials, getStairRailingMaterial, getStraightStairSegmentBodyMaterials, } from './systems/stair/stair-materials';
67
79
  export { StairSystem } from './systems/stair/stair-system';
80
+ // Pure opening-cutout profile math shared by the wall CSG pipeline and
81
+ // roof-wall opening cuts in `@pascal-app/nodes` — keeps shaped holes
82
+ // (arch / rounded / frameless opening) identical across both hosts.
83
+ export { buildOpeningCutoutGeometry, getOpeningCutoutBottomPadding, hasFlatOpeningCutoutBottom, } from './systems/wall/opening-cutout-geometry';
68
84
  export { WallCutout } from './systems/wall/wall-cutout';
69
85
  export { getVisibleWallMaterials } from './systems/wall/wall-materials';
70
86
  // Wall internals re-exported so `@pascal-app/nodes`' registry-driven wall
@@ -72,6 +88,6 @@ export { getVisibleWallMaterials } from './systems/wall/wall-materials';
72
88
  // 800+ lines of CSG / mitering logic during Phase 3. These exports are
73
89
  // removed in Phase 6 when the legacy mount points are deleted.
74
90
  export { WallSystem } from './systems/wall/wall-system';
75
- export { WindowAnimationSystem } from './systems/window/window-animation-system';
76
- export { WindowSystem } from './systems/window/window-system';
91
+ export { poseWindowMovingParts, WindowAnimationSystem, } from './systems/window/window-animation-system';
92
+ export { buildWindowPreviewMesh, WindowSystem } from './systems/window/window-system';
77
93
  export { ZoneSystem } from './systems/zone/zone-system';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared backdrop gradient: flat background looking down, a warm haze band
3
+ * hugging the horizon, the theme sky arriving just above it and deepening
4
+ * toward the zenith. One formula serves the post-processing backdrop and the
5
+ * thumbnail pipeline (per-pixel view ray) AND the site horizon disc's
6
+ * far-field dissolve (per-fragment view direction) — the disc converges to
7
+ * exactly this colour, so ground and backdrop meet without a seam from any
8
+ * camera pose.
9
+ *
10
+ * `dirY` is the world-space view direction's Y component (horizon = 0).
11
+ * Colour inputs are TSL nodes (uniforms or literals).
12
+ */
13
+ export declare function backdropGradient({ dirY, background, haze, sky, skyDeep, }: {
14
+ dirY: any;
15
+ background: any;
16
+ haze: any;
17
+ sky: any;
18
+ skyDeep: any;
19
+ }): any;
20
+ /**
21
+ * Atmospheric haze at the horizon: the theme's *sky* colour pulled toward a
22
+ * warm sun tint — skyish and sunish at once, so the band reads as part of
23
+ * the sky rather than a white stripe. Dark themes keep it faint (a low glow
24
+ * over the night zenith).
25
+ */
26
+ export declare function horizonHazeColor(sky: string, appearance: 'light' | 'dark'): string;
27
+ /**
28
+ * Zenith colour derived from the theme's sky: saturated and darkened in HSL
29
+ * so the hue stays the theme's own (blue studio, lavender sunset, near-black
30
+ * night) while the top of the frame gets real colour depth.
31
+ */
32
+ export declare function deepSkyColor(sky: string): string;
33
+ //# sourceMappingURL=backdrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backdrop.d.ts","sourceRoot":"","sources":["../../src/lib/backdrop.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,GAAG,EACH,OAAO,GACR,EAAE;IACD,IAAI,EAAE,GAAG,CAAA;IACT,UAAU,EAAE,GAAG,CAAA;IACf,IAAI,EAAE,GAAG,CAAA;IACT,GAAG,EAAE,GAAG,CAAA;IACR,OAAO,EAAE,GAAG,CAAA;CACb,GAAG,GAAG,CAUN;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAWlF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyChD"}
@@ -0,0 +1,92 @@
1
+ import { abs, exp, mix, smoothstep } from 'three/tsl';
2
+ /**
3
+ * Shared backdrop gradient: flat background looking down, a warm haze band
4
+ * hugging the horizon, the theme sky arriving just above it and deepening
5
+ * toward the zenith. One formula serves the post-processing backdrop and the
6
+ * thumbnail pipeline (per-pixel view ray) AND the site horizon disc's
7
+ * far-field dissolve (per-fragment view direction) — the disc converges to
8
+ * exactly this colour, so ground and backdrop meet without a seam from any
9
+ * camera pose.
10
+ *
11
+ * `dirY` is the world-space view direction's Y component (horizon = 0).
12
+ * Colour inputs are TSL nodes (uniforms or literals).
13
+ */
14
+ export function backdropGradient({ dirY, background, haze, sky, skyDeep, }) {
15
+ // The pale sky arrives fast (full by ≈8° elevation) so eye-level frames
16
+ // actually show it, then deepens toward the zenith for a real gradient —
17
+ // a single pale stop reads as a white void with blue "hiding" up top.
18
+ let base = mix(background, sky, smoothstep(-0.02, 0.14, dirY));
19
+ base = mix(base, skyDeep, smoothstep(0.1, 0.55, dirY));
20
+ // Haze as an exponential glow hugging the horizon tightly: C¹-smooth on
21
+ // both sides, so it brightens the junction without ever drawing an edge.
22
+ const hazeWeight = exp(abs(dirY).mul(-11)).mul(0.8);
23
+ return mix(base, haze, hazeWeight);
24
+ }
25
+ // Warm sun tint the haze pulls toward — aerial perspective is sky-coloured
26
+ // light plus a little sun scatter, not white fog.
27
+ const HAZE_SUN_TINT = [255, 244, 222];
28
+ /**
29
+ * Atmospheric haze at the horizon: the theme's *sky* colour pulled toward a
30
+ * warm sun tint — skyish and sunish at once, so the band reads as part of
31
+ * the sky rather than a white stripe. Dark themes keep it faint (a low glow
32
+ * over the night zenith).
33
+ */
34
+ export function horizonHazeColor(sky, appearance) {
35
+ const amount = appearance === 'dark' ? 0.25 : 0.5;
36
+ const hex = sky.replace('#', '');
37
+ let out = '#';
38
+ for (let i = 0; i < 3; i++) {
39
+ const c = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
40
+ out += Math.round(c + (HAZE_SUN_TINT[i] - c) * amount)
41
+ .toString(16)
42
+ .padStart(2, '0');
43
+ }
44
+ return out;
45
+ }
46
+ /**
47
+ * Zenith colour derived from the theme's sky: saturated and darkened in HSL
48
+ * so the hue stays the theme's own (blue studio, lavender sunset, near-black
49
+ * night) while the top of the frame gets real colour depth.
50
+ */
51
+ export function deepSkyColor(sky) {
52
+ const hex = sky.replace('#', '');
53
+ const r = Number.parseInt(hex.slice(0, 2), 16) / 255;
54
+ const g = Number.parseInt(hex.slice(2, 4), 16) / 255;
55
+ const b = Number.parseInt(hex.slice(4, 6), 16) / 255;
56
+ const max = Math.max(r, g, b);
57
+ const min = Math.min(r, g, b);
58
+ const l = (max + min) / 2;
59
+ const d = max - min;
60
+ let h = 0;
61
+ let s = 0;
62
+ if (d > 0) {
63
+ s = d / (1 - Math.abs(2 * l - 1));
64
+ if (max === r)
65
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
66
+ else if (max === g)
67
+ h = ((b - r) / d + 2) / 6;
68
+ else
69
+ h = ((r - g) / d + 4) / 6;
70
+ }
71
+ const s2 = Math.min(1, s * 1.5 + 0.05);
72
+ const l2 = l * 0.72;
73
+ const c = (1 - Math.abs(2 * l2 - 1)) * s2;
74
+ const x = c * (1 - Math.abs(((h * 6) % 2) - 1));
75
+ const m = l2 - c / 2;
76
+ const sector = Math.floor(h * 6) % 6;
77
+ const rgb = [
78
+ [c, x, 0],
79
+ [x, c, 0],
80
+ [0, c, x],
81
+ [0, x, c],
82
+ [x, 0, c],
83
+ [c, 0, x],
84
+ ][sector];
85
+ let out = '#';
86
+ for (const channel of rgb) {
87
+ out += Math.round((channel + m) * 255)
88
+ .toString(16)
89
+ .padStart(2, '0');
90
+ }
91
+ return out;
92
+ }
@@ -0,0 +1,13 @@
1
+ import type { BoxGeometry } from 'three';
2
+ /**
3
+ * Rewrite a default `BoxGeometry`'s UVs to world scale — 1 UV unit = 1 metre —
4
+ * so tiled finishes (with `repeat` in tiles-per-metre) render at a consistent
5
+ * real-world scale instead of stretching to fit each face. Matches the
6
+ * world-scale UV convention used by the procedural slab/wall geometry.
7
+ *
8
+ * three.js builds box faces in the fixed order [+X, -X, +Y, -Y, +Z, -Z], four
9
+ * verts each, with UVs spanning 0→1 across the face. Each face's two in-plane
10
+ * dimensions differ, so we scale U/V per face by that face's size in metres.
11
+ */
12
+ export declare function applyWorldScaleBoxUVs(geometry: BoxGeometry, w: number, h: number, d: number): void;
13
+ //# sourceMappingURL=box-uv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box-uv.d.ts","sourceRoot":"","sources":["../../src/lib/box-uv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAExC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EACrB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,IAAI,CAsBN"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Rewrite a default `BoxGeometry`'s UVs to world scale — 1 UV unit = 1 metre —
3
+ * so tiled finishes (with `repeat` in tiles-per-metre) render at a consistent
4
+ * real-world scale instead of stretching to fit each face. Matches the
5
+ * world-scale UV convention used by the procedural slab/wall geometry.
6
+ *
7
+ * three.js builds box faces in the fixed order [+X, -X, +Y, -Y, +Z, -Z], four
8
+ * verts each, with UVs spanning 0→1 across the face. Each face's two in-plane
9
+ * dimensions differ, so we scale U/V per face by that face's size in metres.
10
+ */
11
+ export function applyWorldScaleBoxUVs(geometry, w, h, d) {
12
+ const uv = geometry.getAttribute('uv');
13
+ if (!uv || uv.count < 24)
14
+ return; // non-default segmentation — leave as-is
15
+ // [uScaleMetres, vScaleMetres] per face, in three's face order.
16
+ const faceScale = [
17
+ [d, h], // +X
18
+ [d, h], // -X
19
+ [w, d], // +Y
20
+ [w, d], // -Y
21
+ [w, h], // +Z
22
+ [w, h], // -Z
23
+ ];
24
+ for (let face = 0; face < 6; face += 1) {
25
+ const [us, vs] = faceScale[face];
26
+ for (let v = 0; v < 4; v += 1) {
27
+ const i = face * 4 + v;
28
+ uv.setXY(i, uv.getX(i) * us, uv.getY(i) * vs);
29
+ }
30
+ }
31
+ uv.needsUpdate = true;
32
+ }
@@ -1,16 +1,10 @@
1
- import type * as THREE from 'three';
1
+ import * as THREE from 'three';
2
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
- */
3
+ export declare function ensureRenderableGeometryAttributes(geometry: THREE.BufferGeometry): THREE.BufferGeometry;
10
4
  export declare function csgGeometry(brush: Brush): THREE.BufferGeometry;
11
5
  export declare function csgMaterials(brush: Brush): THREE.Material[];
12
6
  export declare const csgEvaluator: Evaluator;
13
7
  export declare function computeGeometryBoundsTree(geometry: THREE.BufferGeometry): void;
14
8
  export declare function prepareBrushForCSG(brush: Brush): void;
15
- export { ADDITION, Brush, SUBTRACTION } from 'three-bvh-csg';
9
+ export { ADDITION, Brush, INTERSECTION, SUBTRACTION } from 'three-bvh-csg';
16
10
  //# sourceMappingURL=csg-utils.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"csg-utils.d.ts","sourceRoot":"","sources":["../../src/lib/csg-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,KAAK,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AA4CrD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,KAAK,CAAC,cAAc,GAC7B,KAAK,CAAC,cAAc,CAoCtB;AAED,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,QAI9C;AAID,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}