@pascal-app/viewer 0.8.0 → 0.9.2

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 (284) hide show
  1. package/dist/components/error-boundary.d.ts +6 -0
  2. package/dist/components/error-boundary.d.ts.map +1 -1
  3. package/dist/components/error-boundary.js +6 -0
  4. package/dist/components/renderers/node-renderer.d.ts +6 -2
  5. package/dist/components/renderers/node-renderer.d.ts.map +1 -1
  6. package/dist/components/renderers/node-renderer.js +41 -22
  7. package/dist/components/renderers/parametric-node-renderer.d.ts +5 -0
  8. package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -0
  9. package/dist/components/renderers/parametric-node-renderer.js +37 -0
  10. package/dist/components/renderers/scene-renderer.d.ts +1 -1
  11. package/dist/components/renderers/scene-renderer.d.ts.map +1 -1
  12. package/dist/components/viewer/bvh-ecctrl.d.ts +77 -0
  13. package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -0
  14. package/dist/components/viewer/bvh-ecctrl.js +552 -0
  15. package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
  16. package/dist/components/viewer/frame-limiter.js +39 -4
  17. package/dist/components/viewer/glb-interactive.d.ts +41 -0
  18. package/dist/components/viewer/glb-interactive.d.ts.map +1 -0
  19. package/dist/components/viewer/glb-interactive.js +394 -0
  20. package/dist/components/viewer/glb-reference-nodes.d.ts +29 -0
  21. package/dist/components/viewer/glb-reference-nodes.d.ts.map +1 -0
  22. package/dist/components/viewer/glb-reference-nodes.js +80 -0
  23. package/dist/components/viewer/glb-replace-instances.d.ts +18 -0
  24. package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -0
  25. package/dist/components/viewer/glb-replace-instances.js +61 -0
  26. package/dist/components/viewer/glb-scene.d.ts +54 -0
  27. package/dist/components/viewer/glb-scene.d.ts.map +1 -0
  28. package/dist/components/viewer/glb-scene.js +920 -0
  29. package/dist/components/viewer/glb-walkthrough-controller.d.ts +12 -0
  30. package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -0
  31. package/dist/components/viewer/glb-walkthrough-controller.js +357 -0
  32. package/dist/components/viewer/index.d.ts +56 -3
  33. package/dist/components/viewer/index.d.ts.map +1 -1
  34. package/dist/components/viewer/index.js +280 -65
  35. package/dist/components/viewer/lights.d.ts +1 -1
  36. package/dist/components/viewer/lights.d.ts.map +1 -1
  37. package/dist/components/viewer/lights.js +201 -43
  38. package/dist/components/viewer/perf-monitor.d.ts +1 -1
  39. package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
  40. package/dist/components/viewer/perf-monitor.js +115 -12
  41. package/dist/components/viewer/post-processing.d.ts +7 -1
  42. package/dist/components/viewer/post-processing.d.ts.map +1 -1
  43. package/dist/components/viewer/post-processing.js +395 -63
  44. package/dist/components/viewer/registered-systems.d.ts +12 -0
  45. package/dist/components/viewer/registered-systems.d.ts.map +1 -0
  46. package/dist/components/viewer/registered-systems.js +49 -0
  47. package/dist/components/viewer/scene-bvh.d.ts +18 -0
  48. package/dist/components/viewer/scene-bvh.d.ts.map +1 -0
  49. package/dist/components/viewer/scene-bvh.js +97 -0
  50. package/dist/components/viewer/scene-bvh.test.d.ts +2 -0
  51. package/dist/components/viewer/scene-bvh.test.d.ts.map +1 -0
  52. package/dist/components/viewer/scene-bvh.test.js +13 -0
  53. package/dist/components/viewer/scene-environment.d.ts +2 -0
  54. package/dist/components/viewer/scene-environment.d.ts.map +1 -0
  55. package/dist/components/viewer/scene-environment.js +79 -0
  56. package/dist/components/viewer/selection-manager.d.ts +1 -1
  57. package/dist/components/viewer/selection-manager.d.ts.map +1 -1
  58. package/dist/components/viewer/selection-manager.js +37 -14
  59. package/dist/components/viewer/viewer-camera.d.ts +1 -1
  60. package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
  61. package/dist/components/viewer/walkthrough-controls.d.ts +2 -1
  62. package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
  63. package/dist/components/viewer/walkthrough-controls.js +20 -0
  64. package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
  65. package/dist/hooks/use-gltf-ktx2.js +3 -22
  66. package/dist/hooks/use-node-events.d.ts +6 -74
  67. package/dist/hooks/use-node-events.d.ts.map +1 -1
  68. package/dist/hooks/use-node-events.js +28 -8
  69. package/dist/index.d.ts +48 -5
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +82 -4
  72. package/dist/lib/backdrop.d.ts +33 -0
  73. package/dist/lib/backdrop.d.ts.map +1 -0
  74. package/dist/lib/backdrop.js +92 -0
  75. package/dist/lib/box-uv.d.ts +13 -0
  76. package/dist/lib/box-uv.d.ts.map +1 -0
  77. package/dist/lib/box-uv.js +32 -0
  78. package/dist/lib/csg-utils.d.ts +10 -0
  79. package/dist/lib/csg-utils.d.ts.map +1 -0
  80. package/dist/lib/csg-utils.js +93 -0
  81. package/dist/lib/csg-utils.test.d.ts +2 -0
  82. package/dist/lib/csg-utils.test.d.ts.map +1 -0
  83. package/dist/lib/csg-utils.test.js +45 -0
  84. package/dist/lib/drawable-geometry.d.ts +21 -0
  85. package/dist/lib/drawable-geometry.d.ts.map +1 -0
  86. package/dist/lib/drawable-geometry.js +22 -0
  87. package/dist/lib/edge-style.d.ts +4 -0
  88. package/dist/lib/edge-style.d.ts.map +1 -0
  89. package/dist/lib/edge-style.js +31 -0
  90. package/dist/lib/gpu-perf.d.ts +4 -0
  91. package/dist/lib/gpu-perf.d.ts.map +1 -0
  92. package/dist/lib/gpu-perf.js +23 -0
  93. package/dist/lib/ink-edges.d.ts +9 -0
  94. package/dist/lib/ink-edges.d.ts.map +1 -0
  95. package/dist/lib/ink-edges.js +49 -0
  96. package/dist/lib/isolation.d.ts +39 -0
  97. package/dist/lib/isolation.d.ts.map +1 -0
  98. package/dist/lib/isolation.js +103 -0
  99. package/dist/lib/ktx2-loader.d.ts +43 -0
  100. package/dist/lib/ktx2-loader.d.ts.map +1 -0
  101. package/dist/lib/ktx2-loader.js +136 -0
  102. package/dist/lib/layers.d.ts +28 -0
  103. package/dist/lib/layers.d.ts.map +1 -1
  104. package/dist/lib/layers.js +28 -0
  105. package/dist/lib/materials.d.ts +38 -15
  106. package/dist/lib/materials.d.ts.map +1 -1
  107. package/dist/lib/materials.js +364 -72
  108. package/dist/lib/merged-outline-node.d.ts.map +1 -1
  109. package/dist/lib/merged-outline-node.js +7 -0
  110. package/dist/lib/polygon-union.d.ts +4 -0
  111. package/dist/lib/polygon-union.d.ts.map +1 -0
  112. package/dist/lib/polygon-union.js +289 -0
  113. package/dist/lib/polygon-union.test.d.ts +2 -0
  114. package/dist/lib/polygon-union.test.d.ts.map +1 -0
  115. package/dist/lib/polygon-union.test.js +105 -0
  116. package/dist/lib/scene-themes.d.ts +30 -0
  117. package/dist/lib/scene-themes.d.ts.map +1 -0
  118. package/dist/lib/scene-themes.js +202 -0
  119. package/dist/lib/shadow-only.d.ts +4 -0
  120. package/dist/lib/shadow-only.d.ts.map +1 -0
  121. package/dist/lib/shadow-only.js +36 -0
  122. package/dist/lib/tsl-compat.d.ts +12 -0
  123. package/dist/lib/tsl-compat.d.ts.map +1 -0
  124. package/dist/lib/tsl-compat.js +13 -0
  125. package/dist/store/use-viewer.d.ts +92 -12
  126. package/dist/store/use-viewer.d.ts.map +1 -1
  127. package/dist/store/use-viewer.js +201 -6
  128. package/dist/store/use-viewer.test.d.ts +2 -0
  129. package/dist/store/use-viewer.test.d.ts.map +1 -0
  130. package/dist/store/use-viewer.test.js +42 -0
  131. package/dist/systems/ceiling/ceiling-system.d.ts +6 -2
  132. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  133. package/dist/systems/ceiling/ceiling-system.js +66 -13
  134. package/dist/systems/door/door-animation.test.d.ts +2 -0
  135. package/dist/systems/door/door-animation.test.d.ts.map +1 -0
  136. package/dist/systems/door/door-animation.test.js +51 -0
  137. package/dist/systems/door/door-floor-alignment.test.d.ts +2 -0
  138. package/dist/systems/door/door-floor-alignment.test.d.ts.map +1 -0
  139. package/dist/systems/door/door-floor-alignment.test.js +50 -0
  140. package/dist/systems/door/door-system.d.ts +24 -0
  141. package/dist/systems/door/door-system.d.ts.map +1 -1
  142. package/dist/systems/door/door-system.js +864 -180
  143. package/dist/systems/elevator/elevator-interaction-system.d.ts +2 -0
  144. package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -0
  145. package/dist/systems/elevator/elevator-interaction-system.js +62 -0
  146. package/dist/systems/fence/fence-system.d.ts +20 -0
  147. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  148. package/dist/systems/fence/fence-system.js +229 -57
  149. package/dist/systems/floor-elevation/floor-elevation-system.d.ts +20 -0
  150. package/dist/systems/floor-elevation/floor-elevation-system.d.ts.map +1 -0
  151. package/dist/systems/floor-elevation/floor-elevation-system.js +78 -0
  152. package/dist/systems/geometry/geometry-system.d.ts +41 -0
  153. package/dist/systems/geometry/geometry-system.d.ts.map +1 -0
  154. package/dist/systems/geometry/geometry-system.js +348 -0
  155. package/dist/systems/geometry/geometry-system.test.d.ts +2 -0
  156. package/dist/systems/geometry/geometry-system.test.d.ts.map +1 -0
  157. package/dist/systems/geometry/geometry-system.test.js +30 -0
  158. package/dist/systems/interactive/control-widget.d.ts +10 -0
  159. package/dist/systems/interactive/control-widget.d.ts.map +1 -0
  160. package/dist/systems/interactive/control-widget.js +35 -0
  161. package/dist/systems/interactive/interactive-system.d.ts +1 -1
  162. package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
  163. package/dist/systems/interactive/interactive-system.js +55 -56
  164. package/dist/systems/item/item-system.d.ts +7 -0
  165. package/dist/systems/item/item-system.d.ts.map +1 -1
  166. package/dist/systems/item/item-system.js +28 -17
  167. package/dist/systems/item-light/item-light-system.d.ts +1 -1
  168. package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
  169. package/dist/systems/item-light/item-light-system.js +18 -5
  170. package/dist/systems/level/level-system.d.ts.map +1 -1
  171. package/dist/systems/level/level-system.js +28 -4
  172. package/dist/systems/level/level-utils.d.ts +0 -3
  173. package/dist/systems/level/level-utils.d.ts.map +1 -1
  174. package/dist/systems/level/level-utils.js +2 -41
  175. package/dist/systems/roof/roof-materials.d.ts +3 -2
  176. package/dist/systems/roof/roof-materials.d.ts.map +1 -1
  177. package/dist/systems/roof/roof-materials.js +59 -14
  178. package/dist/systems/roof/roof-system.d.ts +46 -6
  179. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  180. package/dist/systems/roof/roof-system.js +1365 -170
  181. package/dist/systems/slab/slab-system.d.ts +5 -3
  182. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  183. package/dist/systems/slab/slab-system.js +204 -68
  184. package/dist/systems/slab/slab-system.test.d.ts +2 -0
  185. package/dist/systems/slab/slab-system.test.d.ts.map +1 -0
  186. package/dist/systems/slab/slab-system.test.js +63 -0
  187. package/dist/systems/stair/stair-materials.d.ts +4 -3
  188. package/dist/systems/stair/stair-materials.d.ts.map +1 -1
  189. package/dist/systems/stair/stair-materials.js +30 -15
  190. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  191. package/dist/systems/stair/stair-system.js +55 -63
  192. package/dist/systems/surface-hole-geometry.d.ts +3 -0
  193. package/dist/systems/surface-hole-geometry.d.ts.map +1 -0
  194. package/dist/systems/surface-hole-geometry.js +4 -0
  195. package/dist/systems/wall/opening-cutout-geometry.d.ts +31 -0
  196. package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -0
  197. package/dist/systems/wall/opening-cutout-geometry.js +167 -0
  198. package/dist/systems/wall/opening-cutout-geometry.test.d.ts +2 -0
  199. package/dist/systems/wall/opening-cutout-geometry.test.d.ts.map +1 -0
  200. package/dist/systems/wall/opening-cutout-geometry.test.js +172 -0
  201. package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
  202. package/dist/systems/wall/wall-cutout.js +62 -17
  203. package/dist/systems/wall/wall-materials.d.ts +12 -7
  204. package/dist/systems/wall/wall-materials.d.ts.map +1 -1
  205. package/dist/systems/wall/wall-materials.js +279 -46
  206. package/dist/systems/wall/wall-opening-cutout.test.d.ts +2 -0
  207. package/dist/systems/wall/wall-opening-cutout.test.d.ts.map +1 -0
  208. package/dist/systems/wall/wall-opening-cutout.test.js +59 -0
  209. package/dist/systems/wall/wall-support-extension.test.d.ts +2 -0
  210. package/dist/systems/wall/wall-support-extension.test.d.ts.map +1 -0
  211. package/dist/systems/wall/wall-support-extension.test.js +48 -0
  212. package/dist/systems/wall/wall-system.d.ts +2 -2
  213. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  214. package/dist/systems/wall/wall-system.js +493 -193
  215. package/dist/systems/window/window-animation-system.d.ts +12 -0
  216. package/dist/systems/window/window-animation-system.d.ts.map +1 -1
  217. package/dist/systems/window/window-animation-system.js +16 -5
  218. package/dist/systems/window/window-system.d.ts +7 -0
  219. package/dist/systems/window/window-system.d.ts.map +1 -1
  220. package/dist/systems/window/window-system.js +308 -18
  221. package/package.json +5 -6
  222. package/dist/components/renderers/building/building-renderer.d.ts +0 -5
  223. package/dist/components/renderers/building/building-renderer.d.ts.map +0 -1
  224. package/dist/components/renderers/building/building-renderer.js +0 -11
  225. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts +0 -5
  226. package/dist/components/renderers/ceiling/ceiling-renderer.d.ts.map +0 -1
  227. package/dist/components/renderers/ceiling/ceiling-renderer.js +0 -58
  228. package/dist/components/renderers/column/column-renderer.d.ts +0 -5
  229. package/dist/components/renderers/column/column-renderer.d.ts.map +0 -1
  230. package/dist/components/renderers/column/column-renderer.js +0 -597
  231. package/dist/components/renderers/door/door-renderer.d.ts +0 -5
  232. package/dist/components/renderers/door/door-renderer.d.ts.map +0 -1
  233. package/dist/components/renderers/door/door-renderer.js +0 -16
  234. package/dist/components/renderers/fence/fence-renderer.d.ts +0 -5
  235. package/dist/components/renderers/fence/fence-renderer.d.ts.map +0 -1
  236. package/dist/components/renderers/fence/fence-renderer.js +0 -15
  237. package/dist/components/renderers/guide/guide-renderer.d.ts +0 -5
  238. package/dist/components/renderers/guide/guide-renderer.d.ts.map +0 -1
  239. package/dist/components/renderers/guide/guide-renderer.js +0 -38
  240. package/dist/components/renderers/item/item-renderer.d.ts +0 -5
  241. package/dist/components/renderers/item/item-renderer.d.ts.map +0 -1
  242. package/dist/components/renderers/item/item-renderer.js +0 -172
  243. package/dist/components/renderers/level/level-renderer.d.ts +0 -5
  244. package/dist/components/renderers/level/level-renderer.d.ts.map +0 -1
  245. package/dist/components/renderers/level/level-renderer.js +0 -11
  246. package/dist/components/renderers/roof/roof-materials.d.ts +0 -4
  247. package/dist/components/renderers/roof/roof-materials.d.ts.map +0 -1
  248. package/dist/components/renderers/roof/roof-materials.js +0 -16
  249. package/dist/components/renderers/roof/roof-renderer.d.ts +0 -5
  250. package/dist/components/renderers/roof/roof-renderer.d.ts.map +0 -1
  251. package/dist/components/renderers/roof/roof-renderer.js +0 -32
  252. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts +0 -5
  253. package/dist/components/renderers/roof-segment/roof-segment-renderer.d.ts.map +0 -1
  254. package/dist/components/renderers/roof-segment/roof-segment-renderer.js +0 -40
  255. package/dist/components/renderers/scan/scan-renderer.d.ts +0 -5
  256. package/dist/components/renderers/scan/scan-renderer.d.ts.map +0 -1
  257. package/dist/components/renderers/scan/scan-renderer.js +0 -54
  258. package/dist/components/renderers/site/site-renderer.d.ts +0 -5
  259. package/dist/components/renderers/site/site-renderer.d.ts.map +0 -1
  260. package/dist/components/renderers/site/site-renderer.js +0 -106
  261. package/dist/components/renderers/slab/slab-renderer.d.ts +0 -5
  262. package/dist/components/renderers/slab/slab-renderer.d.ts.map +0 -1
  263. package/dist/components/renderers/slab/slab-renderer.js +0 -58
  264. package/dist/components/renderers/spawn/spawn-renderer.d.ts +0 -5
  265. package/dist/components/renderers/spawn/spawn-renderer.d.ts.map +0 -1
  266. package/dist/components/renderers/spawn/spawn-renderer.js +0 -32
  267. package/dist/components/renderers/stair/stair-renderer.d.ts +0 -5
  268. package/dist/components/renderers/stair/stair-renderer.d.ts.map +0 -1
  269. package/dist/components/renderers/stair/stair-renderer.js +0 -603
  270. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts +0 -5
  271. package/dist/components/renderers/stair-segment/stair-segment-renderer.d.ts.map +0 -1
  272. package/dist/components/renderers/stair-segment/stair-segment-renderer.js +0 -51
  273. package/dist/components/renderers/wall/wall-renderer.d.ts +0 -5
  274. package/dist/components/renderers/wall/wall-renderer.d.ts.map +0 -1
  275. package/dist/components/renderers/wall/wall-renderer.js +0 -16
  276. package/dist/components/renderers/window/window-renderer.d.ts +0 -5
  277. package/dist/components/renderers/window/window-renderer.d.ts.map +0 -1
  278. package/dist/components/renderers/window/window-renderer.js +0 -21
  279. package/dist/components/renderers/zone/zone-renderer.d.ts +0 -5
  280. package/dist/components/renderers/zone/zone-renderer.d.ts.map +0 -1
  281. package/dist/components/renderers/zone/zone-renderer.js +0 -181
  282. package/dist/components/viewer/ground-occluder.d.ts +0 -2
  283. package/dist/components/viewer/ground-occluder.d.ts.map +0 -1
  284. package/dist/components/viewer/ground-occluder.js +0 -79
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createSceneApi, isNodeKindEnabled, nodeRegistry, useScene, } from '@pascal-app/core';
4
+ import { lazy, Suspense, useMemo } from 'react';
5
+ const DEFAULT_PRIORITY = 5;
6
+ const lazyCache = new WeakMap();
7
+ function loadSystem(def) {
8
+ if (!def.system)
9
+ return null;
10
+ const cached = lazyCache.get(def.system.module);
11
+ if (cached)
12
+ return cached;
13
+ const Comp = lazy(def.system.module);
14
+ lazyCache.set(def.system.module, Comp);
15
+ return Comp;
16
+ }
17
+ /**
18
+ * Mounts every registered node kind's system component, ordered by
19
+ * `system.priority` (default {@link DEFAULT_PRIORITY}).
20
+ *
21
+ * Today the registry is empty so this component mounts nothing — coexists
22
+ * with legacy `*-System` components in `<Viewer>`. Once kinds register via
23
+ * `@pascal-app/nodes`, each kind's registry-driven system takes over and
24
+ * its legacy counterpart short-circuits via the `nodeRegistry.has(kind)`
25
+ * guard added to each legacy system.
26
+ */
27
+ export function RegisteredSystems() {
28
+ const sceneApi = useMemo(() => createSceneApi(useScene), []);
29
+ const installedPlugins = useScene((state) => state.installedPlugins);
30
+ const entries = useMemo(() => {
31
+ return Array.from(nodeRegistry.entries())
32
+ .filter(([, def]) => def.system != null)
33
+ .sort(([, a], [, b]) => {
34
+ const pa = a.system?.priority ?? DEFAULT_PRIORITY;
35
+ const pb = b.system?.priority ?? DEFAULT_PRIORITY;
36
+ return pa - pb;
37
+ });
38
+ }, []);
39
+ if (entries.length === 0)
40
+ return null;
41
+ return (_jsx(Suspense, { fallback: null, children: entries.map(([kind, def]) => {
42
+ if (!isNodeKindEnabled(kind, installedPlugins))
43
+ return null;
44
+ const Comp = loadSystem(def);
45
+ if (!Comp)
46
+ return null;
47
+ return _jsx(Comp, { sceneApi: sceneApi }, `registered-system:${kind}`);
48
+ }) }));
49
+ }
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type Group, Mesh } from 'three';
3
+ import { type SplitStrategy } from 'three-mesh-bvh';
4
+ type SceneBvhProps = {
5
+ children?: ReactNode;
6
+ enabled?: boolean;
7
+ firstHitOnly?: boolean;
8
+ strategy?: SplitStrategy;
9
+ verbose?: boolean;
10
+ setBoundingBox?: boolean;
11
+ maxDepth?: number;
12
+ maxLeafSize?: number;
13
+ indirect?: boolean;
14
+ };
15
+ export declare const isSceneBvhExcluded: (object: Mesh) => boolean;
16
+ export declare const SceneBvh: import("react").ForwardRefExoticComponent<SceneBvhProps & import("react").RefAttributes<Group<import("three").Object3DEventMap>>>;
17
+ export {};
18
+ //# sourceMappingURL=scene-bvh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-bvh.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-bvh.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,SAAS,EAA0C,MAAM,OAAO,CAAA;AAC1F,OAAO,EAAuB,KAAK,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAA;AAEvB,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAKD,eAAO,MAAM,kBAAkB,GAAI,QAAQ,IAAI,YAA4C,CAAA;AAY3F,eAAO,MAAM,QAAQ,mIAoGpB,CAAA"}
@@ -0,0 +1,97 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useThree } from '@react-three/fiber';
3
+ import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
4
+ import { Mesh } from 'three';
5
+ import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree, SAH, } from 'three-mesh-bvh';
6
+ const isMesh = (object) => !!object && typeof object === 'object' && object.isMesh === true;
7
+ export const isSceneBvhExcluded = (object) => object.userData.excludeFromBvh === true;
8
+ const hasBvhCompatibleGeometry = (geometry) => {
9
+ if (!geometry)
10
+ return false;
11
+ const position = geometry.getAttribute('position');
12
+ if (!position)
13
+ return false;
14
+ const vertexCount = geometry.getIndex()?.count ?? position.count;
15
+ return vertexCount >= 3;
16
+ };
17
+ export const SceneBvh = forwardRef(({ children, enabled = true, firstHitOnly = false, strategy = SAH, verbose = false, setBoundingBox = true, maxDepth = 40, maxLeafSize = 10, indirect = false, }, forwardedRef) => {
18
+ const ref = useRef(null);
19
+ const raycaster = useThree((state) => state.raycaster);
20
+ useImperativeHandle(forwardedRef, () => ref.current, []);
21
+ useEffect(() => {
22
+ if (!enabled || !ref.current)
23
+ return;
24
+ const options = {
25
+ strategy,
26
+ verbose,
27
+ setBoundingBox,
28
+ maxDepth,
29
+ maxLeafSize,
30
+ indirect,
31
+ };
32
+ const group = ref.current;
33
+ const acceleratedMeshes = new Set();
34
+ const computedGeometries = new Set();
35
+ raycaster.firstHitOnly = firstHitOnly;
36
+ group.traverse((child) => {
37
+ if (!isMesh(child))
38
+ return;
39
+ if (isSceneBvhExcluded(child))
40
+ return;
41
+ if (child.raycast === Mesh.prototype.raycast) {
42
+ child.raycast = acceleratedRaycast;
43
+ acceleratedMeshes.add(child);
44
+ }
45
+ if (child.raycast !== acceleratedRaycast)
46
+ return;
47
+ const geometry = child.geometry;
48
+ if (geometry.boundsTree || !hasBvhCompatibleGeometry(geometry))
49
+ return;
50
+ try {
51
+ // The three-mesh-bvh + @types/three combo doesn't agree on
52
+ // BVH option / class identity (ComputeBVHOptions vs
53
+ // MeshBVHOptions, GeometryBVH vs MeshBVH) — cast through
54
+ // `unknown` to bypass the structural mismatch. Runtime is
55
+ // fine; we're just calling the library's own helpers.
56
+ ;
57
+ geometry.computeBoundsTree =
58
+ computeBoundsTree;
59
+ geometry.disposeBoundsTree =
60
+ disposeBoundsTree;
61
+ geometry.computeBoundsTree(options);
62
+ computedGeometries.add(geometry);
63
+ }
64
+ catch (error) {
65
+ console.warn('[viewer] Skipping BVH for incompatible mesh geometry.', {
66
+ mesh: child.name || child.type,
67
+ error,
68
+ });
69
+ }
70
+ });
71
+ return () => {
72
+ delete raycaster.firstHitOnly;
73
+ for (const geometry of computedGeometries) {
74
+ if (geometry.boundsTree) {
75
+ geometry.disposeBoundsTree();
76
+ }
77
+ }
78
+ for (const mesh of acceleratedMeshes) {
79
+ if (mesh.raycast === acceleratedRaycast) {
80
+ mesh.raycast = Mesh.prototype.raycast;
81
+ }
82
+ }
83
+ };
84
+ }, [
85
+ enabled,
86
+ firstHitOnly,
87
+ strategy,
88
+ verbose,
89
+ setBoundingBox,
90
+ maxDepth,
91
+ maxLeafSize,
92
+ indirect,
93
+ raycaster,
94
+ ]);
95
+ return _jsx("group", { ref: ref, children: children });
96
+ });
97
+ SceneBvh.displayName = 'SceneBvh';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scene-bvh.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-bvh.test.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-bvh.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ // @ts-expect-error — bun:test is provided by the Bun runtime; viewer does not
2
+ // include Bun ambient types in its production declaration build.
3
+ import { describe, expect, test } from 'bun:test';
4
+ import { Mesh } from 'three';
5
+ import { isSceneBvhExcluded } from './scene-bvh';
6
+ describe('scene BVH exclusions', () => {
7
+ test('keeps annotation meshes on their normal raycast path', () => {
8
+ expect(isSceneBvhExcluded(new Mesh())).toBe(false);
9
+ const annotation = new Mesh();
10
+ annotation.userData.excludeFromBvh = true;
11
+ expect(isSceneBvhExcluded(annotation)).toBe(true);
12
+ });
13
+ });
@@ -0,0 +1,2 @@
1
+ export declare function SceneEnvironment(): null;
2
+ //# sourceMappingURL=scene-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-environment.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/scene-environment.tsx"],"names":[],"mappings":"AAmEA,wBAAgB,gBAAgB,SAkB/B"}
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { useThree } from '@react-three/fiber';
3
+ import { useEffect, useMemo } from 'react';
4
+ import * as THREE from 'three/webgpu';
5
+ import { getSceneTheme } from '../../lib/scene-themes';
6
+ import useViewer from '../../store/use-viewer';
7
+ /**
8
+ * Scene IBL — a small procedural gradient sky (cool zenith → warm horizon →
9
+ * dim ground bounce) used purely as the environment light source. The visible
10
+ * backdrop stays the flat theme background (composited in post-processing);
11
+ * this texture is never shown. Replaces the old `venice_sunset_1k.hdr` fetch:
12
+ * no network dependency, and the vertical color split means upward-facing
13
+ * surfaces read cooler than vertical ones instead of everything getting the
14
+ * same directionless warm wash. Exported as an opt-in <Viewer> child so
15
+ * embed / thumbnail surfaces that don't want IBL simply don't mount it.
16
+ * Only affects `rendered` shading (Lambert ignores env maps).
17
+ */
18
+ // Linear-space gradient stops.
19
+ const ZENITH = [0.4, 0.56, 0.78];
20
+ const HORIZON = [0.95, 0.84, 0.66];
21
+ const GROUND = [0.38, 0.35, 0.3];
22
+ const ENV_INTENSITY = 0.6;
23
+ // The gradient sky is a daylight source; dark themes only want a whisper of it.
24
+ const ENV_INTENSITY_DARK = 0.2;
25
+ const WIDTH = 64;
26
+ const HEIGHT = 32;
27
+ function buildGradientSky() {
28
+ const data = new Float32Array(WIDTH * HEIGHT * 4);
29
+ for (let y = 0; y < HEIGHT; y++) {
30
+ // Row 0 = v0 = nadir, top row = zenith (equirect v spans -90°..+90°).
31
+ const lat = ((y + 0.5) / HEIGHT) * 2 - 1;
32
+ let r;
33
+ let g;
34
+ let b;
35
+ if (lat <= 0) {
36
+ // Below the horizon: flat ground bounce, slightly darker toward nadir.
37
+ const k = 1 + lat * 0.35;
38
+ r = GROUND[0] * k;
39
+ g = GROUND[1] * k;
40
+ b = GROUND[2] * k;
41
+ }
42
+ else {
43
+ // pow < 1 widens the warm horizon band.
44
+ const t = lat ** 0.65;
45
+ r = HORIZON[0] + (ZENITH[0] - HORIZON[0]) * t;
46
+ g = HORIZON[1] + (ZENITH[1] - HORIZON[1]) * t;
47
+ b = HORIZON[2] + (ZENITH[2] - HORIZON[2]) * t;
48
+ }
49
+ for (let x = 0; x < WIDTH; x++) {
50
+ const i = (y * WIDTH + x) * 4;
51
+ data[i] = r;
52
+ data[i + 1] = g;
53
+ data[i + 2] = b;
54
+ data[i + 3] = 1;
55
+ }
56
+ }
57
+ const texture = new THREE.DataTexture(data, WIDTH, HEIGHT, THREE.RGBAFormat, THREE.FloatType);
58
+ texture.mapping = THREE.EquirectangularReflectionMapping;
59
+ texture.colorSpace = THREE.LinearSRGBColorSpace;
60
+ texture.needsUpdate = true;
61
+ return texture;
62
+ }
63
+ export function SceneEnvironment() {
64
+ const scene = useThree((state) => state.scene);
65
+ const texture = useMemo(buildGradientSky, []);
66
+ const appearance = useViewer((state) => getSceneTheme(state.sceneTheme).appearance);
67
+ useEffect(() => {
68
+ const prevEnvironment = scene.environment;
69
+ const prevIntensity = scene.environmentIntensity;
70
+ scene.environment = texture;
71
+ scene.environmentIntensity = appearance === 'dark' ? ENV_INTENSITY_DARK : ENV_INTENSITY;
72
+ return () => {
73
+ scene.environment = prevEnvironment;
74
+ scene.environmentIntensity = prevIntensity;
75
+ texture.dispose();
76
+ };
77
+ }, [scene, texture, appearance]);
78
+ return null;
79
+ }
@@ -1,2 +1,2 @@
1
- export declare const SelectionManager: () => import("react/jsx-runtime").JSX.Element;
1
+ export declare const SelectionManager: () => import("react").JSX.Element;
2
2
  //# sourceMappingURL=selection-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAoSA,eAAO,MAAM,gBAAgB,+CA4E5B,CAAA"}
