fix: improve ceiling handle feedback and WebGPU placeholders

This commit is contained in:
Aymeric Rabot
2026-06-09 14:49:42 -04:00
parent 8ce26154d9
commit 265acdb2be
11 changed files with 661 additions and 55 deletions
+44 -2
View File
@@ -1,9 +1,9 @@
'use client'
import { type CeilingNode, resolveLevelId, useLiveNodeOverrides, useScene } from '@pascal-app/core'
import { PolygonEditor } from '@pascal-app/editor'
import { PolygonEditor, triggerSFX } from '@pascal-app/editor'
import { useViewer } from '@pascal-app/viewer'
import { useCallback, useEffect } from 'react'
import { useCallback, useEffect, useRef } from 'react'
/**
* Phase 5 Stage D — ceiling boundary editor (registry-driven).
@@ -23,6 +23,8 @@ export const CeilingBoundaryEditor: React.FC<{ ceilingId: CeilingNode['id'] }> =
const updateNode = useScene((s) => s.updateNode)
const markDirty = useScene((s) => s.markDirty)
const setSelection = useViewer((s) => s.setSelection)
const setHoveredId = useViewer((s) => s.setHoveredId)
const ownsCeilingHoverRef = useRef(false)
const ceiling = ceilingNode?.type === 'ceiling' ? (ceilingNode as CeilingNode) : null
@@ -48,10 +50,43 @@ export const CeilingBoundaryEditor: React.FC<{ ceilingId: CeilingNode['id'] }> =
[ceilingId, markDirty],
)
const setCeilingHandleHover = useCallback(
(active: boolean) => {
if (active) {
ownsCeilingHoverRef.current = true
setHoveredId(ceilingId)
return
}
if (ownsCeilingHoverRef.current && useViewer.getState().hoveredId === ceilingId) {
setHoveredId(null)
}
ownsCeilingHoverRef.current = false
},
[ceilingId, setHoveredId],
)
const handleHandleHoverChange = useCallback(
(index: number | null) => {
setCeilingHandleHover(index !== null)
},
[setCeilingHandleHover],
)
const handleDragStateChange = useCallback(
(isDragging: boolean) => {
setCeilingHandleHover(isDragging)
},
[setCeilingHandleHover],
)
useEffect(() => {
return () => {
useLiveNodeOverrides.getState().clear(ceilingId)
useScene.getState().markDirty(ceilingId)
if (ownsCeilingHoverRef.current && useViewer.getState().hoveredId === ceilingId) {
useViewer.getState().setHoveredId(null)
}
ownsCeilingHoverRef.current = false
}
}, [ceilingId])
@@ -61,10 +96,17 @@ export const CeilingBoundaryEditor: React.FC<{ ceilingId: CeilingNode['id'] }> =
<PolygonEditor
allowEdgeMove
color="#d4d4d4"
highlightConnectedHandles
levelId={resolveLevelId(ceiling, useScene.getState().nodes)}
minVertices={3}
onDragStateChange={handleDragStateChange}
onDragCommit={() => triggerSFX('sfx:item-place')}
onDragStart={() => triggerSFX('sfx:item-pick')}
onEdgeHoverChange={handleHandleHoverChange}
onMidpointHoverChange={handleHandleHoverChange}
onPolygonChange={handlePolygonChange}
onPolygonPreview={handlePolygonPreview}
onVertexHoverChange={handleHandleHoverChange}
polygon={ceiling.polygon}
surfaceHeight={ceiling.height ?? 2.5}
/>