@pascal-app/nodes 1.0.1 → 1.0.3
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/dist/block/definition.d.ts.map +1 -1
- package/dist/block/definition.js +4 -1
- package/dist/block/face-host.d.ts.map +1 -1
- package/dist/block/face-host.js +19 -2
- package/dist/block/hosted-edit.d.ts +13 -0
- package/dist/block/hosted-edit.d.ts.map +1 -0
- package/dist/block/hosted-edit.js +205 -0
- package/dist/block/last-operation.d.ts +1 -1
- package/dist/block/last-operation.d.ts.map +1 -1
- package/dist/block/last-operation.js +6 -4
- package/dist/block/modal-session.d.ts +2 -1
- package/dist/block/modal-session.d.ts.map +1 -1
- package/dist/block/modal-session.js +2 -2
- package/dist/block/selection.d.ts.map +1 -1
- package/dist/block/selection.js +82 -24
- package/dist/block/surface.d.ts +4 -0
- package/dist/block/surface.d.ts.map +1 -0
- package/dist/block/surface.js +54 -0
- package/dist/block/use-block-face-operation.d.ts +2 -2
- package/dist/block/use-block-face-operation.d.ts.map +1 -1
- package/dist/block/use-block-face-operation.js +25 -11
- package/dist/box-vent/definition.d.ts.map +1 -1
- package/dist/box-vent/definition.js +1 -0
- package/dist/building/renderer.d.ts.map +1 -1
- package/dist/building/renderer.js +1 -1
- package/dist/cabinet/definition.d.ts.map +1 -1
- package/dist/cabinet/definition.js +3 -1
- package/dist/cabinet/hosted-resize.d.ts +3 -6
- package/dist/cabinet/hosted-resize.d.ts.map +1 -1
- package/dist/cabinet/hosted-resize.js +9 -153
- package/dist/cabinet/placement-snap.d.ts.map +1 -1
- package/dist/cabinet/placement-snap.js +4 -2
- package/dist/cabinet/surfaces.d.ts +1 -0
- package/dist/cabinet/surfaces.d.ts.map +1 -1
- package/dist/cabinet/surfaces.js +13 -1
- package/dist/cabinet/tool.d.ts.map +1 -1
- package/dist/cabinet/tool.js +8 -4
- package/dist/ceiling/definition.d.ts.map +1 -1
- package/dist/ceiling/definition.js +5 -0
- package/dist/ceiling/renderer.d.ts.map +1 -1
- package/dist/ceiling/renderer.js +3 -2
- package/dist/chimney/definition.d.ts.map +1 -1
- package/dist/chimney/definition.js +1 -0
- package/dist/column/definition.d.ts.map +1 -1
- package/dist/column/definition.js +10 -3
- package/dist/column/floorplan-affordances.d.ts.map +1 -1
- package/dist/column/floorplan-affordances.js +6 -1
- package/dist/column/floorplan.d.ts.map +1 -1
- package/dist/column/floorplan.js +23 -11
- package/dist/column/hosted-resize.d.ts +116 -0
- package/dist/column/hosted-resize.d.ts.map +1 -0
- package/dist/column/hosted-resize.js +9 -0
- package/dist/column/panel.d.ts.map +1 -1
- package/dist/column/panel.js +6 -3
- package/dist/column/renderer.d.ts.map +1 -1
- package/dist/column/renderer.js +25 -103
- package/dist/column/shape.d.ts +22 -0
- package/dist/column/shape.d.ts.map +1 -0
- package/dist/column/shape.js +120 -0
- package/dist/column/surface.d.ts +4 -0
- package/dist/column/surface.d.ts.map +1 -0
- package/dist/column/surface.js +66 -0
- package/dist/cupola/definition.d.ts.map +1 -1
- package/dist/cupola/definition.js +1 -0
- package/dist/door/definition.d.ts.map +1 -1
- package/dist/door/definition.js +40 -1
- package/dist/door/door-math.d.ts +1 -1
- package/dist/door/door-math.d.ts.map +1 -1
- package/dist/door/door-math.js +7 -10
- package/dist/door/floorplan-affordances.d.ts.map +1 -1
- package/dist/door/floorplan-affordances.js +8 -12
- package/dist/door/move-tool.d.ts.map +1 -1
- package/dist/door/move-tool.js +3 -4
- package/dist/door/panel.d.ts.map +1 -1
- package/dist/door/panel.js +23 -52
- package/dist/door/tool.d.ts.map +1 -1
- package/dist/door/tool.js +20 -2
- package/dist/dormer/definition.d.ts.map +1 -1
- package/dist/dormer/definition.js +1 -0
- package/dist/downspout/definition.d.ts.map +1 -1
- package/dist/downspout/definition.js +1 -0
- package/dist/duct-segment/tool.d.ts.map +1 -1
- package/dist/duct-segment/tool.js +11 -0
- package/dist/duct-terminal/tool.d.ts.map +1 -1
- package/dist/duct-terminal/tool.js +77 -8
- package/dist/elevator/definition.d.ts.map +1 -1
- package/dist/elevator/definition.js +2 -0
- package/dist/elevator/parametrics.d.ts.map +1 -1
- package/dist/elevator/parametrics.js +98 -1
- package/dist/eyebrow-vent/definition.d.ts.map +1 -1
- package/dist/eyebrow-vent/definition.js +1 -0
- package/dist/fence/definition.d.ts.map +1 -1
- package/dist/fence/definition.js +1 -0
- package/dist/fence/tool.js +2 -2
- package/dist/guide/definition.d.ts.map +1 -1
- package/dist/guide/definition.js +1 -0
- package/dist/gutter/definition.d.ts.map +1 -1
- package/dist/gutter/definition.js +1 -0
- package/dist/hvac-equipment/tool.d.ts.map +1 -1
- package/dist/hvac-equipment/tool.js +8 -2
- package/dist/item/__fixtures__/main-floorplan.d.ts +26 -0
- package/dist/item/__fixtures__/main-floorplan.d.ts.map +1 -0
- package/dist/item/__fixtures__/main-floorplan.js +297 -0
- package/dist/item/definition.d.ts.map +1 -1
- package/dist/item/definition.js +3 -1
- package/dist/item/floorplan-move.d.ts.map +1 -1
- package/dist/item/floorplan-move.js +209 -130
- package/dist/item/floorplan.d.ts +22 -0
- package/dist/item/floorplan.d.ts.map +1 -1
- package/dist/item/floorplan.js +61 -2
- package/dist/item/move-tool.d.ts +1 -1
- package/dist/item/move-tool.d.ts.map +1 -1
- package/dist/item/move-tool.js +15 -7
- package/dist/item/renderer.d.ts.map +1 -1
- package/dist/item/renderer.js +8 -2
- package/dist/level/renderer.js +1 -1
- package/dist/lineset/tool.d.ts.map +1 -1
- package/dist/lineset/tool.js +1 -0
- package/dist/liquid-line/tool.d.ts.map +1 -1
- package/dist/liquid-line/tool.js +5 -1
- package/dist/measurement/definition.d.ts.map +1 -1
- package/dist/measurement/definition.js +1 -0
- package/dist/pipe-segment/tool.d.ts.map +1 -1
- package/dist/pipe-segment/tool.js +14 -3
- package/dist/pipe-trap/tool.d.ts.map +1 -1
- package/dist/pipe-trap/tool.js +7 -8
- package/dist/procedural-item/definition.d.ts.map +1 -1
- package/dist/procedural-item/definition.js +4 -1
- package/dist/ridge-vent/definition.d.ts.map +1 -1
- package/dist/ridge-vent/definition.js +1 -0
- package/dist/roof/definition.d.ts.map +1 -1
- package/dist/roof/definition.js +4 -1
- package/dist/roof/panel-model.d.ts +4 -0
- package/dist/roof/panel-model.d.ts.map +1 -0
- package/dist/roof/panel-model.js +151 -0
- package/dist/roof/panel.d.ts.map +1 -1
- package/dist/roof/panel.js +3 -4
- package/dist/roof/parametrics.d.ts.map +1 -1
- package/dist/roof/parametrics.js +16 -1
- package/dist/roof-segment/definition.d.ts.map +1 -1
- package/dist/roof-segment/definition.js +1 -0
- package/dist/roof-segment/parametrics.d.ts.map +1 -1
- package/dist/roof-segment/parametrics.js +176 -1
- package/dist/scan/definition.d.ts.map +1 -1
- package/dist/scan/definition.js +1 -0
- package/dist/shared/commit-opening-move.d.ts +4 -0
- package/dist/shared/commit-opening-move.d.ts.map +1 -0
- package/dist/shared/commit-opening-move.js +9 -0
- package/dist/shared/curtain-opening-limits.d.ts +14 -0
- package/dist/shared/curtain-opening-limits.d.ts.map +1 -0
- package/dist/shared/curtain-opening-limits.js +53 -0
- package/dist/shared/draft-axis-guides.d.ts +0 -6
- package/dist/shared/draft-axis-guides.d.ts.map +1 -1
- package/dist/shared/draft-axis-guides.js +1 -8
- package/dist/shared/hosted-resize.d.ts +12 -0
- package/dist/shared/hosted-resize.d.ts.map +1 -0
- package/dist/shared/hosted-resize.js +166 -0
- package/dist/shared/opening-grid-follow.d.ts +8 -0
- package/dist/shared/opening-grid-follow.d.ts.map +1 -0
- package/dist/shared/opening-grid-follow.js +12 -0
- package/dist/shared/opening-property-preview-host.d.ts +3 -0
- package/dist/shared/opening-property-preview-host.d.ts.map +1 -0
- package/dist/shared/opening-property-preview-host.js +21 -0
- package/dist/shared/opening-property-preview.d.ts +19 -0
- package/dist/shared/opening-property-preview.d.ts.map +1 -0
- package/dist/shared/opening-property-preview.js +99 -0
- package/dist/shared/resting-surface-plan.d.ts +2 -1
- package/dist/shared/resting-surface-plan.d.ts.map +1 -1
- package/dist/shared/resting-surface-plan.js +29 -4
- package/dist/shared/surface-counterparts.d.ts +12 -0
- package/dist/shared/surface-counterparts.d.ts.map +1 -0
- package/dist/shared/surface-counterparts.js +27 -0
- package/dist/shared/wall-attach-target.d.ts +1 -0
- package/dist/shared/wall-attach-target.d.ts.map +1 -1
- package/dist/shared/wall-attach-target.js +4 -1
- package/dist/shared/wall-event-from-grid.d.ts +5 -0
- package/dist/shared/wall-event-from-grid.d.ts.map +1 -0
- package/dist/shared/wall-event-from-grid.js +36 -0
- package/dist/shelf/definition.d.ts.map +1 -1
- package/dist/shelf/definition.js +3 -1
- package/dist/shelf/floorplan.d.ts.map +1 -1
- package/dist/shelf/floorplan.js +9 -2
- package/dist/site/renderer.d.ts.map +1 -1
- package/dist/site/renderer.js +9 -2
- package/dist/skylight/definition.d.ts.map +1 -1
- package/dist/skylight/definition.js +1 -0
- package/dist/slab/definition.d.ts.map +1 -1
- package/dist/slab/definition.js +4 -0
- package/dist/solar-panel/definition.d.ts.map +1 -1
- package/dist/solar-panel/definition.js +1 -0
- package/dist/spawn/definition.d.ts.map +1 -1
- package/dist/spawn/definition.js +1 -0
- package/dist/stair/definition.d.ts.map +1 -1
- package/dist/stair/definition.js +2 -0
- package/dist/stair/parametrics.d.ts.map +1 -1
- package/dist/stair/parametrics.js +164 -1
- package/dist/stair-segment/definition.d.ts.map +1 -1
- package/dist/stair-segment/definition.js +1 -0
- package/dist/stair-segment/parametrics.d.ts.map +1 -1
- package/dist/stair-segment/parametrics.js +81 -1
- package/dist/turbine-vent/definition.d.ts.map +1 -1
- package/dist/turbine-vent/definition.js +1 -0
- package/dist/wall/actions.d.ts +3 -0
- package/dist/wall/actions.d.ts.map +1 -0
- package/dist/wall/actions.js +56 -0
- package/dist/wall/curtain-opening-frame.d.ts +14 -0
- package/dist/wall/curtain-opening-frame.d.ts.map +1 -0
- package/dist/wall/curtain-opening-frame.js +111 -0
- package/dist/wall/curtain-panel-highlight.d.ts +3 -0
- package/dist/wall/curtain-panel-highlight.d.ts.map +1 -0
- package/dist/wall/curtain-panel-highlight.js +113 -0
- package/dist/wall/curtain-wall-adapter.d.ts +3 -0
- package/dist/wall/curtain-wall-adapter.d.ts.map +1 -0
- package/dist/wall/curtain-wall-adapter.js +55 -0
- package/dist/wall/curtain-wall-floorplan.d.ts +3 -0
- package/dist/wall/curtain-wall-floorplan.d.ts.map +1 -0
- package/dist/wall/curtain-wall-floorplan.js +91 -0
- package/dist/wall/curtain-wall-geometry.d.ts +4 -0
- package/dist/wall/curtain-wall-geometry.d.ts.map +1 -0
- package/dist/wall/curtain-wall-geometry.js +226 -0
- package/dist/wall/curtain-wall-layout.d.ts +16 -0
- package/dist/wall/curtain-wall-layout.d.ts.map +1 -0
- package/dist/wall/curtain-wall-layout.js +176 -0
- package/dist/wall/curtain-wall-materials.d.ts +5 -0
- package/dist/wall/curtain-wall-materials.d.ts.map +1 -0
- package/dist/wall/curtain-wall-materials.js +55 -0
- package/dist/wall/curtain-wall-panel.d.ts +14 -0
- package/dist/wall/curtain-wall-panel.d.ts.map +1 -0
- package/dist/wall/curtain-wall-panel.js +167 -0
- package/dist/wall/curtain-wall-piece-geometry.d.ts +5 -0
- package/dist/wall/curtain-wall-piece-geometry.d.ts.map +1 -0
- package/dist/wall/curtain-wall-piece-geometry.js +220 -0
- package/dist/wall/curtain-wall-shadow.d.ts +4 -0
- package/dist/wall/curtain-wall-shadow.d.ts.map +1 -0
- package/dist/wall/curtain-wall-shadow.js +15 -0
- package/dist/wall/definition.d.ts +0 -15
- package/dist/wall/definition.d.ts.map +1 -1
- package/dist/wall/definition.js +65 -4
- package/dist/wall/drawing-mode.d.ts +12 -0
- package/dist/wall/drawing-mode.d.ts.map +1 -0
- package/dist/wall/drawing-mode.js +38 -0
- package/dist/wall/floorplan-tool.d.ts +4 -0
- package/dist/wall/floorplan-tool.d.ts.map +1 -0
- package/dist/wall/floorplan-tool.js +107 -0
- package/dist/wall/floorplan.d.ts.map +1 -1
- package/dist/wall/floorplan.js +6 -2
- package/dist/wall/length-patch.d.ts +3 -0
- package/dist/wall/length-patch.d.ts.map +1 -0
- package/dist/wall/length-patch.js +14 -0
- package/dist/wall/move-tool.d.ts.map +1 -1
- package/dist/wall/move-tool.js +23 -1
- package/dist/wall/paint.d.ts.map +1 -1
- package/dist/wall/paint.js +39 -4
- package/dist/wall/panel-model.d.ts +4 -0
- package/dist/wall/panel-model.d.ts.map +1 -0
- package/dist/wall/panel-model.js +117 -0
- package/dist/wall/panel.d.ts.map +1 -1
- package/dist/wall/panel.js +20 -24
- package/dist/wall/property-preview.d.ts +7 -0
- package/dist/wall/property-preview.d.ts.map +1 -0
- package/dist/wall/property-preview.js +31 -0
- package/dist/wall/rectangle-command.d.ts +149 -0
- package/dist/wall/rectangle-command.d.ts.map +1 -0
- package/dist/wall/rectangle-command.js +22 -0
- package/dist/wall/rectangle-tool.d.ts +2 -0
- package/dist/wall/rectangle-tool.d.ts.map +1 -0
- package/dist/wall/rectangle-tool.js +147 -0
- package/dist/wall/renderer.d.ts.map +1 -1
- package/dist/wall/renderer.js +7 -4
- package/dist/wall/slots.d.ts +2 -2
- package/dist/wall/slots.d.ts.map +1 -1
- package/dist/wall/slots.js +10 -2
- package/dist/wall/split-floorplan-layer.d.ts +4 -0
- package/dist/wall/split-floorplan-layer.d.ts.map +1 -0
- package/dist/wall/split-floorplan-layer.js +71 -0
- package/dist/wall/split-pointer.d.ts +3 -0
- package/dist/wall/split-pointer.d.ts.map +1 -0
- package/dist/wall/split-pointer.js +95 -0
- package/dist/wall/split-preview.d.ts +55 -0
- package/dist/wall/split-preview.d.ts.map +1 -0
- package/dist/wall/split-preview.js +106 -0
- package/dist/wall/split-session.d.ts +16 -0
- package/dist/wall/split-session.d.ts.map +1 -0
- package/dist/wall/split-session.js +138 -0
- package/dist/wall/split-store.d.ts +16 -0
- package/dist/wall/split-store.d.ts.map +1 -0
- package/dist/wall/split-store.js +6 -0
- package/dist/wall/split-tool.d.ts +10 -0
- package/dist/wall/split-tool.d.ts.map +1 -0
- package/dist/wall/split-tool.js +95 -0
- package/dist/wall/system.d.ts.map +1 -1
- package/dist/wall/system.js +3 -1
- package/dist/wall/tool.d.ts.map +1 -1
- package/dist/wall/tool.js +14 -6
- package/dist/wall/wall-batch-system.d.ts.map +1 -1
- package/dist/wall/wall-batch-system.js +3 -0
- package/dist/window/definition.d.ts.map +1 -1
- package/dist/window/definition.js +48 -1
- package/dist/window/floorplan-affordances.d.ts.map +1 -1
- package/dist/window/floorplan-affordances.js +8 -10
- package/dist/window/move-tool.d.ts.map +1 -1
- package/dist/window/move-tool.js +4 -6
- package/dist/window/panel.d.ts.map +1 -1
- package/dist/window/panel.js +21 -59
- package/dist/window/tool.d.ts.map +1 -1
- package/dist/window/tool.js +34 -2
- package/dist/window/window-math.d.ts +1 -1
- package/dist/window/window-math.d.ts.map +1 -1
- package/dist/window/window-math.js +8 -11
- package/dist/zone/definition.d.ts.map +1 -1
- package/dist/zone/definition.js +1 -0
- package/dist/zone/quantities-panel.d.ts.map +1 -1
- package/dist/zone/quantities-panel.js +3 -19
- package/dist/zone/renderer.d.ts.map +1 -1
- package/dist/zone/renderer.js +1 -1
- package/package.json +8 -8
- package/dist/shared/opening-documentation-fields.d.ts +0 -16
- package/dist/shared/opening-documentation-fields.d.ts.map +0 -1
- package/dist/shared/opening-documentation-fields.js +0 -54
package/dist/door/move-tool.js
CHANGED
|
@@ -5,6 +5,7 @@ import { useViewer } from '@pascal-app/viewer';
|
|
|
5
5
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
|
|
7
7
|
import { LineBasicNodeMaterial } from 'three/webgpu';
|
|
8
|
+
import { commitOpeningMove } from '../shared/commit-opening-move';
|
|
8
9
|
import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, } from '../shared/opening-guides-runtime';
|
|
9
10
|
import { beginOpeningMoveHistorySession } from '../shared/opening-move-history';
|
|
10
11
|
import { isWallMeshHidden, shouldIgnoreWallEventForOpeningMove, } from '../shared/opening-move-wall-gate';
|
|
@@ -451,14 +452,13 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
451
452
|
visible: original.visible,
|
|
452
453
|
});
|
|
453
454
|
history.commitStep(() => {
|
|
454
|
-
|
|
455
|
+
commitOpeningMove(movingDoorNode.id, {
|
|
455
456
|
position: [target.clampedX, target.clampedY, 0],
|
|
456
457
|
rotation: [0, target.itemRotation, 0],
|
|
457
458
|
side: target.side,
|
|
458
459
|
parentId: target.wallId,
|
|
459
460
|
wallId: target.wallId,
|
|
460
461
|
roofSegmentId: undefined,
|
|
461
|
-
metadata: {},
|
|
462
462
|
visible: true,
|
|
463
463
|
});
|
|
464
464
|
});
|
|
@@ -712,7 +712,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
712
712
|
visible: original.visible,
|
|
713
713
|
});
|
|
714
714
|
history.commitStep(() => {
|
|
715
|
-
|
|
715
|
+
commitOpeningMove(movingDoorNode.id, {
|
|
716
716
|
position: target.position,
|
|
717
717
|
rotation: [0, 0, 0],
|
|
718
718
|
side: 'front',
|
|
@@ -720,7 +720,6 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
|
|
|
720
720
|
wallId: undefined,
|
|
721
721
|
roofSegmentId: segmentId,
|
|
722
722
|
roofFace: target.face.id,
|
|
723
|
-
metadata: {},
|
|
724
723
|
visible: true,
|
|
725
724
|
});
|
|
726
725
|
});
|
package/dist/door/panel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/door/panel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/door/panel.tsx"],"names":[],"mappings":"AAyIA,MAAM,CAAC,OAAO,UAAU,SAAS,uCA+nChC"}
|
package/dist/door/panel.js
CHANGED
|
@@ -4,8 +4,10 @@ import { DoorNode, useInteractive, useScene } from '@pascal-app/core';
|
|
|
4
4
|
import { ActionButton, ActionGroup, cn, PanelSection, PanelWrapper, SegmentedControl, SliderControl, ToggleControl, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Copy, DoorOpen, FlipHorizontal2, Move, Trash2 } from 'lucide-react';
|
|
7
|
-
import { useCallback,
|
|
8
|
-
import {
|
|
7
|
+
import { useCallback, useEffect, useMemo } from 'react';
|
|
8
|
+
import { constrainCurtainOpening, curtainOpeningLimits } from '../shared/curtain-opening-limits';
|
|
9
|
+
import { createOpeningPropertyPreview } from '../shared/opening-property-preview';
|
|
10
|
+
import { openingPropertyPreviewHost } from '../shared/opening-property-preview-host';
|
|
9
11
|
import { scaleHandleHeight } from './door-math';
|
|
10
12
|
const doorTypeOptions = [
|
|
11
13
|
{ label: 'Hinged', value: 'hinged', available: true },
|
|
@@ -106,7 +108,10 @@ export default function DoorPanel() {
|
|
|
106
108
|
const setSelection = useViewer((s) => s.setSelection);
|
|
107
109
|
const deleteNode = useScene((s) => s.deleteNode);
|
|
108
110
|
const setMovingNode = useEditor((s) => s.setMovingNode);
|
|
109
|
-
const
|
|
111
|
+
const preview = useMemo(() => selectedId
|
|
112
|
+
? createOpeningPropertyPreview(selectedId, openingPropertyPreviewHost)
|
|
113
|
+
: null, [selectedId]);
|
|
114
|
+
useEffect(() => () => preview?.cancel(), [preview]);
|
|
110
115
|
const node = useScene((s) => selectedId ? s.nodes[selectedId] : undefined);
|
|
111
116
|
// Panel slider-drag fix recipe (plans/editor-node-registry.md). Without
|
|
112
117
|
// it, the 29+ SliderControls in this panel would loop on drag.
|
|
@@ -116,6 +121,7 @@ export default function DoorPanel() {
|
|
|
116
121
|
const liveNode = useScene.getState().nodes[selectedId];
|
|
117
122
|
if (liveNode?.type !== 'door')
|
|
118
123
|
return;
|
|
124
|
+
updates = constrainCurtainOpening(liveNode, updates, useScene.getState().nodes);
|
|
119
125
|
const hasChange = Object.entries(updates).some(([key, value]) => {
|
|
120
126
|
const currentValue = liveNode[key];
|
|
121
127
|
return !isSameDoorValue(currentValue, value);
|
|
@@ -131,43 +137,8 @@ export default function DoorPanel() {
|
|
|
131
137
|
if (liveNode.parentId)
|
|
132
138
|
scene.dirtyNodes.add(liveNode.parentId);
|
|
133
139
|
}, [selectedId]);
|
|
134
|
-
const previewDoorUpdate =
|
|
135
|
-
|
|
136
|
-
return;
|
|
137
|
-
const liveNode = useScene.getState().nodes[selectedId];
|
|
138
|
-
if (liveNode?.type !== 'door')
|
|
139
|
-
return;
|
|
140
|
-
if (!(previewRef.current &&
|
|
141
|
-
previewRef.current.id === selectedId &&
|
|
142
|
-
previewRef.current.key === key)) {
|
|
143
|
-
previewRef.current = {
|
|
144
|
-
id: selectedId,
|
|
145
|
-
key,
|
|
146
|
-
value: liveNode[key],
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (isSameDoorValue(liveNode[key], value))
|
|
150
|
-
return;
|
|
151
|
-
liveNode[key] = value;
|
|
152
|
-
useScene.getState().dirtyNodes.add(selectedId);
|
|
153
|
-
}, [selectedId]);
|
|
154
|
-
const commitDoorPreview = useCallback((key, value) => {
|
|
155
|
-
if (!selectedId)
|
|
156
|
-
return;
|
|
157
|
-
const scene = useScene.getState();
|
|
158
|
-
const liveNode = scene.nodes[selectedId];
|
|
159
|
-
const preview = previewRef.current;
|
|
160
|
-
if (liveNode?.type === 'door' && preview?.id === selectedId && preview.key === key) {
|
|
161
|
-
;
|
|
162
|
-
liveNode[key] = preview.value;
|
|
163
|
-
scene.dirtyNodes.add(selectedId);
|
|
164
|
-
}
|
|
165
|
-
previewRef.current = null;
|
|
166
|
-
useScene
|
|
167
|
-
.getState()
|
|
168
|
-
.updateNode(selectedId, { [key]: value });
|
|
169
|
-
scene.dirtyNodes.add(selectedId);
|
|
170
|
-
}, [selectedId]);
|
|
140
|
+
const previewDoorUpdate = (key, value) => preview?.preview({ [key]: value });
|
|
141
|
+
const commitDoorPreview = (key, value) => preview?.commit({ [key]: value });
|
|
171
142
|
const handleClose = useCallback(() => {
|
|
172
143
|
setSelection({ selectedIds: [] });
|
|
173
144
|
}, [setSelection]);
|
|
@@ -254,6 +225,12 @@ export default function DoorPanel() {
|
|
|
254
225
|
};
|
|
255
226
|
if (!(node && node.type === 'door' && selectedId))
|
|
256
227
|
return null;
|
|
228
|
+
const limits = curtainOpeningLimits(node, useScene.getState().nodes);
|
|
229
|
+
const heightUpdates = (height) => ({
|
|
230
|
+
height,
|
|
231
|
+
position: [node.position[0], height / 2, node.position[2]],
|
|
232
|
+
handleHeight: scaleHandleHeight(node.handleHeight, node.height, height),
|
|
233
|
+
});
|
|
257
234
|
const hSum = node.segments.reduce((s, seg) => s + seg.heightRatio, 0);
|
|
258
235
|
const normHeights = node.segments.map((seg) => seg.heightRatio / hSum);
|
|
259
236
|
const isOpening = node.openingKind === 'opening';
|
|
@@ -478,19 +455,13 @@ export default function DoorPanel() {
|
|
|
478
455
|
? 'border-orange-400/60 bg-orange-400/10 text-foreground'
|
|
479
456
|
: 'border-border/50 bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground', !option.available &&
|
|
480
457
|
'cursor-not-allowed opacity-45 hover:bg-[#2C2C2E] hover:text-muted-foreground'), disabled: !option.available, onClick: () => handleUpdate(getDoorTypeUpdates(option.value)), type: "button", children: [_jsx(DoorOpen, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate font-medium", children: option.label })] }, option.value));
|
|
481
|
-
}) }))] }),
|
|
458
|
+
}) }))] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: _jsxs(_Fragment, { children: ["X", _jsx("sub", { className: "ml-[1px] text-[11px] opacity-70", children: "wall" })] }), max: 10, min: -10, onChange: (v) => handleUpdate({ position: [v, node.position[1], node.position[2]] }), precision: 2, step: 0.1, unit: "m", value: node.position[0] }), showFlipSide && (_jsx("div", { className: "px-1 pt-2 pb-1", children: _jsx(ActionButton, { className: "w-full", icon: _jsx(FlipHorizontal2, { className: "h-4 w-4" }), label: "Flip Side", onClick: handleFlip }) }))] }), showFoldSection && (_jsxs(PanelSection, { title: "Fold", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Panels" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ leafCount: v === '2' ? 2 : 4 }), options: [
|
|
482
459
|
{ label: '2', value: '2' },
|
|
483
460
|
{ label: '4', value: '4' },
|
|
484
461
|
], value: node.leafCount === 2 ? '2' : '4' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showSlideSection && (_jsxs(PanelSection, { title: "Slide", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: doorType === 'pocket' ? 'Pocket' : doorType === 'barn' ? 'Rail' : 'Panel' }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ slideDirection: v }), options: [
|
|
485
462
|
{ label: 'Left', value: 'left' },
|
|
486
463
|
{ label: 'Right', value: 'right' },
|
|
487
|
-
], value: node.slideDirection ?? 'left' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showGarageSection && (_jsxs(PanelSection, { title: "Garage", children: [_jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) }), isSectionalGarageDoor && (_jsx(SliderControl, { label: "Panels", max: 8, min: 3, onChange: (v) => handleUpdate({ garagePanelCount: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: node.garagePanelCount ?? 4 }))] })), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: maxDoorWidth, min: 0.5, onChange: (v) =>
|
|
488
|
-
height: v,
|
|
489
|
-
position: [node.position[0], v / 2, node.position[2]],
|
|
490
|
-
// Keep the handle at the same relative height as the door resizes,
|
|
491
|
-
// matching the height-resize arrow.
|
|
492
|
-
handleHeight: scaleHandleHeight(node.handleHeight, node.height, v),
|
|
493
|
-
}), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.height })] }), showDoorShapeSection && (_jsxs(PanelSection, { title: "Top Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
464
|
+
], value: node.slideDirection ?? 'left' })] }) }), _jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) })] })), showGarageSection && (_jsxs(PanelSection, { title: "Garage", children: [_jsx(SliderControl, { label: "Open", max: 100, min: 0, onChange: (v) => handleUpdate({ operationState: v / 100 }), precision: 0, restoreOnCommit: false, step: 5, unit: "%", value: Math.round((node.operationState ?? 0) * 100) }), isSectionalGarageDoor && (_jsx(SliderControl, { label: "Panels", max: 8, min: 3, onChange: (v) => handleUpdate({ garagePanelCount: Math.round(v) }), precision: 0, restoreOnCommit: false, step: 1, value: node.garagePanelCount ?? 4 }))] })), _jsxs(PanelSection, { title: "Dimensions", children: [limits && (_jsx("p", { className: "text-[11px] text-muted-foreground", children: "Size is limited to the wall, including clearance for the opening frame." })), _jsx(SliderControl, { label: "Width", max: Math.min(maxDoorWidth, limits?.width ?? Infinity), min: Math.min(0.5, limits?.width ?? 0.5), onChange: (v) => previewDoorUpdate('width', v), onCommit: (v) => commitDoorPreview('width', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.01, unit: "m", value: node.width }), _jsx(SliderControl, { label: "Height", max: limits?.height ?? 1000, min: Math.min(1, limits?.height ?? 1), onChange: (v) => preview?.preview(heightUpdates(v)), onCommit: (v) => preview?.commit(heightUpdates(v)), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.01, unit: "m", value: node.height })] }), showDoorShapeSection && (_jsxs(PanelSection, { title: "Top Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
494
465
|
openingShape: v,
|
|
495
466
|
...(v === 'rounded'
|
|
496
467
|
? {
|
|
@@ -508,10 +479,10 @@ export default function DoorPanel() {
|
|
|
508
479
|
], value: doorShape }) }), doorShape === 'rounded' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ openingRadiusMode: v }), options: [
|
|
509
480
|
{ label: 'All', value: 'all' },
|
|
510
481
|
{ label: 'Individual', value: 'individual' },
|
|
511
|
-
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
482
|
+
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
512
483
|
['Top Left', 0],
|
|
513
484
|
['Top Right', 1],
|
|
514
|
-
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), doorShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) =>
|
|
485
|
+
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), doorShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) => previewDoorUpdate('archHeight', v), onCommit: (v) => commitDoorPreview('archHeight', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: archHeight }))] })), showOpeningShapeSection && (_jsxs(PanelSection, { title: "Opening Shape", children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({
|
|
515
486
|
openingShape: v,
|
|
516
487
|
...(v === 'rounded'
|
|
517
488
|
? { openingRadiusMode, openingTopRadii, cornerRadius, openingRevealRadius }
|
|
@@ -524,10 +495,10 @@ export default function DoorPanel() {
|
|
|
524
495
|
], value: openingShape }) }), openingShape === 'rounded' && (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex flex-col gap-2 px-1 pb-1", children: _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ openingRadiusMode: v }), options: [
|
|
525
496
|
{ label: 'All', value: 'all' },
|
|
526
497
|
{ label: 'Individual', value: 'individual' },
|
|
527
|
-
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
498
|
+
], value: openingRadiusMode }) }), openingRadiusMode === 'all' ? (_jsx(SliderControl, { label: "Corner Radius", max: maxRoundedRadius, min: 0, onChange: (v) => previewDoorUpdate('cornerRadius', v), onCommit: (v) => commitDoorPreview('cornerRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: cornerRadius })) : (_jsx(_Fragment, { children: [
|
|
528
499
|
['Top Left', 0],
|
|
529
500
|
['Top Right', 1],
|
|
530
|
-
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), openingShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) =>
|
|
501
|
+
].map(([label, index]) => (_jsx(SliderControl, { label: label, max: maxRoundedRadius, min: 0, onChange: (v) => setOpeningTopRadius(index, v), onCommit: (v) => setOpeningTopRadius(index, v, true), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 2, step: 0.05, unit: "m", value: openingTopRadii[index] ?? 0 }, label))) })), _jsx(SliderControl, { label: "Reveal Radius", max: 0.08, min: 0, onChange: (v) => previewDoorUpdate('openingRevealRadius', v), onCommit: (v) => commitDoorPreview('openingRevealRadius', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, restoreOnCommit: false, precision: 3, step: 0.005, unit: "m", value: openingRevealRadius })] })), openingShape === 'arch' && (_jsx(SliderControl, { label: "Arch Height", max: node.height, min: 0.05, onChange: (v) => previewDoorUpdate('archHeight', v), onCommit: (v) => commitDoorPreview('archHeight', v), onCancel: () => preview?.cancel(), previewWhileTyping: true, precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: archHeight }))] })), !isCutoutOnly && (_jsxs(_Fragment, { children: [showFrameSection && (_jsxs(PanelSection, { title: "Frame", children: [_jsx(SliderControl, { label: "Thickness", max: 0.2, min: 0.01, onChange: (v) => handleUpdate({ frameThickness: v }), precision: 3, step: 0.01, unit: "m", value: node.frameThickness }), _jsx(SliderControl, { label: "Depth", max: 0.3, min: 0.01, onChange: (v) => handleUpdate({ frameDepth: v }), precision: 3, step: 0.01, unit: "m", value: node.frameDepth })] })), showContentPaddingSection && (_jsxs(PanelSection, { title: "Content Padding", children: [_jsx(SliderControl, { label: "Horizontal", max: 0.2, min: 0, onChange: (v) => handleUpdate({ contentPadding: [v, node.contentPadding[1]] }), precision: 3, step: 0.005, unit: "m", value: node.contentPadding[0] }), _jsx(SliderControl, { label: "Vertical", max: 0.2, min: 0, onChange: (v) => handleUpdate({ contentPadding: [node.contentPadding[0], v] }), precision: 3, step: 0.005, unit: "m", value: node.contentPadding[1] })] })), showSwingSection && (_jsx(PanelSection, { title: "Swing", children: _jsxs("div", { className: "flex flex-col gap-2 px-1 pb-1", children: [supportsHingeSide && (_jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Hinges Side" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ hingesSide: v }), options: [
|
|
531
502
|
{ label: 'Left', value: 'left' },
|
|
532
503
|
{ label: 'Right', value: 'right' },
|
|
533
504
|
], value: node.hingesSide })] })), _jsxs("div", { className: "space-y-1", children: [_jsx("span", { className: "font-medium text-[10px] text-muted-foreground/80 uppercase tracking-wider", children: "Direction" }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ swingDirection: v }), options: [
|
package/dist/door/tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/door/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/door/tool.tsx"],"names":[],"mappings":"AAqEA;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAwtBrB,CAAA;AAED,eAAe,QAAQ,CAAA"}
|
package/dist/door/tool.js
CHANGED
|
@@ -5,6 +5,7 @@ import { useViewer } from '@pascal-app/viewer';
|
|
|
5
5
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
|
|
7
7
|
import { LineBasicNodeMaterial } from 'three/webgpu';
|
|
8
|
+
import { shouldFollowOpeningGrid, shouldHandleOpeningHostLeave, } from '../shared/opening-grid-follow';
|
|
8
9
|
import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, } from '../shared/opening-guides-runtime';
|
|
9
10
|
import { getRoofWallOpeningCursorPose, resolveRoofWallOpeningTarget, worldToSelectedBuildingLocal, } from '../shared/roof-wall-opening-placement';
|
|
10
11
|
import { collectWallOpeningAlignmentCandidates, resolveWallSlideAlignment, } from '../shared/wall-opening-alignment';
|
|
@@ -385,7 +386,17 @@ const DoorTool = () => {
|
|
|
385
386
|
commitDoorAtWall(event.node, clampedX, clampedY, side, itemRotation);
|
|
386
387
|
event.stopPropagation();
|
|
387
388
|
};
|
|
388
|
-
|
|
389
|
+
// XR runtimes deliver selectend as a grid click, but do not replay the
|
|
390
|
+
// R3F wall pointer-up event. Commit the latest valid wall hover so a
|
|
391
|
+
// controller/hand release places the opening on the wall it visibly hit.
|
|
392
|
+
const onXRGridClick = (event) => {
|
|
393
|
+
if (event.nativeEvent?.pointerType !== 'xr' || !lastWallEvent)
|
|
394
|
+
return;
|
|
395
|
+
onWallClick(lastWallEvent);
|
|
396
|
+
};
|
|
397
|
+
const onWallLeave = (event) => {
|
|
398
|
+
if (!shouldHandleOpeningHostLeave(event.nativeEvent))
|
|
399
|
+
return;
|
|
389
400
|
if (hostKind !== 'wall')
|
|
390
401
|
return;
|
|
391
402
|
lastWallEvent = null;
|
|
@@ -404,7 +415,12 @@ const DoorTool = () => {
|
|
|
404
415
|
// timeStamp) — it owns the frame and has snapped the draft, so skip the
|
|
405
416
|
// floor follow this tick.
|
|
406
417
|
const ts = event.nativeEvent?.timeStamp ?? -1;
|
|
407
|
-
if (
|
|
418
|
+
if (!shouldFollowOpeningGrid({
|
|
419
|
+
eventTime: ts,
|
|
420
|
+
hasActiveHost: hostKind !== null,
|
|
421
|
+
lastHostEventTime: lastMeshEventTime,
|
|
422
|
+
pointerType: event.nativeEvent?.pointerType,
|
|
423
|
+
}))
|
|
408
424
|
return;
|
|
409
425
|
// Fresh floor-only frame: the cursor is off any wall/roof. Drop any draft
|
|
410
426
|
// and free-follow the cursor with the invalid (unplaceable) ghost.
|
|
@@ -575,6 +591,7 @@ const DoorTool = () => {
|
|
|
575
591
|
emitter.on('wall:enter', onWallHover);
|
|
576
592
|
emitter.on('wall:move', onWallHover);
|
|
577
593
|
emitter.on('wall:click', onWallClick);
|
|
594
|
+
emitter.on('grid:click', onXRGridClick);
|
|
578
595
|
emitter.on('wall:leave', onWallLeave);
|
|
579
596
|
emitter.on('roof:enter', onRoofHover);
|
|
580
597
|
emitter.on('roof:move', onRoofHover);
|
|
@@ -599,6 +616,7 @@ const DoorTool = () => {
|
|
|
599
616
|
emitter.off('wall:enter', onWallHover);
|
|
600
617
|
emitter.off('wall:move', onWallHover);
|
|
601
618
|
emitter.off('wall:click', onWallClick);
|
|
619
|
+
emitter.off('grid:click', onXRGridClick);
|
|
602
620
|
emitter.off('wall:leave', onWallLeave);
|
|
603
621
|
emitter.off('roof:enter', onRoofHover);
|
|
604
622
|
emitter.off('roof:move', onRoofHover);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/dormer/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAqPrC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/dormer/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAqPrC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,CA+E9D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/downspout/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAiIxC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,OAAO,aAAa,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/downspout/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAiIxC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,OAAO,aAAa,CA6DpE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAuBtF,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAYpG,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAA;AA2IxB,qEAAqE;AACrE,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAUjF;AAgDD;;;;;6BAK6B;AAC7B,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,OAAO,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;CACxB,CAAA;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,UAAQ,EACnB,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,EAC3C,WAAW,GAAE,QAAQ,GAAG,QAAmB,GAC1C,YAAY,GAAG,IAAI,CAsLrB;AAED,QAAA,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-segment/tool.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAuBtF,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAA;AAYpG,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAA;AA2IxB,qEAAqE;AACrE,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAUjF;AAgDD;;;;;6BAK6B;AAC7B,KAAK,YAAY,GAAG;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,OAAO,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IACxD,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;CACxB,CAAA;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,SAAS,GAAG,IAAI,EAC3B,SAAS,EAAE,UAAU,GAAG,IAAI,EAC5B,OAAO,EAAE,SAAS,GAAG,IAAI,EACzB,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,EACjC,WAAW,UAAQ,EACnB,YAAY,GAAE,OAAO,CAAC,eAAe,CAAM,EAC3C,WAAW,GAAE,QAAQ,GAAG,QAAmB,GAC1C,YAAY,GAAG,IAAI,CAsLrB;AAED,QAAA,MAAM,eAAe,0CAoRpB,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -390,6 +390,7 @@ export function planDuctDraw(start, end, startPort, startBody, endPort, endBody,
|
|
|
390
390
|
}
|
|
391
391
|
const DuctSegmentTool = () => {
|
|
392
392
|
const { activeLevelId, sceneApi, unit } = useRegistryToolContext();
|
|
393
|
+
const toolDefaults = useEditor((s) => s.toolDefaults['duct-segment']);
|
|
393
394
|
const cursorRef = useRef(null);
|
|
394
395
|
const continuationSeedRef = useRef(currentDuctContinuationSeed());
|
|
395
396
|
const continuationSeed = continuationSeedRef.current;
|
|
@@ -523,6 +524,16 @@ const DuctSegmentTool = () => {
|
|
|
523
524
|
}
|
|
524
525
|
},
|
|
525
526
|
});
|
|
527
|
+
useEffect(() => {
|
|
528
|
+
if (!toolDefaults)
|
|
529
|
+
return;
|
|
530
|
+
setProfile((current) => ({
|
|
531
|
+
shape: toolDefaults.shape ?? current.shape,
|
|
532
|
+
diameter: toolDefaults.diameter ?? current.diameter,
|
|
533
|
+
width: toolDefaults.width ?? current.width,
|
|
534
|
+
height: toolDefaults.height ?? current.height,
|
|
535
|
+
}));
|
|
536
|
+
}, [toolDefaults]);
|
|
526
537
|
const previewPlan = useMemo(() => {
|
|
527
538
|
if (!(activeLevelId && run.start && run.cursor))
|
|
528
539
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-terminal/tool.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/duct-terminal/tool.tsx"],"names":[],"mappings":"AAmJA;;;;;;;;;GASG;AACH,QAAA,MAAM,gBAAgB,0CAyYrB,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { DuctTerminalNode, emitter, pointInPolygon, resolveCeilingHeight, resolveLevelId, resolveSupportSlabPatch, sceneRegistry, useScene, } from '@pascal-app/core';
|
|
4
|
-
import { CursorSphere, getFloorStackPreviewPosition, isGridSnapActive, isMagneticSnapActive, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
4
|
+
import { CursorSphere, getFloorStackPreviewPosition, getSpatialPointerId, isGridSnapActive, isMagneticSnapActive, triggerSFX, useEditor, } from '@pascal-app/editor';
|
|
5
5
|
import { useViewer } from '@pascal-app/viewer';
|
|
6
6
|
import { Html } from '@react-three/drei';
|
|
7
7
|
import { useThree } from '@react-three/fiber';
|
|
@@ -111,6 +111,7 @@ function resolvePortSnap(position, fallbackYaw) {
|
|
|
111
111
|
const DuctTerminalTool = () => {
|
|
112
112
|
const { camera, gl } = useThree();
|
|
113
113
|
const activeLevelId = useViewer((s) => s.selection.levelId);
|
|
114
|
+
const toolDefaults = useEditor((s) => s.toolDefaults['duct-terminal']);
|
|
114
115
|
const [mount, setMount] = useState('floor');
|
|
115
116
|
const [placement, setPlacement] = useState(null);
|
|
116
117
|
const mountRef = useRef('floor');
|
|
@@ -121,11 +122,12 @@ const DuctTerminalTool = () => {
|
|
|
121
122
|
// override the manual M selection (port direction picks floor / ceiling /
|
|
122
123
|
// wall), so the preview must show the inferred mount, not the toolbar one.
|
|
123
124
|
const effectiveMount = placement?.mount ?? mount;
|
|
124
|
-
const
|
|
125
|
+
const configuredNode = useMemo(() => DuctTerminalNode.parse({
|
|
125
126
|
...ductTerminalDefinition.defaults(),
|
|
127
|
+
...toolDefaults,
|
|
126
128
|
name: 'Register',
|
|
127
|
-
|
|
128
|
-
}), [effectiveMount]);
|
|
129
|
+
}), [toolDefaults]);
|
|
130
|
+
const previewNode = useMemo(() => DuctTerminalNode.parse({ ...configuredNode, mount: effectiveMount }), [configuredNode, effectiveMount]);
|
|
129
131
|
const ghost = useMemo(() => {
|
|
130
132
|
const group = buildDuctTerminalGeometry(previewNode);
|
|
131
133
|
group.traverse((child) => {
|
|
@@ -137,6 +139,11 @@ const DuctTerminalTool = () => {
|
|
|
137
139
|
});
|
|
138
140
|
return group;
|
|
139
141
|
}, [previewNode]);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
mountRef.current = configuredNode.mount;
|
|
144
|
+
setMount(configuredNode.mount);
|
|
145
|
+
setPlacement(null);
|
|
146
|
+
}, [configuredNode.mount]);
|
|
140
147
|
useEffect(() => {
|
|
141
148
|
if (!activeLevelId)
|
|
142
149
|
return;
|
|
@@ -237,6 +244,7 @@ const DuctTerminalTool = () => {
|
|
|
237
244
|
const commit = (p) => {
|
|
238
245
|
const terminal = DuctTerminalNode.parse({
|
|
239
246
|
...ductTerminalDefinition.defaults(),
|
|
247
|
+
...toolDefaults,
|
|
240
248
|
name: 'Register',
|
|
241
249
|
mount: p.mount,
|
|
242
250
|
position: p.position,
|
|
@@ -251,17 +259,63 @@ const DuctTerminalTool = () => {
|
|
|
251
259
|
useViewer.getState().setSelection({ selectedIds: [committedTerminal.id] });
|
|
252
260
|
triggerSFX('sfx:item-place');
|
|
253
261
|
};
|
|
254
|
-
// ---- Floor / ceiling: own raycast against a horizontal plane ----
|
|
255
262
|
let lastPointer = null;
|
|
256
263
|
let lastWall = null;
|
|
264
|
+
let lastGrid = null;
|
|
265
|
+
let lastXRNode = null;
|
|
266
|
+
const resolveGrid = (event) => {
|
|
267
|
+
const step = isGridSnapActive() ? useEditor.getState().gridSnapStep : 0;
|
|
268
|
+
const position = alignDrawPoint([snap(event.localPosition[0], step), 0, snap(event.localPosition[2], step)], { applySnap: isMagneticSnapActive(), bypass: !isMagneticSnapActive() });
|
|
269
|
+
const snapEnabled = isGridSnapActive() || isMagneticSnapActive();
|
|
270
|
+
const mated = snapEnabled ? resolvePortSnap(position, yawRef.current) : null;
|
|
271
|
+
return mated
|
|
272
|
+
? { position: mated.position, yaw: mated.yaw, mount: mated.mount, snapped: true }
|
|
273
|
+
: { position, yaw: yawRef.current, mount: 'floor' };
|
|
274
|
+
};
|
|
275
|
+
const onGridMove = (event) => {
|
|
276
|
+
lastGrid = event;
|
|
277
|
+
if (mountRef.current === 'floor')
|
|
278
|
+
setPlacement(resolveGrid(event));
|
|
279
|
+
};
|
|
280
|
+
const onGridClick = (event) => {
|
|
281
|
+
if (mountRef.current === 'floor')
|
|
282
|
+
commit(resolveGrid(event));
|
|
283
|
+
};
|
|
284
|
+
const resolveXRCeiling = (event) => {
|
|
285
|
+
if (mountRef.current !== 'ceiling' || event.node.type !== 'ceiling')
|
|
286
|
+
return null;
|
|
287
|
+
if (getSpatialPointerId(event.nativeEvent) == null)
|
|
288
|
+
return null;
|
|
289
|
+
const world = new Vector3(...event.position);
|
|
290
|
+
const level = activeLevelMesh();
|
|
291
|
+
const local = level ? level.worldToLocal(world) : world;
|
|
292
|
+
return {
|
|
293
|
+
position: [local.x, resolveCeilingHeight(event.node, useScene.getState().nodes), local.z],
|
|
294
|
+
yaw: yawRef.current,
|
|
295
|
+
mount: 'ceiling',
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
const onXRNodeMove = (event) => {
|
|
299
|
+
lastXRNode = event;
|
|
300
|
+
const p = resolveXRCeiling(event);
|
|
301
|
+
if (p)
|
|
302
|
+
setPlacement(p);
|
|
303
|
+
};
|
|
304
|
+
const onXRNodeClick = (event) => {
|
|
305
|
+
const p = resolveXRCeiling(event);
|
|
306
|
+
if (p)
|
|
307
|
+
commit(p);
|
|
308
|
+
};
|
|
309
|
+
// ---- Ceiling: desktop owns a canvas ray; XR uses the spatial node ray. ----
|
|
257
310
|
const onPointerMove = (e) => {
|
|
258
311
|
lastPointer = e;
|
|
259
|
-
|
|
312
|
+
lastXRNode = null;
|
|
313
|
+
if (mountRef.current !== 'ceiling')
|
|
260
314
|
return;
|
|
261
315
|
setPlacement(resolvePlanar(e));
|
|
262
316
|
};
|
|
263
317
|
const onCanvasClick = (e) => {
|
|
264
|
-
if (mountRef.current
|
|
318
|
+
if (mountRef.current !== 'ceiling')
|
|
265
319
|
return;
|
|
266
320
|
if (useViewer.getState().cameraDragging)
|
|
267
321
|
return;
|
|
@@ -350,11 +404,22 @@ const DuctTerminalTool = () => {
|
|
|
350
404
|
if (lastWall)
|
|
351
405
|
onWallMove(lastWall);
|
|
352
406
|
}
|
|
407
|
+
else if (mountRef.current === 'floor') {
|
|
408
|
+
if (lastGrid)
|
|
409
|
+
onGridMove(lastGrid);
|
|
410
|
+
}
|
|
411
|
+
else if (lastXRNode && getSpatialPointerId(lastXRNode.nativeEvent) != null) {
|
|
412
|
+
onXRNodeMove(lastXRNode);
|
|
413
|
+
}
|
|
353
414
|
else if (lastPointer)
|
|
354
415
|
onPointerMove(lastPointer);
|
|
355
416
|
});
|
|
356
417
|
canvas.addEventListener('pointermove', onPointerMove);
|
|
357
418
|
canvas.addEventListener('click', onCanvasClick);
|
|
419
|
+
emitter.on('grid:move', onGridMove);
|
|
420
|
+
emitter.on('grid:click', onGridClick);
|
|
421
|
+
emitter.on('node:move', onXRNodeMove);
|
|
422
|
+
emitter.on('node:click', onXRNodeClick);
|
|
358
423
|
emitter.on('wall:move', onWallMove);
|
|
359
424
|
emitter.on('wall:click', onWallClick);
|
|
360
425
|
window.addEventListener('keydown', onKeyDown, true);
|
|
@@ -362,12 +427,16 @@ const DuctTerminalTool = () => {
|
|
|
362
427
|
unsubscribeSnapping();
|
|
363
428
|
canvas.removeEventListener('pointermove', onPointerMove);
|
|
364
429
|
canvas.removeEventListener('click', onCanvasClick);
|
|
430
|
+
emitter.off('grid:move', onGridMove);
|
|
431
|
+
emitter.off('grid:click', onGridClick);
|
|
432
|
+
emitter.off('node:move', onXRNodeMove);
|
|
433
|
+
emitter.off('node:click', onXRNodeClick);
|
|
365
434
|
emitter.off('wall:move', onWallMove);
|
|
366
435
|
emitter.off('wall:click', onWallClick);
|
|
367
436
|
window.removeEventListener('keydown', onKeyDown, true);
|
|
368
437
|
clearDrawAlignment();
|
|
369
438
|
};
|
|
370
|
-
}, [activeLevelId, camera, gl]);
|
|
439
|
+
}, [activeLevelId, camera, gl, toolDefaults]);
|
|
371
440
|
if (!activeLevelId || !placement)
|
|
372
441
|
return null;
|
|
373
442
|
const mountLabel = effectiveMount.charAt(0).toUpperCase() + effectiveMount.slice(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/elevator/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAsJvC;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,OAAO,YAAY,
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/elevator/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAA;AAKzB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAsJvC;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,OAAO,YAAY,CAgHlE,CAAA"}
|
|
@@ -173,6 +173,7 @@ export const elevatorDefinition = {
|
|
|
173
173
|
return rest;
|
|
174
174
|
},
|
|
175
175
|
capabilities: {
|
|
176
|
+
surfacePlacement: 'floor-only',
|
|
176
177
|
selectable: { hitVolume: 'bbox' },
|
|
177
178
|
// Generic XZ translate so the floating action menu's Move button
|
|
178
179
|
// (and the side move-arrows emitted from `def.floorplan`) drive the
|
|
@@ -220,6 +221,7 @@ export const elevatorDefinition = {
|
|
|
220
221
|
handles: elevatorHandles,
|
|
221
222
|
// No dirty consumer rebuilds this kind — see NodeDefinition.dirtyTracking.
|
|
222
223
|
dirtyTracking: false,
|
|
224
|
+
rendersChildren: false,
|
|
223
225
|
renderer: {
|
|
224
226
|
kind: 'parametric',
|
|
225
227
|
module: () => import('./renderer'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/elevator/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAE1E,eAAO,MAAM,mBAAmB,EAAE,oBAAoB,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"parametrics.d.ts","sourceRoot":"","sources":["../../src/elevator/parametrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAE1E,eAAO,MAAM,mBAAmB,EAAE,oBAAoB,CAAC,YAAY,CAoGlE,CAAA"}
|
|
@@ -1,4 +1,101 @@
|
|
|
1
1
|
export const elevatorParametrics = {
|
|
2
|
-
groups: [
|
|
2
|
+
groups: [
|
|
3
|
+
{
|
|
4
|
+
label: 'Position',
|
|
5
|
+
fields: [
|
|
6
|
+
{ key: 'position', kind: 'vec3' },
|
|
7
|
+
{
|
|
8
|
+
key: 'rotation',
|
|
9
|
+
kind: 'number',
|
|
10
|
+
label: 'Rotation (rad)',
|
|
11
|
+
min: -Math.PI,
|
|
12
|
+
max: Math.PI,
|
|
13
|
+
step: Math.PI / 36,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: 'Cab',
|
|
19
|
+
fields: [
|
|
20
|
+
{ key: 'width', kind: 'number', unit: 'm', min: 0.8, max: 1000, step: 0.05 },
|
|
21
|
+
{ key: 'depth', kind: 'number', unit: 'm', min: 0.8, max: 1000, step: 0.05 },
|
|
22
|
+
{ key: 'cabHeight', kind: 'number', unit: 'm', min: 1.8, max: 1000, step: 0.05 },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Shaft',
|
|
27
|
+
fields: [
|
|
28
|
+
{
|
|
29
|
+
key: 'shaftWallThickness',
|
|
30
|
+
kind: 'number',
|
|
31
|
+
label: 'Wall thickness',
|
|
32
|
+
unit: 'm',
|
|
33
|
+
min: 0.04,
|
|
34
|
+
max: 0.4,
|
|
35
|
+
step: 0.01,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'shaftStyle',
|
|
39
|
+
kind: 'enum',
|
|
40
|
+
options: ['solid', 'glass'],
|
|
41
|
+
display: 'segmented',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: 'Doors',
|
|
47
|
+
fields: [
|
|
48
|
+
{ key: 'doorWidth', kind: 'number', unit: 'm', min: 0.45, max: 1000, step: 0.05 },
|
|
49
|
+
{ key: 'doorHeight', kind: 'number', unit: 'm', min: 1.2, max: 1000, step: 0.05 },
|
|
50
|
+
{
|
|
51
|
+
key: 'doorStyle',
|
|
52
|
+
kind: 'enum',
|
|
53
|
+
options: ['center-opening', 'single-left', 'single-right'],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: 'doorPanelStyle',
|
|
57
|
+
kind: 'enum',
|
|
58
|
+
label: 'Panel style',
|
|
59
|
+
options: ['glass-frame', 'solid-panel', 'segmented-panel'],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: 'Levels',
|
|
65
|
+
fields: [
|
|
66
|
+
{ key: 'fromLevelId', kind: 'ref', label: 'From level', refKind: 'level' },
|
|
67
|
+
{ key: 'toLevelId', kind: 'ref', label: 'To level', refKind: 'level' },
|
|
68
|
+
{ key: 'defaultLevelId', kind: 'ref', label: 'Default level', refKind: 'level' },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
label: 'Motion',
|
|
73
|
+
fields: [
|
|
74
|
+
{ key: 'speed', kind: 'number', unit: 'm/s', min: 0.5, max: 8, step: 0.1 },
|
|
75
|
+
{
|
|
76
|
+
key: 'doorDurationMs',
|
|
77
|
+
kind: 'number',
|
|
78
|
+
label: 'Door time',
|
|
79
|
+
unit: 'ms',
|
|
80
|
+
min: 300,
|
|
81
|
+
max: 2200,
|
|
82
|
+
step: 50,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
key: 'dwellMs',
|
|
86
|
+
kind: 'number',
|
|
87
|
+
label: 'Dwell',
|
|
88
|
+
unit: 'ms',
|
|
89
|
+
min: 300,
|
|
90
|
+
max: 5000,
|
|
91
|
+
step: 100,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
derive: (next) => ({
|
|
97
|
+
doorHeight: Math.min(next.doorHeight, Math.max(1.2, next.cabHeight - 0.1)),
|
|
98
|
+
doorWidth: Math.min(next.doorWidth, Math.max(0.45, next.width - 0.1)),
|
|
99
|
+
}),
|
|
3
100
|
customPanel: () => import('./panel'),
|
|
4
101
|
};
|