@pascal-app/editor 1.1.0 → 1.1.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 (262) hide show
  1. package/package.json +9 -15
  2. package/src/components/editor/action-menu-button.tsx +1 -1
  3. package/src/components/editor/alignment-3d-guide-layer.tsx +1 -1
  4. package/src/components/editor/custom-camera-controls.tsx +11 -11
  5. package/src/components/editor/editor-layout-v2.tsx +1 -1
  6. package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
  7. package/src/components/editor/first-person-controls.tsx +20 -1981
  8. package/src/components/editor/floating-action-menu.tsx +1 -1
  9. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  10. package/src/components/editor/floor-region-controls.tsx +6 -2
  11. package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
  12. package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
  13. package/src/components/editor/floorplan-panel.tsx +26 -22
  14. package/src/components/editor/floorplan-wall-typing-keys.ts +1 -1
  15. package/src/components/editor/follow-pascal.test.tsx +1 -2
  16. package/src/components/editor/follow-pascal.tsx +1 -1
  17. package/src/components/editor/footprint-height-handle.tsx +1 -1
  18. package/src/components/editor/group-actions.ts +1 -2
  19. package/src/components/editor/group-floating-action-menu.tsx +1 -1
  20. package/src/components/editor/group-move-3d.ts +1 -2
  21. package/src/components/editor/group-rotate-handle.tsx +1 -2
  22. package/src/components/editor/handles/use-handle-drag.ts +1 -2
  23. package/src/components/editor/index.tsx +24 -14
  24. package/src/components/editor/inspector-extension-actions.tsx +1 -1
  25. package/src/components/editor/node-arrow-handles.tsx +1 -1
  26. package/src/components/editor/open-wall-ends-3d-layer.tsx +1 -1
  27. package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
  28. package/src/components/editor/room-controls.tsx +7 -4
  29. package/src/components/editor/room-handles-2d.tsx +2 -3
  30. package/src/components/editor/room-handles.tsx +1 -2
  31. package/src/components/editor/room-highlight.tsx +6 -105
  32. package/src/components/editor/room-labels.test.ts +8 -822
  33. package/src/components/editor/room-labels.tsx +40 -1671
  34. package/src/components/editor/room-webgpu-materials.test.ts +1 -1
  35. package/src/components/editor/selection-manager.tsx +5 -3
  36. package/src/components/editor/site-edge-labels.tsx +1 -1
  37. package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
  38. package/src/components/editor/use-floorplan-background-placement.ts +2 -1
  39. package/src/components/editor/views/plugins-view.tsx +1 -1
  40. package/src/components/editor/views/view-bar.tsx +9 -9
  41. package/src/components/editor/wall-measurement-label.tsx +1 -1
  42. package/src/components/editor/wall-move-side-handles.tsx +1 -1
  43. package/src/components/editor/wall-pull-grip.tsx +2 -2
  44. package/src/components/editor-2d/floorplan-group-move.tsx +2 -3
  45. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1 -1
  46. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +1 -1
  47. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +1 -2
  48. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
  49. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
  50. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
  51. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +1 -2
  52. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +8 -10
  53. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +25 -33
  54. package/src/components/systems/roof/roof-edit-system.tsx +4 -3
  55. package/src/components/tools/distribution/distribution-run-tool.tsx +1 -1
  56. package/src/components/tools/item/placement-history.test.tsx +1 -1
  57. package/src/components/tools/item/use-placement-coordinator.tsx +2 -3
  58. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +6 -2
  59. package/src/components/tools/registry/move-registry-node-tool.tsx +1 -2
  60. package/src/components/tools/shared/cursor-sphere.tsx +1 -1
  61. package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
  62. package/src/components/tools/shared/placement-box.tsx +1 -1
  63. package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
  64. package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
  65. package/src/components/ui/action-menu/camera-actions.tsx +2 -2
  66. package/src/components/ui/action-menu/control-modes.tsx +1 -1
  67. package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
  68. package/src/components/ui/action-menu/index.tsx +3 -3
  69. package/src/components/ui/action-menu/measurement-control.tsx +3 -3
  70. package/src/components/ui/action-menu/placement.ts +0 -18
  71. package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
  72. package/src/components/ui/action-menu/view-toggles.tsx +5 -5
  73. package/src/components/ui/controls/finish-swatch.tsx +1 -1
  74. package/src/components/ui/controls/material-paint-panel.tsx +2 -2
  75. package/src/components/ui/controls/scene-material-list.tsx +2 -2
  76. package/src/components/ui/controls/select-control.tsx +1 -1
  77. package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
  78. package/src/components/ui/floating-level-selector.tsx +3 -3
  79. package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
  80. package/src/components/ui/helpers/helper-manager.test.tsx +1 -1
  81. package/src/components/ui/helpers/helper-manager.tsx +1 -1
  82. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  83. package/src/components/ui/node-icon-image.test.tsx +46 -0
  84. package/src/components/ui/node-icon-image.tsx +33 -1
  85. package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
  86. package/src/components/ui/panels/floor-foundation-panel.tsx +2 -2
  87. package/src/components/ui/panels/floor-opening-panel.tsx +4 -4
  88. package/src/components/ui/panels/node-display.ts +1 -1
  89. package/src/components/ui/panels/panel-manager.tsx +1 -1
  90. package/src/components/ui/panels/panel-wrapper.tsx +1 -1
  91. package/src/components/ui/panels/parametric-inspector.tsx +1 -1
  92. package/src/components/ui/panels/room-construction-rows.tsx +6 -6
  93. package/src/components/ui/panels/room-name-options.ts +1 -5
  94. package/src/components/ui/panels/room-panel.tsx +6 -8
  95. package/src/components/ui/primitives/color-dot.tsx +2 -2
  96. package/src/components/ui/primitives/opacity-control.tsx +2 -2
  97. package/src/components/ui/primitives/sidebar.tsx +3 -3
  98. package/src/components/ui/right-stack.tsx +1 -1
  99. package/src/components/ui/sidebar/icon-rail.tsx +1 -1
  100. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
  101. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  102. package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
  103. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
  104. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
  105. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +1 -1
  106. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  107. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
  108. package/src/components/ui/sidebar/panels/site-panel/index.tsx +2 -2
  109. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
  110. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  111. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
  112. package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
  113. package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
  114. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
  115. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
  116. package/src/components/ui/sidebar/tab-bar.tsx +1 -1
  117. package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +1 -1
  118. package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
  119. package/src/components/viewer-overlay.tsx +1 -2
  120. package/src/hooks/use-auto-frame.ts +1 -2
  121. package/src/hooks/use-keyboard.ts +1 -2
  122. package/src/hooks/use-selected-room.ts +5 -7
  123. package/src/i18n/floor-footprint-name.ts +1 -1
  124. package/src/i18n/locales/en/messages.po +180 -182
  125. package/src/i18n/locales/es/messages.po +180 -182
  126. package/src/i18n/locales/fr/messages.po +180 -182
  127. package/src/i18n/locales/ja/messages.po +180 -182
  128. package/src/i18n/locales/zh-CN/messages.po +180 -182
  129. package/src/i18n/locales.test.ts +1 -1
  130. package/src/index.tsx +109 -131
  131. package/src/lib/below-grade.test.tsx +4 -4
  132. package/src/lib/camera-facing.test.ts +1 -1
  133. package/src/lib/camera-facing.ts +2 -3
  134. package/src/lib/editor-level-display.ts +1 -1
  135. package/src/lib/floor-footprints.test.ts +2 -2
  136. package/src/lib/floor-opening-draft.ts +1 -1
  137. package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
  138. package/src/lib/floorplan/annotation-visibility.ts +1 -1
  139. package/src/lib/floorplan/floorplan-export.test.ts +1 -1
  140. package/src/lib/floorplan/floorplan-export.tsx +8 -11
  141. package/src/lib/floorplan/floorplan-extension.ts +4 -157
  142. package/src/lib/floorplan/floorplan-mode.ts +2 -1
  143. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
  144. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
  145. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
  146. package/src/lib/floorplan/geometry.ts +2 -112
  147. package/src/lib/floorplan/index.ts +0 -9
  148. package/src/lib/floorplan/items.ts +2 -1
  149. package/src/lib/floorplan/schedules.ts +6 -3
  150. package/src/lib/floorplan/sheet-export.ts +7 -3
  151. package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
  152. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
  153. package/src/lib/follow-pascal-presentation.ts +1 -1
  154. package/src/lib/glb-export.ts +1 -1
  155. package/src/lib/material-paint.ts +1 -1
  156. package/src/lib/measurements.test.ts +2 -1
  157. package/src/lib/mezzanine-selection.test.ts +1 -1
  158. package/src/lib/paint-region-mode.ts +1 -1
  159. package/src/lib/point-ask/session.ts +1 -2
  160. package/src/lib/roof-duplication.test.ts +100 -0
  161. package/src/lib/roof-duplication.ts +30 -5
  162. package/src/lib/room-handle-drag.ts +2 -12
  163. package/src/lib/room-name-catalog.test.ts +2 -1
  164. package/src/lib/room-name-messages.test.ts +2 -1
  165. package/src/lib/room-name-messages.ts +1 -118
  166. package/src/lib/room-name-storage.test.ts +2 -1
  167. package/src/lib/room-selection-commands.ts +2 -2
  168. package/src/lib/room-selection.test.ts +6 -6
  169. package/src/lib/room-transform-session.ts +1 -2
  170. package/src/lib/room-zone-routing.ts +2 -2
  171. package/src/lib/selection-routing.test.ts +0 -28
  172. package/src/lib/selection-routing.ts +1 -40
  173. package/src/lib/sfx-bus.ts +8 -32
  174. package/src/lib/sfx-player.test.ts +72 -1
  175. package/src/lib/sfx-player.ts +49 -337
  176. package/src/lib/viewer-selection.test.ts +38 -10
  177. package/src/lib/wall-pull.test.ts +1 -1
  178. package/src/lib/wall-pull.ts +1 -27
  179. package/src/store/use-editor.tsx +17 -26
  180. package/src/store/use-floorplan-annotation-visibility.ts +5 -5
  181. package/src/store/use-wall-region-handles-selection.ts +1 -2
  182. package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
  183. package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
  184. package/src/components/editor/first-person/build-collider-world.ts +0 -549
  185. package/src/components/editor/first-person/ground-holes.test.ts +0 -128
  186. package/src/components/editor/first-person/ground-holes.ts +0 -130
  187. package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
  188. package/src/components/editor/first-person/mechanism-targets.ts +0 -88
  189. package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
  190. package/src/components/editor/first-person/terrain-collider.ts +0 -212
  191. package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
  192. package/src/components/editor/floorplan-camera-sync.ts +0 -213
  193. package/src/components/editor/localized-html.tsx +0 -22
  194. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
  195. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
  196. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
  197. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
  198. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
  199. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
  200. package/src/components/editor-2d/svg-paths.ts +0 -124
  201. package/src/components/ui/action-menu/action-button.tsx +0 -89
  202. package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
  203. package/src/components/ui/primitives/button.tsx +0 -69
  204. package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
  205. package/src/components/ui/primitives/popover.tsx +0 -42
  206. package/src/components/ui/primitives/switch.tsx +0 -29
  207. package/src/components/ui/primitives/tooltip.tsx +0 -57
  208. package/src/components/ui/scene-loader.tsx +0 -73
  209. package/src/components/viewer/floorplan-compass-button.tsx +0 -67
  210. package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
  211. package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
  212. package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
  213. package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
  214. package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
  215. package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
  216. package/src/components/viewer/floorplan-preview.tsx +0 -1065
  217. package/src/components/viewer/render-settings-menu.tsx +0 -294
  218. package/src/components/viewer/sky-control.tsx +0 -710
  219. package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
  220. package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
  221. package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
  222. package/src/components/viewer/viewer-controls-bar.tsx +0 -496
  223. package/src/components/viewer/viewer-hover-label.tsx +0 -42
  224. package/src/components/viewer/viewer-rooms.tsx +0 -248
  225. package/src/components/viewer/viewer-scene-header.tsx +0 -286
  226. package/src/components/viewer/viewer-selection-manager.tsx +0 -124
  227. package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
  228. package/src/components/viewer/viewer-stage-modes.ts +0 -49
  229. package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
  230. package/src/components/viewer/viewer-stage.test.tsx +0 -47
  231. package/src/components/viewer/viewer-stage.tsx +0 -221
  232. package/src/components/walkthrough-hud.tsx +0 -193
  233. package/src/hooks/use-mobile.ts +0 -19
  234. package/src/i18n/level-name.ts +0 -39
  235. package/src/i18n/scene-theme-name.ts +0 -16
  236. package/src/lib/below-grade.ts +0 -133
  237. package/src/lib/camera-pose.test.ts +0 -237
  238. package/src/lib/camera-pose.ts +0 -172
  239. package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
  240. package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
  241. package/src/lib/floorplan/floorplan-readonly.ts +0 -95
  242. package/src/lib/floorplan/marks.test.ts +0 -213
  243. package/src/lib/floorplan/marks.ts +0 -238
  244. package/src/lib/measurements.ts +0 -8
  245. package/src/lib/node-display-label.ts +0 -37
  246. package/src/lib/room-assembly-overlay.test.ts +0 -275
  247. package/src/lib/room-assembly-overlay.ts +0 -265
  248. package/src/lib/room-selection.ts +0 -417
  249. package/src/lib/scene-bounds.test.ts +0 -327
  250. package/src/lib/scene-bounds.ts +0 -233
  251. package/src/lib/typing-target.ts +0 -9
  252. package/src/lib/viewer-selection.ts +0 -595
  253. package/src/lib/zone-content.ts +0 -133
  254. package/src/store/camera-pose-store.test.ts +0 -29
  255. package/src/store/camera-pose-store.ts +0 -27
  256. package/src/store/navigation-sync-pose-store.test.ts +0 -34
  257. package/src/store/navigation-sync-pose-store.ts +0 -27
  258. package/src/store/use-audio.test.ts +0 -146
  259. package/src/store/use-audio.tsx +0 -169
  260. package/src/store/use-first-person-hud.ts +0 -40
  261. package/src/store/use-follow-pascal.test.ts +0 -62
  262. package/src/store/use-follow-pascal.ts +0 -53