1
+ {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../../src/components/viewer/selection-manager.tsx"],"names":[],"mappings":"AAiTA,eAAO,MAAM,gBAAgB,mCAqG5B,CAAA"}
@@ -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, 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;
@@ -236,28 +239,43 @@ export const SelectionManager = () => {
236
239
  const strategy = getStrategy();
237
240
  if (!strategy)
238
241
  return;
242
+ // Ceilings are selected via their floor-plan helper and the
243
+ // boundary-editor vertex handles, never via a direct 3D click on
244
+ // the polygon. Skipping selection routing here means a click on a
245
+ // ceiling falls through to the item / wall / floor below it.
246
+ if (event.node.type === 'ceiling')
247
+ return;
239
248
  if (strategy.isValid(event.node)) {
240
249
  event.stopPropagation();
241
250
  if (event.node.type === 'slab') {
242
251
  useViewer.setState({ hoveredId: null });
243
252
  return;
244
253
  }
245
- useViewer.setState({ hoveredId: event.node.id });
254
+ useViewer.setState({
255
+ hoveredId: resolveSelectionProxyId(event.node, useScene.getState().nodes),
256
+ });
246
257
  }
247
258
  };
248
259
  const onLeave = (event) => {
249
260
  const strategy = getStrategy();
250
261
  if (!strategy)
251
262
  return;
263
+ if (event.node.type === 'ceiling')
264
+ return;
252
265
  if (strategy.isValid(event.node)) {
253
266
  event.stopPropagation();
254
- 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
+ }
255
271
  }
256
272
  };
