@pascal-app/editor 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.
- package/package.json +14 -9
- package/src/components/editor/alignment-3d-guide-layer.tsx +10 -2
- package/src/components/editor/bake-exporter.tsx +49 -0
- package/src/components/editor/bake-thumbnail.tsx +95 -0
- package/src/components/editor/camera-dragging-lifecycle.test.ts +49 -0
- package/src/components/editor/camera-dragging-lifecycle.ts +41 -0
- package/src/components/editor/custom-camera-controls.tsx +332 -199
- package/src/components/editor/delete-confirmation-dialog.tsx +54 -0
- package/src/components/editor/editor-layout-mobile.tsx +5 -0
- package/src/components/editor/editor-layout-v2.tsx +18 -0
- package/src/components/editor/elevation-3d-guide-layer.tsx +120 -0
- package/src/components/editor/export-manager.tsx +71 -63
- package/src/components/editor/fence-tangent-lines-3d.tsx +87 -0
- package/src/components/editor/first-person/build-collider-world.test.ts +102 -5
- package/src/components/editor/first-person/build-collider-world.ts +52 -5
- package/src/components/editor/first-person/terrain-collider.test.ts +132 -0
- package/src/components/editor/first-person/terrain-collider.ts +212 -0
- package/src/components/editor/first-person-controls.tsx +410 -136
- package/src/components/editor/floating-action-menu.tsx +435 -64
- package/src/components/editor/floating-building-action-menu.tsx +1 -1
- package/src/components/editor/floorplan-background-selection.test.ts +72 -0
- package/src/components/editor/floorplan-background-selection.ts +7 -20
- package/src/components/editor/floorplan-camera-sync.test.ts +249 -0
- package/src/components/editor/floorplan-camera-sync.ts +213 -0
- package/src/components/editor/floorplan-mode-coordinator.tsx +82 -0
- package/src/components/editor/floorplan-navigation-presentation.test.ts +142 -0
- package/src/components/editor/floorplan-navigation-presentation.ts +156 -0
- package/src/components/editor/floorplan-panel.tsx +2517 -1492
- package/src/components/editor/grid.tsx +166 -39
- package/src/components/editor/group-actions.ts +597 -0
- package/src/components/editor/group-floating-action-menu.tsx +130 -0
- package/src/components/editor/group-move-3d.ts +397 -0
- package/src/components/editor/group-rotate-handle.tsx +102 -64
- package/src/components/editor/group-selection-box-3d.tsx +173 -0
- package/src/components/editor/group-transform-shared.test.ts +192 -1
- package/src/components/editor/group-transform-shared.ts +240 -7
- package/src/components/editor/handles/handle-arrow.tsx +81 -23
- package/src/components/editor/handles/handle-drag-history.test.ts +96 -0
- package/src/components/editor/handles/handle-drag-history.ts +14 -0
- package/src/components/editor/handles/preview-overrides.test.ts +26 -0
- package/src/components/editor/handles/preview-overrides.ts +13 -0
- package/src/components/editor/handles/resize-snap.test.ts +52 -0
- package/src/components/editor/handles/resize-snap.ts +23 -0
- package/src/components/editor/handles/use-handle-drag.ts +49 -6
- package/src/components/editor/index.tsx +289 -35
- package/src/components/editor/measurement-pill.tsx +68 -23
- package/src/components/editor/node-action-menu.tsx +14 -1
- package/src/components/editor/node-arrow-handles.tsx +409 -180
- package/src/components/editor/opening-guides-3d-layer.tsx +144 -0
- package/src/components/editor/quick-measurement-card.tsx +76 -0
- package/src/components/editor/quick-measurement-hud.tsx +34 -0
- package/src/components/editor/riser-diagram-panel.tsx +137 -0
- package/src/components/editor/selection-manager.tsx +814 -466
- package/src/components/editor/site-edge-labels.tsx +28 -6
- package/src/components/editor/slab-hole-highlights.tsx +13 -5
- package/src/components/editor/snapshot-capture-overlay.tsx +258 -115
- package/src/components/editor/three-context-bridge.ts +22 -0
- package/src/components/editor/thumbnail-generator.tsx +118 -253
- package/src/components/editor/use-floorplan-background-placement.ts +113 -45
- package/src/components/editor/use-floorplan-hit-testing.test.ts +82 -0
- package/src/components/editor/use-floorplan-hit-testing.ts +144 -161
- package/src/components/editor/use-floorplan-scene-data.ts +5 -5
- package/src/components/editor/use-mesh-settle-epoch.ts +27 -0
- package/src/components/editor/wall-measurement-label.tsx +10 -28
- package/src/components/editor/wall-move-side-handles.tsx +229 -39
- package/src/components/editor/wall-opening-highlights.tsx +63 -32
- package/src/components/editor/wall-snap-beacon-layer.tsx +162 -6
- package/src/components/editor-2d/floorplan-action-menu-layer.tsx +9 -5
- package/src/components/editor-2d/floorplan-alignment-guide-layer.tsx +2 -1
- package/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +40 -9
- package/src/components/editor-2d/floorplan-cursor-indicator-position.test.ts +31 -0
- package/src/components/editor-2d/floorplan-cursor-indicator-position.ts +39 -0
- package/src/components/editor-2d/floorplan-group-action-menu.tsx +87 -0
- package/src/components/editor-2d/floorplan-group-move.tsx +744 -0
- package/src/components/editor-2d/floorplan-measurement-tool-layer.test.ts +113 -0
- package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1672 -0
- package/src/components/editor-2d/floorplan-quick-measure-layer.tsx +212 -0
- package/src/components/editor-2d/floorplan-registered-tool-layer.tsx +72 -0
- package/src/components/editor-2d/floorplan-registry-action-menu.tsx +219 -20
- package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +327 -59
- package/src/components/editor-2d/floorplan-render-context.test.ts +27 -0
- package/src/components/editor-2d/floorplan-render-context.tsx +113 -8
- package/src/components/editor-2d/floorplan-snap-beacon-layer.tsx +5 -3
- package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +285 -0
- package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +516 -0
- package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +236 -0
- package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +618 -0
- package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +369 -0
- package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +431 -32
- package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +89 -0
- package/src/components/editor-2d/renderers/floorplan-label-angle.ts +106 -0
- package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +94 -26
- package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +587 -0
- package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +2280 -578
- package/src/components/editor-2d/renderers/floorplan-stair-layer.tsx +20 -10
- package/src/components/editor-2d/renderers/floorplan-voronoi-layer.tsx +128 -0
- package/src/components/systems/ceiling/ceiling-selection-affordance-system.tsx +425 -61
- package/src/components/systems/ceiling/ceiling-system.tsx +97 -4
- package/src/components/systems/roof/roof-edit-system.tsx +1768 -13
- package/src/components/systems/selection-affordance-manager.tsx +38 -0
- package/src/components/systems/zone/zone-label-editor-system.tsx +14 -1
- package/src/components/systems/zone/zone-system.tsx +42 -13
- package/src/components/tools/elevator/elevator-tool.tsx +34 -8
- package/src/components/tools/elevator/move-elevator-tool.tsx +13 -2
- package/src/components/tools/fence/fence-drafting.ts +107 -8
- package/src/components/tools/item/move-tool.tsx +17 -13
- package/src/components/tools/item/placement-math.test.ts +13 -1
- package/src/components/tools/item/placement-math.ts +28 -2
- package/src/components/tools/item/placement-strategies.ts +246 -5
- package/src/components/tools/item/placement-types.ts +13 -1
- package/src/components/tools/item/use-draft-node.ts +146 -57
- package/src/components/tools/item/use-placement-coordinator.tsx +813 -125
- package/src/components/tools/registry/move-registry-node-tool.tsx +636 -103
- package/src/components/tools/roof/roof-tool.tsx +336 -94
- package/src/components/tools/select/box-select-state.ts +18 -7
- package/src/components/tools/select/box-select-tool.tsx +176 -40
- package/src/components/tools/select/marquee-geometry.test.ts +161 -0
- package/src/components/tools/select/marquee-geometry.ts +155 -0
- package/src/components/tools/select/plane-box-select-tool.tsx +1 -8
- package/src/components/tools/select/select-candidates.ts +1 -1
- package/src/components/tools/shared/cursor-sphere.tsx +62 -26
- package/src/components/tools/shared/drag-bounding-box.tsx +28 -4
- package/src/components/tools/shared/facing-indicator.tsx +87 -0
- package/src/components/tools/shared/facing-pose-indicator.tsx +54 -0
- package/src/components/tools/shared/floor-stack-preview.ts +4 -0
- package/src/components/tools/shared/horizontal-construction-plane.ts +123 -0
- package/src/components/tools/shared/placement-box.tsx +183 -1
- package/src/components/tools/shared/pointer-support-cap.test.ts +98 -0
- package/src/components/tools/shared/pointer-support-cap.ts +273 -0
- package/src/components/tools/shared/polygon-editor.tsx +276 -35
- package/src/components/tools/site/site-boundary-editor.tsx +101 -42
- package/src/components/tools/site/stroke-pointer-ownership.test.ts +91 -0
- package/src/components/tools/site/stroke-pointer-ownership.ts +57 -0
- package/src/components/tools/site/terrain-brush-cursor.tsx +247 -0
- package/src/components/tools/site/terrain-sculpt-grid.tsx +192 -0
- package/src/components/tools/site/terrain-sculpt-tool.tsx +356 -0
- package/src/components/tools/stair/stair-click-guard.test.ts +58 -0
- package/src/components/tools/stair/stair-click-guard.ts +72 -0
- package/src/components/tools/stair/stair-defaults.ts +1 -0
- package/src/components/tools/stair/stair-tool.tsx +164 -42
- package/src/components/tools/tool-manager.tsx +149 -30
- package/src/components/tools/wall/wall-drafting.test.ts +447 -0
- package/src/components/tools/wall/wall-drafting.ts +304 -108
- package/src/components/tools/wall/wall-snap-geometry.test.ts +52 -0
- package/src/components/tools/wall/wall-snap-geometry.ts +137 -9
- package/src/components/tools/zone/zone-boundary-editor.tsx +5 -1
- package/src/components/tools/zone/zone-tool.tsx +98 -88
- package/src/components/ui/action-menu/camera-actions.tsx +24 -17
- package/src/components/ui/action-menu/control-modes.tsx +44 -94
- package/src/components/ui/action-menu/furnish-tools.tsx +5 -5
- package/src/components/ui/action-menu/index.tsx +2 -4
- package/src/components/ui/action-menu/measurement-control.tsx +267 -0
- package/src/components/ui/action-menu/structure-tools.tsx +22 -13
- package/src/components/ui/action-menu/view-toggles.tsx +42 -90
- package/src/components/ui/command-palette/editor-commands.tsx +16 -3
- package/src/components/ui/command-palette/index.tsx +4 -3
- package/src/components/ui/controls/material-paint-panel.tsx +93 -18
- package/src/components/ui/controls/material-picker.tsx +162 -152
- package/src/components/ui/controls/material-properties-editor.tsx +108 -0
- package/src/components/ui/controls/metric-control.tsx +118 -44
- package/src/components/ui/controls/scene-material-list.tsx +247 -0
- package/src/components/ui/controls/slider-control.tsx +88 -38
- package/src/components/ui/controls/terrain-sculpt-panel.tsx +193 -0
- package/src/components/ui/floating-level-selector.tsx +74 -20
- package/src/components/ui/helpers/building-helper.tsx +10 -23
- package/src/components/ui/helpers/contextual-helper-panel.tsx +428 -0
- package/src/components/ui/helpers/helper-manager.tsx +273 -14
- package/src/components/ui/helpers/item-helper.tsx +28 -32
- package/src/components/ui/helpers/registered-tool-helper.tsx +45 -11
- package/src/components/ui/helpers/roof-helper.tsx +10 -12
- package/src/components/ui/icon-ref.tsx +47 -0
- package/src/components/ui/item-catalog/catalog-items.tsx +39 -1
- package/src/components/ui/item-catalog/item-catalog.tsx +13 -36
- package/src/components/ui/level-duplicate-dialog.tsx +1 -1
- package/src/components/ui/panels/multi-selection-panel.tsx +57 -0
- package/src/components/ui/panels/node-display.ts +17 -17
- package/src/components/ui/panels/panel-manager.tsx +36 -14
- package/src/components/ui/panels/panel-wrapper.tsx +24 -3
- package/src/components/ui/panels/parametric-inspector.tsx +19 -4
- package/src/components/ui/panels/reference-panel.tsx +54 -19
- package/src/components/ui/panels/selection-breakdown.test.ts +24 -0
- package/src/components/ui/panels/selection-breakdown.ts +20 -0
- package/src/components/ui/primitives/shortcut-token.tsx +39 -3
- package/src/components/ui/primitives/sidebar.tsx +1 -0
- package/src/components/ui/sidebar/app-sidebar.tsx +5 -1
- package/src/components/ui/sidebar/icon-rail.tsx +50 -31
- package/src/components/ui/sidebar/panels/plugins-panel.tsx +218 -0
- package/src/components/ui/sidebar/panels/settings-panel/index.tsx +82 -41
- package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +76 -6
- package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +12 -4
- package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +2 -1
- package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +4 -3
- package/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +10 -7
- package/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx +7 -2
- package/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +10 -7
- package/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +10 -7
- package/src/components/ui/sidebar/panels/site-panel/index.tsx +42 -17
- package/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx +31 -17
- package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +72 -25
- package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +7 -3
- package/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +12 -8
- package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +4 -3
- package/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +10 -7
- package/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx +2 -2
- package/src/components/ui/sidebar/panels/site-panel/tree-node.tsx +44 -3
- package/src/components/ui/sidebar/panels/site-panel/tree-structure.ts +36 -0
- package/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx +7 -2
- package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +3 -3
- package/src/components/ui/sidebar/tab-bar.tsx +42 -28
- package/src/components/ui/sidebar/use-plugin-panels.tsx +132 -0
- package/src/components/ui/snap-target-badge.test.tsx +40 -0
- package/src/components/ui/snap-target-badge.tsx +88 -0
- package/src/components/viewer/viewer-controls-bar.tsx +466 -0
- package/src/components/viewer/viewer-scene-header.tsx +235 -0
- package/src/components/viewer-overlay.tsx +36 -596
- package/src/components/viewer-zone-system.tsx +6 -1
- package/src/components/walkthrough-hud.tsx +111 -0
- package/src/hooks/use-auto-save.test.ts +14 -0
- package/src/hooks/use-auto-save.ts +54 -7
- package/src/hooks/use-ceiling-events.ts +3 -2
- package/src/hooks/use-drag-action.ts +4 -1
- package/src/hooks/use-grid-events.ts +24 -0
- package/src/hooks/use-keyboard.ts +438 -70
- package/src/index.tsx +355 -9
- package/src/lib/active-placement-surface.test.ts +24 -0
- package/src/lib/active-placement-surface.ts +42 -0
- package/src/lib/camera-pose.test.ts +237 -0
- package/src/lib/camera-pose.ts +172 -0
- package/src/lib/ceiling-plan-snap.ts +24 -0
- package/src/lib/contextual-help.test.ts +112 -0
- package/src/lib/contextual-help.ts +144 -0
- package/src/lib/continuation.ts +64 -0
- package/src/lib/direct-manipulation.test.ts +275 -0
- package/src/lib/direct-manipulation.ts +118 -0
- package/src/lib/door-interaction.ts +1 -1
- package/src/lib/editor-api.ts +23 -35
- package/src/lib/elevation-guides.test.ts +107 -0
- package/src/lib/elevation-guides.ts +236 -0
- package/src/lib/floorplan/annotation-visibility.test.ts +327 -0
- package/src/lib/floorplan/annotation-visibility.ts +133 -0
- package/src/lib/floorplan/apply-alignment.test.ts +25 -0
- package/src/lib/floorplan/apply-alignment.ts +18 -12
- package/src/lib/floorplan/drawing-coordination.test.ts +46 -0
- package/src/lib/floorplan/drawing-coordination.ts +13 -0
- package/src/lib/floorplan/floorplan-export.test.ts +319 -0
- package/src/lib/floorplan/floorplan-export.tsx +978 -0
- package/src/lib/floorplan/floorplan-extension.test.ts +43 -0
- package/src/lib/floorplan/floorplan-extension.ts +181 -0
- package/src/lib/floorplan/floorplan-mode.test.ts +120 -0
- package/src/lib/floorplan/floorplan-mode.ts +73 -0
- package/src/lib/floorplan/floorplan-pdfkit-document.ts +194 -0
- package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +107 -0
- package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +680 -0
- package/src/lib/floorplan/geometry.ts +52 -0
- package/src/lib/floorplan/index.ts +3 -0
- package/src/lib/floorplan/items.ts +5 -2
- package/src/lib/floorplan/plan-coords.ts +21 -0
- package/src/lib/fresh-planar-placement.test.ts +283 -3
- package/src/lib/fresh-planar-placement.ts +85 -1
- package/src/lib/glb-export.test.ts +556 -0
- package/src/lib/glb-export.ts +1071 -0
- package/src/lib/ground-surface.ts +95 -0
- package/src/lib/history.test.ts +96 -0
- package/src/lib/history.ts +31 -0
- package/src/lib/interaction/hot-set.test.ts +133 -0
- package/src/lib/interaction/hot-set.ts +67 -0
- package/src/lib/interaction/overlay-policy.test.ts +52 -0
- package/src/lib/interaction/overlay-policy.ts +59 -0
- package/src/lib/interaction/scope.ts +243 -0
- package/src/lib/level-duplication.test.ts +2 -1
- package/src/lib/level-selection.ts +2 -2
- package/src/lib/material-paint.ts +36 -49
- package/src/lib/measurement-kind.test.ts +30 -0
- package/src/lib/measurement-kind.ts +19 -0
- package/src/lib/measurement-label.test.ts +47 -0
- package/src/lib/measurement-label.ts +68 -0
- package/src/lib/measurement-parser.ts +116 -0
- package/src/lib/measurements.test.ts +188 -0
- package/src/lib/measurements.ts +210 -0
- package/src/lib/paint-scope.test.ts +454 -0
- package/src/lib/paint-scope.ts +461 -0
- package/src/lib/placement-drag-release.ts +23 -0
- package/src/lib/planar-cursor-placement.test.ts +57 -0
- package/src/lib/plugin-panels.test.ts +19 -0
- package/src/lib/plugin-panels.ts +91 -0
- package/src/lib/quick-action-feedback.ts +33 -0
- package/src/lib/quick-action-nodes.test.ts +94 -0
- package/src/lib/quick-action-nodes.ts +47 -0
- package/src/lib/quick-measurement.test.ts +77 -0
- package/src/lib/quick-measurement.ts +109 -0
- package/src/lib/roof-duplication.ts +6 -6
- package/src/lib/roof-hover-outline-proxy.ts +22 -0
- package/src/lib/roof-wall-hit.ts +164 -0
- package/src/lib/scene-clipboard.test.ts +325 -0
- package/src/lib/scene-clipboard.ts +310 -21
- package/src/lib/scene.ts +28 -5
- package/src/lib/selection-routing.test.ts +313 -0
- package/src/lib/selection-routing.ts +180 -0
- package/src/lib/sfx/index.ts +1 -0
- package/src/lib/sfx/movement-tick.test.ts +65 -0
- package/src/lib/sfx/movement-tick.ts +18 -0
- package/src/lib/sfx-bus.ts +82 -14
- package/src/lib/sfx-player.test.ts +266 -0
- package/src/lib/sfx-player.ts +262 -69
- package/src/lib/site-boundary.test.ts +53 -0
- package/src/lib/site-boundary.ts +27 -0
- package/src/lib/slab-plan-snap.test.ts +93 -0
- package/src/lib/slab-plan-snap.ts +108 -0
- package/src/lib/snapping-mode.test.ts +165 -0
- package/src/lib/snapping-mode.ts +191 -0
- package/src/lib/stair-duplication.test.ts +103 -0
- package/src/lib/stair-duplication.ts +58 -86
- package/src/lib/stair-levels.ts +2 -0
- package/src/lib/surface-plan-snap.test.ts +71 -0
- package/src/lib/surface-plan-snap.ts +256 -0
- package/src/lib/terrain-sculpt.test.ts +429 -0
- package/src/lib/terrain-sculpt.ts +301 -0
- package/src/lib/terrain-verb-color.test.ts +51 -0
- package/src/lib/terrain-verb-color.ts +58 -0
- package/src/lib/touch-gesture-priority.test.ts +45 -0
- package/src/lib/touch-gesture-priority.ts +30 -0
- package/src/lib/use-linear-display.ts +40 -0
- package/src/lib/window-interaction.ts +1 -1
- package/src/lib/world-grid-snap.ts +37 -5
- package/src/store/camera-pose-store.test.ts +29 -0
- package/src/store/camera-pose-store.ts +27 -0
- package/src/store/live-draft-preview-stores.test.ts +136 -0
- package/src/store/navigation-sync-pose-store.test.ts +34 -0
- package/src/store/navigation-sync-pose-store.ts +27 -0
- package/src/store/terrain-sculpt-mode.test.ts +223 -0
- package/src/store/use-delete-confirmation.ts +27 -0
- package/src/store/use-direct-manipulation-feedback.ts +20 -0
- package/src/store/use-drawing-view.test.ts +23 -0
- package/src/store/use-drawing-view.ts +84 -0
- package/src/store/use-editor.tsx +665 -126
- package/src/store/use-elevation-guides.ts +40 -0
- package/src/store/use-facing-pose.ts +44 -0
- package/src/store/use-fence-curve-draft.ts +51 -0
- package/src/store/use-first-person-hud.ts +40 -0
- package/src/store/use-floorplan-annotation-visibility.ts +60 -0
- package/src/store/use-floorplan-draft-preview.ts +151 -0
- package/src/store/use-floorplan-marquee.ts +50 -0
- package/src/store/use-floorplan-mode.ts +110 -0
- package/src/store/use-interaction-scope.test.ts +206 -0
- package/src/store/use-interaction-scope.ts +140 -0
- package/src/store/use-measurement-draft.test.ts +559 -0
- package/src/store/use-measurement-draft.ts +570 -0
- package/src/store/use-opening-guides.ts +41 -0
- package/src/store/use-path-draft-preview.ts +90 -0
- package/src/store/use-placement-preview.ts +11 -3
- package/src/store/use-quick-measurement-hud.test.ts +53 -0
- package/src/store/use-quick-measurement-hud.ts +77 -0
- package/src/store/use-segment-draft-chain.ts +28 -0
- package/src/store/use-stair-build-preview.ts +53 -0
- package/src/store/use-wall-snap-indicator.ts +2 -0
- package/src/components/editor/first-person/bvh-ecctrl.tsx +0 -860
- package/src/components/editor/group-move-handle.tsx +0 -316
- package/src/components/ui/panels/paint-panel.tsx +0 -163
- package/src/lib/floorplan/selection-tool.ts +0 -271
- package/src/lib/level-name.ts +0 -11
|
@@ -2,24 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
import { emitter, type FenceNode, isCurvedWall, type WallNode } from '@pascal-app/core'
|
|
4
4
|
import { type MouseEvent as ReactMouseEvent, useCallback } from 'react'
|
|
5
|
+
import { resolveCeilingPlanPointSnap } from '../../lib/ceiling-plan-snap'
|
|
5
6
|
import { alignFloorplanDraftPoint, getPlanPointDistance } from '../../lib/floorplan'
|
|
7
|
+
import { resolveSlabPlanPointSnap } from '../../lib/slab-plan-snap'
|
|
8
|
+
import useAlignmentGuides from '../../store/use-alignment-guides'
|
|
9
|
+
import useEditor, { isAngleSnapActive, isMagneticSnapActive } from '../../store/use-editor'
|
|
10
|
+
import usePlacementPreview from '../../store/use-placement-preview'
|
|
11
|
+
import useSegmentDraftChain from '../../store/use-segment-draft-chain'
|
|
6
12
|
import { snapFenceDraftPoint } from '../tools/fence/fence-drafting'
|
|
7
|
-
import {
|
|
8
|
-
WALL_FINE_GRID_STEP,
|
|
9
|
-
WALL_GRID_STEP,
|
|
10
|
-
type WallPlanPoint,
|
|
11
|
-
} from '../tools/wall/wall-drafting'
|
|
13
|
+
import { getSegmentGridStep, type WallPlanPoint } from '../tools/wall/wall-drafting'
|
|
12
14
|
|
|
13
15
|
type UseFloorplanBackgroundPlacementArgs = {
|
|
14
16
|
activePolygonDraftPoints: WallPlanPoint[]
|
|
15
17
|
ceilingDraftPoints: WallPlanPoint[]
|
|
16
18
|
clearFencePlacementDraft: () => void
|
|
17
19
|
clearRoofPlacementDraft: () => void
|
|
20
|
+
clearWallPlacementDraft: () => void
|
|
18
21
|
emitFloorplanGridEvent: (
|
|
19
22
|
type: 'click' | 'double-click' | 'move',
|
|
20
23
|
planPoint: WallPlanPoint,
|
|
21
24
|
event: ReactMouseEvent<SVGSVGElement>,
|
|
22
|
-
) =>
|
|
25
|
+
) => void
|
|
23
26
|
fenceDraftStart: WallPlanPoint | null
|
|
24
27
|
fences: FenceNode[]
|
|
25
28
|
findClosestWallPoint: (
|
|
@@ -40,7 +43,7 @@ type UseFloorplanBackgroundPlacementArgs = {
|
|
|
40
43
|
) => boolean
|
|
41
44
|
handleCeilingPlacementPoint: (point: WallPlanPoint) => void
|
|
42
45
|
handleSlabPlacementPoint: (point: WallPlanPoint) => void
|
|
43
|
-
handleWallPlacementPoint: (point: WallPlanPoint
|
|
46
|
+
handleWallPlacementPoint: (point: WallPlanPoint) => void
|
|
44
47
|
handleZonePlacementPoint: (point: WallPlanPoint) => void
|
|
45
48
|
isCeilingBuildActive: boolean
|
|
46
49
|
isCeilingItemPlacementActive: boolean
|
|
@@ -51,18 +54,19 @@ type UseFloorplanBackgroundPlacementArgs = {
|
|
|
51
54
|
isRoofBuildActive: boolean
|
|
52
55
|
isWallBuildActive: boolean
|
|
53
56
|
isZoneBuildActive: boolean
|
|
57
|
+
levelId: string | null
|
|
54
58
|
roofDraftStart: WallPlanPoint | null
|
|
55
59
|
setCursorPoint: React.Dispatch<React.SetStateAction<WallPlanPoint | null>>
|
|
56
60
|
setFenceDraftEnd: React.Dispatch<React.SetStateAction<WallPlanPoint | null>>
|
|
57
61
|
setFenceDraftStart: React.Dispatch<React.SetStateAction<WallPlanPoint | null>>
|
|
58
62
|
setRoofDraftEnd: React.Dispatch<React.SetStateAction<WallPlanPoint | null>>
|
|
59
63
|
setRoofDraftStart: React.Dispatch<React.SetStateAction<WallPlanPoint | null>>
|
|
60
|
-
shiftPressed: boolean
|
|
61
64
|
snapWallDraftPoint: (args: {
|
|
62
65
|
point: WallPlanPoint
|
|
63
66
|
walls: WallNode[]
|
|
64
67
|
start?: WallPlanPoint
|
|
65
68
|
angleSnap?: boolean
|
|
69
|
+
bypassSnap?: boolean
|
|
66
70
|
step?: number
|
|
67
71
|
gridSnap?: (point: WallPlanPoint) => WallPlanPoint
|
|
68
72
|
}) => WallPlanPoint
|
|
@@ -77,7 +81,7 @@ type UseFloorplanBackgroundPlacementArgs = {
|
|
|
77
81
|
* Snap a building-local plan point to the world XZ grid at `step`.
|
|
78
82
|
* Injected so the hook doesn't have to know the building's rotation
|
|
79
83
|
* or position — used by wall / fence branches that snap at variable
|
|
80
|
-
* step
|
|
84
|
+
* step.
|
|
81
85
|
*/
|
|
82
86
|
worldGridSnap: (point: WallPlanPoint, step: number) => WallPlanPoint
|
|
83
87
|
}
|
|
@@ -87,6 +91,7 @@ export function useFloorplanBackgroundPlacement({
|
|
|
87
91
|
ceilingDraftPoints,
|
|
88
92
|
clearFencePlacementDraft,
|
|
89
93
|
clearRoofPlacementDraft,
|
|
94
|
+
clearWallPlacementDraft,
|
|
90
95
|
emitFloorplanGridEvent,
|
|
91
96
|
fenceDraftStart,
|
|
92
97
|
fences,
|
|
@@ -107,13 +112,13 @@ export function useFloorplanBackgroundPlacement({
|
|
|
107
112
|
isRoofBuildActive,
|
|
108
113
|
isWallBuildActive,
|
|
109
114
|
isZoneBuildActive,
|
|
115
|
+
levelId,
|
|
110
116
|
roofDraftStart,
|
|
111
117
|
setCursorPoint,
|
|
112
118
|
setFenceDraftEnd,
|
|
113
119
|
setFenceDraftStart,
|
|
114
120
|
setRoofDraftEnd,
|
|
115
121
|
setRoofDraftStart,
|
|
116
|
-
shiftPressed,
|
|
117
122
|
snapWallDraftPoint,
|
|
118
123
|
snapPolygonDraftPoint,
|
|
119
124
|
toPoint2D,
|
|
@@ -144,22 +149,29 @@ export function useFloorplanBackgroundPlacement({
|
|
|
144
149
|
stopPropagation: () => {},
|
|
145
150
|
} as any)
|
|
146
151
|
}
|
|
152
|
+
// Drop the off-wall ghost on commit so it doesn't linger at the
|
|
153
|
+
// just-placed spot before the next pointer move re-evaluates.
|
|
154
|
+
usePlacementPreview.getState().clear()
|
|
147
155
|
return true
|
|
148
156
|
}
|
|
149
157
|
|
|
150
158
|
if (isCeilingBuildActive) {
|
|
151
|
-
// Align the committed vertex the same way the move-preview did, so
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
// Align the committed vertex the same way the move-preview did, so the
|
|
160
|
+
// placed point matches what the user saw — mode-driven (the chip):
|
|
161
|
+
// `grid` quantizes, `angles` locks 15° rays, `lines` snaps onto walls /
|
|
162
|
+
// alignment, `off` is free. Alt remains force/free at commit time.
|
|
163
|
+
const angleSnap = ceilingDraftPoints.length > 0 && isAngleSnapActive()
|
|
164
|
+
const fallbackPoint = snapPolygonDraftPoint({
|
|
156
165
|
point: planPoint,
|
|
157
166
|
start: ceilingDraftPoints[ceilingDraftPoints.length - 1],
|
|
158
167
|
angleSnap,
|
|
159
168
|
})
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
const snappedPoint = resolveCeilingPlanPointSnap({
|
|
170
|
+
rawPoint: planPoint,
|
|
171
|
+
fallbackPoint,
|
|
172
|
+
levelId,
|
|
173
|
+
align: !angleSnap,
|
|
174
|
+
}).point
|
|
163
175
|
|
|
164
176
|
emitFloorplanGridEvent('click', snappedPoint, event)
|
|
165
177
|
handleCeilingPlacementPoint(snappedPoint)
|
|
@@ -167,8 +179,11 @@ export function useFloorplanBackgroundPlacement({
|
|
|
167
179
|
}
|
|
168
180
|
|
|
169
181
|
if (isRoofBuildActive) {
|
|
182
|
+
// Footprint placement (polygon context: grid / lines / off, no angle),
|
|
183
|
+
// mode-driven to match the chip. Alt is force/free at commit time;
|
|
184
|
+
// alignment display/pull follows the active magnetic mode.
|
|
170
185
|
const snappedPoint = alignFloorplanDraftPoint(getSnappedFloorplanPoint(planPoint), {
|
|
171
|
-
|
|
186
|
+
applySnap: isMagneticSnapActive(),
|
|
172
187
|
})
|
|
173
188
|
emitFloorplanGridEvent('click', snappedPoint, event)
|
|
174
189
|
setCursorPoint(snappedPoint)
|
|
@@ -183,16 +198,19 @@ export function useFloorplanBackgroundPlacement({
|
|
|
183
198
|
}
|
|
184
199
|
|
|
185
200
|
if (isFenceBuildActive) {
|
|
186
|
-
// Fence draft:
|
|
187
|
-
//
|
|
188
|
-
// `gridSnap`
|
|
189
|
-
//
|
|
190
|
-
const fenceStep =
|
|
201
|
+
// Fence draft: mode-driven (matches the chip), same as the move
|
|
202
|
+
// preview. `grid` snaps to the world XZ grid (rotation-safe via the
|
|
203
|
+
// `gridSnap` callback), `angles` locks 15° rays from the start, `lines`
|
|
204
|
+
// pulls onto walls / fences / alignment, `off` is free.
|
|
205
|
+
const fenceStep = getSegmentGridStep()
|
|
206
|
+
const fenceAngleSnap = fenceDraftStart !== null && isAngleSnapActive()
|
|
191
207
|
const fenceSnapped = snapFenceDraftPoint({
|
|
192
208
|
point: planPoint,
|
|
193
209
|
walls,
|
|
194
210
|
fences,
|
|
195
|
-
|
|
211
|
+
start: fenceDraftStart ?? undefined,
|
|
212
|
+
angleSnap: fenceAngleSnap,
|
|
213
|
+
magnetic: isMagneticSnapActive(),
|
|
196
214
|
gridSnap: (p) => worldGridSnap(p, fenceStep),
|
|
197
215
|
})
|
|
198
216
|
const fenceGridBase = worldGridSnap(planPoint, fenceStep)
|
|
@@ -200,18 +218,42 @@ export function useFloorplanBackgroundPlacement({
|
|
|
200
218
|
fenceSnapped[0] !== fenceGridBase[0] || fenceSnapped[1] !== fenceGridBase[1]
|
|
201
219
|
const snappedPoint = fenceLocked
|
|
202
220
|
? fenceSnapped
|
|
203
|
-
: alignFloorplanDraftPoint(fenceSnapped, {
|
|
221
|
+
: alignFloorplanDraftPoint(fenceSnapped, {
|
|
222
|
+
applySnap: isMagneticSnapActive() && !fenceAngleSnap,
|
|
223
|
+
})
|
|
204
224
|
|
|
205
225
|
emitFloorplanGridEvent('click', snappedPoint, event)
|
|
206
226
|
setCursorPoint(snappedPoint)
|
|
207
227
|
|
|
228
|
+
// Double-click finishes the chain. The emit above already made the
|
|
229
|
+
// 3D fence tool stopDrafting (its detail >= 2 guard), so close the
|
|
230
|
+
// 2D draft too — leaving it open desyncs the two views.
|
|
231
|
+
if (fenceDraftStart && event.detail >= 2) {
|
|
232
|
+
clearFencePlacementDraft()
|
|
233
|
+
return true
|
|
234
|
+
}
|
|
235
|
+
|
|
208
236
|
if (!fenceDraftStart) {
|
|
209
237
|
setFenceDraftStart(snappedPoint)
|
|
210
238
|
setFenceDraftEnd(snappedPoint)
|
|
211
239
|
} else if (
|
|
212
240
|
getPlanPointDistance(toPoint2D(fenceDraftStart), toPoint2D(snappedPoint)) >= 0.01
|
|
213
241
|
) {
|
|
214
|
-
|
|
242
|
+
// Single mode commits one segment per click: the same emit above
|
|
243
|
+
// already made the 3D fence tool stopDrafting, so close the 2D
|
|
244
|
+
// draft too instead of chaining.
|
|
245
|
+
if (useEditor.getState().getContinuation('fence') === 'single') {
|
|
246
|
+
clearFencePlacementDraft()
|
|
247
|
+
setCursorPoint(snappedPoint)
|
|
248
|
+
return true
|
|
249
|
+
}
|
|
250
|
+
// The 3D fence tool owns creation and keeps chaining from the
|
|
251
|
+
// committed fence's resolved end — chain the 2D draft from the
|
|
252
|
+
// same published point so both views draft the next segment
|
|
253
|
+
// from the same start.
|
|
254
|
+
const nextStart = useSegmentDraftChain.getState().fence ?? snappedPoint
|
|
255
|
+
setFenceDraftStart(nextStart)
|
|
256
|
+
setFenceDraftEnd(nextStart)
|
|
215
257
|
} else {
|
|
216
258
|
setFenceDraftEnd(snappedPoint)
|
|
217
259
|
}
|
|
@@ -224,15 +266,20 @@ export function useFloorplanBackgroundPlacement({
|
|
|
224
266
|
// swallow the click and skip local draft state updates — leaving
|
|
225
267
|
// the 2D draft polygon invisible while the 3D tool builds fine).
|
|
226
268
|
if (isPolygonBuildActive) {
|
|
227
|
-
const angleSnap = activePolygonDraftPoints.length > 0 &&
|
|
228
|
-
|
|
269
|
+
const angleSnap = activePolygonDraftPoints.length > 0 && isAngleSnapActive()
|
|
270
|
+
const fallbackPoint = snapPolygonDraftPoint({
|
|
229
271
|
point: planPoint,
|
|
230
272
|
start: activePolygonDraftPoints[activePolygonDraftPoints.length - 1],
|
|
231
273
|
angleSnap,
|
|
232
274
|
})
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
275
|
+
// Zone shares the slab surface snap (wall corners / midpoints /
|
|
276
|
+
// crossings + alignment) — it's the same polygon-on-a-level draw.
|
|
277
|
+
const snappedPoint = resolveSlabPlanPointSnap({
|
|
278
|
+
rawPoint: planPoint,
|
|
279
|
+
fallbackPoint,
|
|
280
|
+
levelId,
|
|
281
|
+
align: !angleSnap,
|
|
282
|
+
}).point
|
|
236
283
|
|
|
237
284
|
// Emit the grid event so the registry-driven slab tool also
|
|
238
285
|
// sees the click (parity with ceiling / fence / roof branches
|
|
@@ -255,26 +302,45 @@ export function useFloorplanBackgroundPlacement({
|
|
|
255
302
|
// / draftEnd state in the floor plan would never update, leaving
|
|
256
303
|
// the dashed-line draft preview invisible.
|
|
257
304
|
if (isWallBuildActive) {
|
|
258
|
-
// Wall draft:
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
const
|
|
305
|
+
// Wall draft: mode-driven (matches the chip + the move-preview branch).
|
|
306
|
+
// `grid` snaps to the world XZ grid (rotation-safe via `gridSnap`),
|
|
307
|
+
// `angles` locks 15° rays from the start, `lines` pulls the endpoint
|
|
308
|
+
// onto existing wall corners / edges + alignment, `off` is free.
|
|
309
|
+
const wallStep = getSegmentGridStep()
|
|
310
|
+
const wallAngleSnap = draftStart !== null && isAngleSnapActive()
|
|
264
311
|
const wallSnapped = snapWallDraftPoint({
|
|
265
312
|
point: planPoint,
|
|
266
313
|
walls,
|
|
267
|
-
|
|
314
|
+
start: draftStart ?? undefined,
|
|
315
|
+
angleSnap: wallAngleSnap,
|
|
268
316
|
gridSnap: (p) => worldGridSnap(p, wallStep),
|
|
269
317
|
})
|
|
270
318
|
const wallGridBase = worldGridSnap(planPoint, wallStep)
|
|
271
319
|
const wallLocked = wallSnapped[0] !== wallGridBase[0] || wallSnapped[1] !== wallGridBase[1]
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
320
|
+
let snappedPoint = wallSnapped
|
|
321
|
+
if (wallLocked) {
|
|
322
|
+
useAlignmentGuides.getState().clear()
|
|
323
|
+
} else {
|
|
324
|
+
// Alignment lines are shown in every mode; the pull applies only when
|
|
325
|
+
// magnetic ('lines') and the segment isn't angle-locked.
|
|
326
|
+
snappedPoint = alignFloorplanDraftPoint(wallSnapped, {
|
|
327
|
+
applySnap: isMagneticSnapActive() && !wallAngleSnap,
|
|
328
|
+
})
|
|
329
|
+
}
|
|
275
330
|
|
|
276
331
|
emitFloorplanGridEvent('click', snappedPoint, event)
|
|
277
|
-
|
|
332
|
+
|
|
333
|
+
// Double-click finishes the chain. The emit above already made the
|
|
334
|
+
// 3D wall tool stopDrafting (its detail >= 2 guard), so close the
|
|
335
|
+
// 2D draft too — otherwise it stays open against a closed 3D tool
|
|
336
|
+
// and the next previewed segment is silently never created.
|
|
337
|
+
if (draftStart && event.detail >= 2) {
|
|
338
|
+
clearWallPlacementDraft()
|
|
339
|
+
setCursorPoint(snappedPoint)
|
|
340
|
+
return true
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
handleWallPlacementPoint(snappedPoint)
|
|
278
344
|
return true
|
|
279
345
|
}
|
|
280
346
|
|
|
@@ -291,7 +357,8 @@ export function useFloorplanBackgroundPlacement({
|
|
|
291
357
|
// local floor-plan draft handler (column / spawn / shelf / etc.).
|
|
292
358
|
// The tool's `grid:click` subscriber owns the placement.
|
|
293
359
|
if (isFloorplanGridInteractionActive) {
|
|
294
|
-
const snappedPoint =
|
|
360
|
+
const snappedPoint = getSnappedFloorplanPoint(planPoint)
|
|
361
|
+
emitFloorplanGridEvent('click', snappedPoint, event)
|
|
295
362
|
setCursorPoint(snappedPoint)
|
|
296
363
|
return true
|
|
297
364
|
}
|
|
@@ -303,6 +370,7 @@ export function useFloorplanBackgroundPlacement({
|
|
|
303
370
|
ceilingDraftPoints,
|
|
304
371
|
clearFencePlacementDraft,
|
|
305
372
|
clearRoofPlacementDraft,
|
|
373
|
+
clearWallPlacementDraft,
|
|
306
374
|
emitFloorplanGridEvent,
|
|
307
375
|
fenceDraftStart,
|
|
308
376
|
fences,
|
|
@@ -322,13 +390,13 @@ export function useFloorplanBackgroundPlacement({
|
|
|
322
390
|
isRoofBuildActive,
|
|
323
391
|
isWallBuildActive,
|
|
324
392
|
isZoneBuildActive,
|
|
393
|
+
levelId,
|
|
325
394
|
roofDraftStart,
|
|
326
395
|
setCursorPoint,
|
|
327
396
|
setFenceDraftEnd,
|
|
328
397
|
setFenceDraftStart,
|
|
329
398
|
setRoofDraftEnd,
|
|
330
399
|
setRoofDraftStart,
|
|
331
|
-
shiftPressed,
|
|
332
400
|
snapWallDraftPoint,
|
|
333
401
|
snapPolygonDraftPoint,
|
|
334
402
|
toPoint2D,
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { collectRegistrySelectionIdsInBounds } from './use-floorplan-hit-testing'
|
|
3
|
+
|
|
4
|
+
const identityMatrix = {
|
|
5
|
+
inverse() {
|
|
6
|
+
return this
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function pointFactory() {
|
|
11
|
+
return {
|
|
12
|
+
x: 0,
|
|
13
|
+
y: 0,
|
|
14
|
+
matrixTransform() {
|
|
15
|
+
return pointFactoryWithPosition(this.x, this.y)
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pointFactoryWithPosition(x: number, y: number) {
|
|
21
|
+
return {
|
|
22
|
+
x,
|
|
23
|
+
y,
|
|
24
|
+
matrixTransform() {
|
|
25
|
+
return pointFactoryWithPosition(x, y)
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function geometry(x: number, y: number, width: number, height: number) {
|
|
31
|
+
return {
|
|
32
|
+
getBBox: () => ({ x, y, width, height }),
|
|
33
|
+
getScreenCTM: () => identityMatrix,
|
|
34
|
+
} as unknown as SVGGraphicsElement
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function entry(nodeId: string, children: SVGGraphicsElement[]) {
|
|
38
|
+
return {
|
|
39
|
+
dataset: { nodeId },
|
|
40
|
+
querySelectorAll: () => children,
|
|
41
|
+
} as unknown as SVGGElement
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function scene(entries: SVGGElement[]) {
|
|
45
|
+
return {
|
|
46
|
+
getScreenCTM: () => identityMatrix,
|
|
47
|
+
ownerSVGElement: {
|
|
48
|
+
createSVGPoint: pointFactory,
|
|
49
|
+
},
|
|
50
|
+
querySelectorAll: () => entries,
|
|
51
|
+
} as unknown as SVGGElement
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe('collectRegistrySelectionIdsInBounds', () => {
|
|
55
|
+
test('selects rendered registry geometry and preserves candidate order', () => {
|
|
56
|
+
const renderedScene = scene([
|
|
57
|
+
entry('wall_1', [geometry(0, 0, 4, 0.2)]),
|
|
58
|
+
entry('door_1', [geometry(1, 1, 0.9, 0.9)]),
|
|
59
|
+
entry('outside_1', [geometry(20, 20, 1, 1)]),
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
expect(
|
|
63
|
+
collectRegistrySelectionIdsInBounds(renderedScene, { minX: -1, minY: -1, maxX: 5, maxY: 5 }, [
|
|
64
|
+
'door_1',
|
|
65
|
+
'outside_1',
|
|
66
|
+
'wall_1',
|
|
67
|
+
]),
|
|
68
|
+
).toEqual(['door_1', 'wall_1'])
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('ignores rendered entries outside the selectable registry candidates', () => {
|
|
72
|
+
const renderedScene = scene([entry('zone_1', [geometry(0, 0, 2, 2)])])
|
|
73
|
+
|
|
74
|
+
expect(
|
|
75
|
+
collectRegistrySelectionIdsInBounds(
|
|
76
|
+
renderedScene,
|
|
77
|
+
{ minX: -1, minY: -1, maxX: 3, maxY: 3 },
|
|
78
|
+
[],
|
|
79
|
+
),
|
|
80
|
+
).toEqual([])
|
|
81
|
+
})
|
|
82
|
+
})
|