@@ -19,13 +19,13 @@
19
19
 
20
20
  import {
21
21
  type AnyNodeId,
22
- getWallCurveFrameAt,
23
22
  getWallThickness,
24
23
  useScene,
25
24
  WALL_CONSTRUCTION_FIELDS,
26
25
  type WallNode,
27
26
  type WallPlanPoint,
28
27
  wallFollowsStorey,
28
+ wallPullSeed,
29
29
  } from '@pascal-app/core'
30
30
  import { useViewer } from '@pascal-app/viewer'
31
31
  import { create } from 'zustand'
@@ -34,15 +34,6 @@ import type { ContinuationMode } from './continuation'
34
34
  import { getWallDrawVariant, selectWallDrawVariant } from './wall-draw-variant'
35
35
  import { publishWallRunFeedback } from './wall-run-snap'
36
36
 
37
- /** The floor plan's affordance id for a wall end's pull grip (a `move-arrow`, variant `pull`). */
38
- export const WALL_PULL_AFFORDANCE = 'wall-pull'
39
-
40
- /** What a pull grip carries: the wall, and which of its ends it pulls from. */
41
- export type WallPullGripPayload = { wallId: string; endpoint: 'start' | 'end' }
42
-
43
- /** The grip's tooltip, in both views. */
44
- export const WALL_PULL_GRIP_TITLE = 'Drag to draw the next wall'
45
-
46
37
  export type WallPullRun = {
47
38
  /** Bumped per pull, so each view seeds its draft from it once. */
48
39
  seq: number
@@ -93,23 +84,6 @@ export function wallPullTypePatch(wall: WallNode, storeyHeight: number | null):
93
84
  return patch as Partial<WallNode>
94
85
  }