257
273
  const onClick = (event) => {
258
274
  const strategy = getStrategy();
259
275
  if (!strategy)
260
276
  return;
277
+ if (event.node.type === 'ceiling')
278
+ return;
261
279
  if (!strategy.isValid(event.node))
262
280
  return;
263
281
  event.stopPropagation();
@@ -266,7 +284,9 @@ export const SelectionManager = () => {
266
284
  // Clear hover immediately after clicking on building/level/zone
267
285
  useViewer.setState({ hoveredId: null });
268
286
  };
269
- // Subscribe to all node types
287
+ // Subscribe to all node types. Hardcoded kinds + registry-supplied kinds
288
+ // (any NodeDefinition declaring `capabilities.selectable`). Phase 6
289
+ // collapses these into a single registry-driven list.
270
290
  const allTypes = [
271
291
  'building',
272
292
  'level',
@@ -282,13 +302,15 @@ export const SelectionManager = () => {
282
302
  'window',
283
303
  'door',
284
304
  ];
285
- for (const type of allTypes) {
305
+ const registryKinds = getSelectableKinds().filter((k) => !allTypes.includes(k));
306
+ const subscribedKinds = [...allTypes, ...registryKinds];
307
+ for (const type of subscribedKinds) {
286
308
  emitter.on(`${type}:enter`, onEnter);
287
309
  emitter.on(`${type}:leave`, onLeave);
288
310
  emitter.on(`${type}:click`, onClick);
289
311
  }
290
312
  return () => {
291
- for (const type of allTypes) {
313
+ for (const type of subscribedKinds) {
292
314
  emitter.off(`${type}:enter`, onEnter);
293
315
  emitter.off(`${type}:leave`, onLeave);
294
316
  emitter.off(`${type}:click`, onClick);
@@ -302,7 +324,8 @@ const PointerMissedHandler = ({ clickHandledRef, }) => {
302
324
  useEffect(() => {
303
325
  const handleClick = (event) => {
304
326
  // Only handle left clicks
305
- if (useViewer.getState().cameraDragging)
327
+ const viewerState = useViewer.getState();
328
+ if (viewerState.cameraDragging || viewerState.inputDragging)
306
329
  return;
307
330
  if (event.button !== 0)
308
331
  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,3 @@
1
- export declare const WalkthroughControls: () => import("react/jsx-runtime").JSX.Element | null;
1
+ export declare const WALKTHROUGH_FOV = 60;
2
+ export declare const WalkthroughControls: () => import("react").JSX.Element | null;
2
3
  //# 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,eAAe,KAAK,CAAA;AAMjC,eAAO,MAAM,mBAAmB,0CAsI/B,CAAA"}
@@ -7,6 +7,11 @@ import { Vector3 } from 'three';
7
7
  import useViewer from '../../store/use-viewer';
8
8
  const MOVE_SPEED = 5;
9
9
  const EYE_HEIGHT = 1.6;
10
+ // First-person FOV. The orbit camera is 50° (set on the Canvas), which feels
11
+ // cramped on foot; ~60° vertical (~90° horizontal at 16:9) restores peripheral
12
+ // awareness without wide-angle distortion. Applied only while walking — both
13
+ // walkthrough controllers read this and restore the orbit FOV on exit.
14
+ export const WALKTHROUGH_FOV = 60;
10
15
  const _direction = new Vector3();
11
16
  const _forward = new Vector3();
12
17
  const _right = new Vector3();
@@ -21,6 +26,21 @@ export const WalkthroughControls = () => {
21
26
  camera.position.y = EYE_HEIGHT;
22
27
  }
23
28
  }, [walkthroughMode, camera]);
29
+ // Widen FOV while walking; restore the orbit FOV on exit.
30
+ useEffect(() => {
31
+ if (!walkthroughMode)
32
+ return;
33
+ const cam = camera;
34
+ if (!cam.isPerspectiveCamera)
35
+ return;
36
+ const prevFov = cam.fov;
37
+ cam.fov = WALKTHROUGH_FOV;
38
+ cam.updateProjectionMatrix();
39
+ return () => {
40
+ cam.fov = prevFov;
41
+ cam.updateProjectionMatrix();
42
+ };
43
+ }, [walkthroughMode, camera]);
24
44
  // Keyboard handlers
25
45
  useEffect(() => {
26
46
  if (!walkthroughMode)
@@ -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;AAK3C,QAAA,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,UAAU,CAAC,OAAO,OAAO,CAU5D,CAAA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1,32 +1,13 @@
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 { ensureKtx2Support, ktx2Loader } 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)) {
8
+ if (ensureKtx2Support(gl)) {
28
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
- loader.setKTX2Loader(ktx2LoaderInstance);
10
+ loader.setKTX2Loader(ktx2Loader);
30
11
  }
31
12
  loader.setMeshoptDecoder(MeshoptDecoder);
32
13
  });
@@ -1,80 +1,12 @@
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
- onClick: (e: ThreeEvent<PointerEvent>) => void;
9
+ onClick: (_e: ThreeEvent<PointerEvent>) => void;
78
10
  onPointerEnter: (e: ThreeEvent<PointerEvent>) => void;
79
11
  onPointerLeave: (e: ThreeEvent<PointerEvent>) => void;
80
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":"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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;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"}