From ced76b04756c37efdc48cbca2d1f8b21d8bfd1b7 Mon Sep 17 00:00:00 2001 From: wass08 Date: Wed, 25 Feb 2026 15:21:19 +0900 Subject: [PATCH] fix placement --- .../components/editor/selection-manager.tsx | 6 +-- .../components/ui/panels/door-panel.tsx | 39 +++++++++++++------ .../renderers/door/door-renderer.tsx | 3 +- .../renderers/wall/wall-renderer.tsx | 6 +-- .../renderers/window/window-renderer.tsx | 3 +- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/apps/editor/components/editor/selection-manager.tsx b/apps/editor/components/editor/selection-manager.tsx index ffe551c2..239757d8 100644 --- a/apps/editor/components/editor/selection-manager.tsx +++ b/apps/editor/components/editor/selection-manager.tsx @@ -20,7 +20,7 @@ const isNodeInCurrentLevel = (node: AnyNode): boolean => { return nodeLevelId === currentLevelId; }; -type SelectableNodeType = "wall" | "item" | "building" | "zone" | 'slab' | 'ceiling' | 'roof' | 'window'; +type SelectableNodeType = "wall" | "item" | "building" | "zone" | 'slab' | 'ceiling' | 'roof' | 'window' | 'door'; interface SelectionStrategy { types: SelectableNodeType[]; @@ -44,7 +44,7 @@ const SELECTION_STRATEGIES: Record = { }, structure: { - types: ["wall", "item", "zone", "slab", "ceiling", "roof", "window"], + types: ["wall", "item", "zone", "slab", "ceiling", "roof", "window", "door"], handleSelect: (node, isShift) => { const { selection, setSelection } = useViewer.getState(); if (node.type === 'zone') { @@ -80,7 +80,7 @@ const SELECTION_STRATEGIES: Record = { (node as ItemNode).asset.category === "window" ); } - if (node.type === "window") return true; + if (node.type === "window" || node.type === "door") return true; return false; } diff --git a/apps/editor/components/ui/panels/door-panel.tsx b/apps/editor/components/ui/panels/door-panel.tsx index 254597f4..8330d741 100644 --- a/apps/editor/components/ui/panels/door-panel.tsx +++ b/apps/editor/components/ui/panels/door-panel.tsx @@ -91,6 +91,23 @@ export function DoorPanel() { setSelection({ selectedIds: [] }) }, [node, setMovingNode, setSelection]) + const setSegmentHeightRatio = (segIdx: number, newVal: number) => { + const numSegs = node!.segments.length + const totalH = node!.segments.reduce((sum, s) => sum + s.heightRatio, 0) + const normH = node!.segments.map(s => s.heightRatio / totalH) + const clamped = Math.max(0.05, Math.min(0.95, newVal)) + const neighborIdx = segIdx < numSegs - 1 ? segIdx + 1 : segIdx - 1 + const delta = clamped - normH[segIdx]! + const neighborVal = Math.max(0.05, normH[neighborIdx]! - delta) + const newRatios = normH.map((v, i) => { + if (i === segIdx) return clamped + if (i === neighborIdx) return neighborVal + return v + }) + const updated = node!.segments.map((s, idx) => ({ ...s, heightRatio: newRatios[idx]! })) + handleUpdate({ segments: updated }) + } + const setSegmentColumnRatio = (segIdx: number, colIdx: number, newVal: number) => { const seg = node!.segments[segIdx]! const normRatios = (() => { @@ -115,6 +132,9 @@ export function DoorPanel() { if (!node || node.type !== 'door' || selectedIds.length !== 1) return null + const hSum = node.segments.reduce((s, seg) => s + seg.heightRatio, 0) + const normHeights = node.segments.map(seg => seg.heightRatio / hSum) + return (
{/* Header */} @@ -455,19 +475,16 @@ export function DoorPanel() {
{ - const updated = node.segments.map((s, idx) => - idx === i ? { ...s, heightRatio: Math.max(0.05, v) } : s, - ) - handleUpdate({ segments: updated }) - }} - min={0.05} - precision={2} - step={0.05} + label="Height" + value={Math.round(normHeights[i]! * 100 * 10) / 10} + onChange={(v) => setSegmentHeightRatio(i, v / 100)} + min={5} + max={95} + precision={1} + step={1} className="flex-1" /> + %
{/* Columns */}
diff --git a/packages/viewer/src/components/renderers/door/door-renderer.tsx b/packages/viewer/src/components/renderers/door/door-renderer.tsx index d723cfd1..4acd54f4 100644 --- a/packages/viewer/src/components/renderers/door/door-renderer.tsx +++ b/packages/viewer/src/components/renderers/door/door-renderer.tsx @@ -8,6 +8,7 @@ export const DoorRenderer = ({ node }: { node: DoorNode }) => { useRegistry(node.id, 'door', ref) const handlers = useNodeEvents(node, 'door') + const isTransient = !!(node.metadata as Record | null)?.isTransient return ( { visible={node.visible} position={node.position} rotation={node.rotation} - {...handlers} + {...(isTransient ? {} : handlers)} > {/* DoorSystem replaces this geometry each time the node is dirty */} diff --git a/packages/viewer/src/components/renderers/wall/wall-renderer.tsx b/packages/viewer/src/components/renderers/wall/wall-renderer.tsx index 94405e77..4663962b 100644 --- a/packages/viewer/src/components/renderers/wall/wall-renderer.tsx +++ b/packages/viewer/src/components/renderers/wall/wall-renderer.tsx @@ -12,11 +12,11 @@ export const WallRenderer = ({ node }: { node: WallNode }) => { const handlers = useNodeEvents(node, 'wall') return ( - + {/* WallSystem will replace this geometry in the next frame */} - {/* Collision mesh: full-wall geometry (no cutouts) for WallSystem, no event handlers */} - + {/* Collision mesh: full-wall geometry (no cutouts) for pointer events */} + diff --git a/packages/viewer/src/components/renderers/window/window-renderer.tsx b/packages/viewer/src/components/renderers/window/window-renderer.tsx index 75c20188..f2d8677c 100644 --- a/packages/viewer/src/components/renderers/window/window-renderer.tsx +++ b/packages/viewer/src/components/renderers/window/window-renderer.tsx @@ -8,6 +8,7 @@ export const WindowRenderer = ({ node }: { node: WindowNode }) => { useRegistry(node.id, 'window', ref) const handlers = useNodeEvents(node, 'window') + const isTransient = !!(node.metadata as Record | null)?.isTransient return ( { visible={node.visible} position={node.position} rotation={node.rotation} - {...handlers} + {...(isTransient ? {} : handlers)} > {/* WindowSystem replaces this geometry each time the node is dirty */}