95
86
 
96
- /**
97
- * The pulled end of `wall` and the direction out of it: along the wall for a
98
- * straight one, along its tangent for a curved one.
99
- */
100
- export function wallPullSeed(
101
- wall: Pick<WallNode, 'start' | 'end' | 'curveOffset'>,
102
- endpoint: 'start' | 'end',
103
- ): { start: WallPlanPoint; reference: WallPlanPoint } | null {
104
- const start: WallPlanPoint =
105
- endpoint === 'start' ? [wall.start[0], wall.start[1]] : [wall.end[0], wall.end[1]]
106
- const tangent = getWallCurveFrameAt(wall as WallNode, endpoint === 'start' ? 0 : 1).tangent
107
- const sign = endpoint === 'start' ? -1 : 1
108
- const length = Math.hypot(tangent.x, tangent.y)
109
- if (!(length > 1e-9)) return null
110
- return { start, reference: [(tangent.x / length) * sign, (tangent.y / length) * sign] }
111
- }
112
-
113
87
  // What the pull changed for its run, put back when it ends.
114
88
  let restore: { shape: ContinuationMode; toolDefaults: Record<string, unknown> | null } | null = null
115
89
  let stopWatching: (() => void) | null = null
@@ -21,6 +21,15 @@ import {
21
21
  type WallSurfaceSide,
22
22
  } from '@pascal-app/core'
23
23
  import { useViewer } from '@pascal-app/viewer'
24
+ import {
25
+ cameraPoseStore,
26
+ type NavigationSyncPose,
27
+ type NavigationSyncPoseInput,
28
+ publishNavigationSyncPose,
29
+ type RoomKey,
30
+ sameRoom,
31
+ subscribeNavigationSyncPose,
32
+ } from '@pascal-app/viewer/ui'
24
33
  import { create } from 'zustand'
25
34
  import { persist } from 'zustand/middleware'
26
35
  import {
@@ -56,7 +65,6 @@ import {
56
65
  type PaintHoverInfo,
57
66
  type PaintScope,
58
67
  } from '../lib/paint-scope'
59
- import { type RoomKey, sameRoom } from '../lib/room-selection'
60
68
  import {
61
69
  cycleSnappingModeIn,
62
70
  defaultSnappingModeFor,
@@ -66,8 +74,6 @@ import {
66
74
  snapContextOf,
67
75
  snappingModesFor,
68
76
  } from '../lib/snapping-mode'
69
- import { cameraPoseStore } from './camera-pose-store'
70
- import { publishNavigationSyncPoseToStore } from './navigation-sync-pose-store'
71
77
  import useInteractionScope from './use-interaction-scope'
72
78
  import {
73
79
  clampViewPaneRatio,
@@ -233,18 +239,6 @@ export type CatalogCategory =
233
239
  export type FloorplanSelectionTool = 'click' | 'marquee'
234
240
  export type GridSnapStep = 0.5 | 0.25 | 0.1 | 0.05
235
241
 
236
- export type NavigationSyncSource = '2d' | '3d'
237
-
238
- export type NavigationSyncPose = {
239
- source: NavigationSyncSource
240
- revision: number
241
- target: [number, number, number]
242
- azimuth: number
243
- viewWidth: number
244
- }
245
-
246
- export type NavigationSyncPoseInput = Omit<NavigationSyncPose, 'revision'>
247
-
248
242
  // Combined tool type. Known literals keep autocomplete; the `(string & {})`
249
243
  // arm lets plugin-contributed tool ids (e.g. `'trees:tree'`) typecheck without
250
244
  // the host enumerating every plugin kind. The runtime dispatch is already
@@ -490,12 +484,13 @@ type EditorState = {
490
484
  setViewPinned: (viewId: string, pinned: boolean) => void
491
485
  isFloorplanHovered: boolean
492
486
  setFloorplanHovered: (hovered: boolean) => void
487
+ /** Mirror of viewer/ui's navigation sync store, kept for plugins that read it here. */
488
+ navigationSyncPose: NavigationSyncPose | null
489
+ publishNavigationSyncPose: (pose: NavigationSyncPoseInput) => void
493
490
  // Toggleable DWV riser-diagram (plumbing isometric) overlay.
494
491
  isRiserOpen: boolean
495
492
  setRiserOpen: (open: boolean) => void
496
493
  toggleRiserOpen: () => void
497
- navigationSyncPose: NavigationSyncPose | null
498
- publishNavigationSyncPose: (pose: NavigationSyncPoseInput) => void
499
494
  floorplanSelectionTool: FloorplanSelectionTool
500
495
  setFloorplanSelectionTool: (tool: FloorplanSelectionTool) => void
501
496
  gridSnapStep: GridSnapStep
@@ -1538,18 +1533,11 @@ const useEditor = create<EditorState>()(
1538
1533
  set((state) => ({ pinnedViews: { ...state.pinnedViews, [viewId]: pinned } })),
1539
1534
  isFloorplanHovered: false,
1540
1535
  setFloorplanHovered: (hovered) => set({ isFloorplanHovered: hovered }),
1536
+ navigationSyncPose: null,
1537
+ publishNavigationSyncPose,
1541
1538
  isRiserOpen: false,
1542
1539
  setRiserOpen: (open) => set({ isRiserOpen: open }),
1543
1540
  toggleRiserOpen: () => set((state) => ({ isRiserOpen: !state.isRiserOpen })),
1544
- navigationSyncPose: null,
1545
- publishNavigationSyncPose: (pose) => {
1546
- const navigationSyncPose = {
1547
- ...pose,
1548
- revision: (get().navigationSyncPose?.revision ?? 0) + 1,
1549
- }
1550
- publishNavigationSyncPoseToStore(navigationSyncPose)
1551
- set({ navigationSyncPose })
1552
- },
1553
1541
  floorplanSelectionTool: 'click' as FloorplanSelectionTool,
1554
1542
  setFloorplanSelectionTool: (tool) => set({ floorplanSelectionTool: tool }),
1555
1543
  gridSnapStep: DEFAULT_PERSISTED_EDITOR_LAYOUT_STATE.gridSnapStep,
@@ -1863,4 +1851,7 @@ usePaintRegionMode.subscribe((state) => {
1863
1851
  if (useEditor.getState().paintEraser !== paintEraser) useEditor.setState({ paintEraser })
1864
1852
  })
1865
1853
 
1854
+ // Published plugins read the 2D/3D navigation pose from the editor store; the shared store owns it.
1855
+ subscribeNavigationSyncPose((navigationSyncPose) => useEditor.setState({ navigationSyncPose }))
1856
+
1866
1857
  export default useEditor
@@ -1,5 +1,10 @@
1
1
  'use client'
2
2
 
3
+ import {
4
+ DEFAULT_FLOORPLAN_WALL_DIMENSION_FACES,
5
+ type FloorplanWallDimensionFaces,
6
+ normalizeFloorplanWallDimensionFaces,
7
+ } from '@pascal-app/core'
3
8
  import { create } from 'zustand'
4
9
  import { persist } from 'zustand/middleware'
5
10
  import {
@@ -8,11 +13,6 @@ import {
8
13
  type FloorplanAnnotationVisibility,
9
14
  normalizeFloorplanAnnotationVisibility,
10
15
  } from '../lib/floorplan/annotation-visibility'
11
- import {
12
- DEFAULT_FLOORPLAN_WALL_DIMENSION_FACES,
13
- type FloorplanWallDimensionFaces,
14
- normalizeFloorplanWallDimensionFaces,
15
- } from '../lib/floorplan/floorplan-extension'
16
16
 
17
17
  type PersistedFloorplanAnnotationState = {
18
18
  visibility: FloorplanAnnotationVisibility
@@ -1,10 +1,9 @@
1
1
  import { type AnyNodeId, useScene } from '@pascal-app/core'
2
- import { useViewer } from '@pascal-app/viewer'
2
+ import { isTypingTarget, useViewer } from '@pascal-app/viewer'
3
3
  import { create } from 'zustand'
4
4
  import { hasLiveGestures } from '../lib/gesture-lifecycle'
5
5
  import { removeWallRegion } from '../lib/paint-regions'
6
6
  import { sfxEmitter } from '../lib/sfx-bus'
7
- import { isTypingTarget } from '../lib/typing-target'
8
7
  import useDeleteConfirmation from './use-delete-confirmation'
9
8
  import useInteractionScope from './use-interaction-scope'
10
9
 
@@ -1,108 +0,0 @@
1
- import type { Polygon } from '@pascal-app/core'
2
- import {
3
- type PillCandidate,
4
- placePills,
5
- type RoomHit,
6
- type RoomLabelEntry,
7
- roomAt,
8
- } from '../room-labels'
9
-
10
- // One room-label placement pass and one pointer pick, for a 900 × 600 px house of 31, 60 and 120
11
- // rooms (every third an L), printed as JSON medians in ms. Run with `bun run <this file>`.
12
- let seed = 11
13
- const random = () => {
14
- seed = (seed * 1_103_515_245 + 12_345) % 2 ** 31
15
- return seed / 2 ** 31
16
- }
17
-
18
- function house(count: number) {
19
- const columns = Math.ceil(Math.sqrt(count * 1.5))
20
- const rows = Math.ceil(count / columns)
21
- const width = 900 / columns
22
- const depth = 600 / rows
23
- return Array.from({ length: count }, (_, i) => {
24
- const left = 270 + (i % columns) * width
25
- const top = 150 + Math.floor(i / columns) * depth
26
- const right = left + width
27
- const bottom = top + depth
28
- const outer: [number, number][] =
29
- i % 3 === 0
30
- ? [
31
- [left, top],
32
- [right, top],
33
- [right, top + depth / 2],
34
- [left + width / 2, top + depth / 2],
35
- [left + width / 2, bottom],
36
- [left, bottom],
37
- ]
38
- : [
39
- [left, top],
40
- [right, top],
41
- [right, bottom],
42
- [left, bottom],
43
- ]
44
- const outline: Polygon = { outer, holes: [] }
45
- const pill = 60 + random() * 110
46
- const candidate: PillCandidate = {
47
- id: `room_${i}`,
48
- x: left + width / 4,
49
- y: top + depth / 4,
50
- size: [pill, 24, pill * 0.6],
51
- area: width * depth * (i % 3 === 0 ? 0.75 : 1),
52
- outline,
53
- }
54
- const entry: RoomLabelEntry = {
55
- zoneId: candidate.id,
56
- polygon: outer,
57
- holes: [],
58
- area: candidate.area,
59
- }
60
- return { candidate, entry }
61
- })
62
- }
63
-
64
- const median = (samples: number[]) => samples.sort((a, b) => a - b)[samples.length >> 1]!
65
-
66
- const pane = { width: 1440, height: 900 }
67
- const results: Record<string, unknown> = {}
68
- for (const count of [31, 60, 120]) {
69
- const rooms = house(count)
70
- const candidates = rooms.map((room) => room.candidate)
71
- const entries = rooms.map((room) => room.entry)
72
- for (let i = 0; i < 20; i++) placePills(candidates, pane)
73
- const cold: number[] = []
74
- const warm: number[] = []
75
- let previous = placePills(candidates, pane)
76
- for (let i = 0; i < 100; i++) {
77
- let started = performance.now()
78
- placePills(candidates, pane)
79
- cold.push(performance.now() - started)
80
- started = performance.now()
81
- previous = placePills(candidates, pane, previous)
82
- warm.push(performance.now() - started)
83
- }
84
- const points = Array.from(
85
- { length: 1000 },
86
- (): RoomHit => [270 + random() * 900, 150 + random() * 600, 0],
87
- )
88
- for (const point of points) roomAt(entries, () => point)
89
- const picks: number[] = []
90
- for (let i = 0; i < 20; i++) {
91
- const started = performance.now()
92
- for (const point of points) roomAt(entries, () => point)
93
- picks.push((performance.now() - started) / points.length)
94
- }
95
- const tiers = Object.fromEntries(
96
- ['full', 'name', 'dot', 'hidden'].map((tier) => [
97
- tier,
98
- [...previous.values()].filter((placement) => placement.tier === tier).length,
99
- ]),
100
- )
101
- results[count] = {
102
- placeMs: median(cold),
103
- placeWithPreviousMs: median(warm),
104
- pickMs: median(picks),
105
- tiers,
106
- }
107
- }
108
- console.log(JSON.stringify(results, null, 2))