feat(editor): live floor-stacking, unified handle system, slab-hole editing + interaction polish (#375)
- Live slab-stacking Y previews for all floor-placed kinds (item/shelf/spawn/column/stair) during placement + both move pathways, via a shared core resolver; canonical positions unchanged. - Unified 3D handle system (one drag pipeline + one visual primitive) with forgiving invisible hit-areas on every handle, kept on EDITOR_LAYER so they don't poison the MRT scene pass. - Hover + click-to-edit slab holes in 3D (manual hole -> hole editor; stair/elevator hole -> select owner); generic cross-arrow polygon-move grip; normalized handle interaction colors. - NaN-safe node mutations + non-finite shadow-light bounds guard. - Built on #373 (level-scoped alignment / registry slab tool); #373 owns X/Z alignment, this owns Y floor-stacking.
This commit is contained in:
@@ -24,6 +24,7 @@ export const SlabHoleEditor: React.FC<{ slabId: SlabNode['id']; holeIndex: numbe
|
||||
const slab = slabNode?.type === 'slab' ? (slabNode as SlabNode) : null
|
||||
const holes = slab?.holes || []
|
||||
const hole = holes[holeIndex]
|
||||
const metadata = slab?.holeMetadata?.[holeIndex]
|
||||
|
||||
const handlePolygonChange = useCallback(
|
||||
(newPolygon: Array<[number, number]>) => {
|
||||
@@ -60,7 +61,7 @@ export const SlabHoleEditor: React.FC<{ slabId: SlabNode['id']; holeIndex: numbe
|
||||
}
|
||||
}, [slabId])
|
||||
|
||||
if (!(slab && hole) || hole.length < 3) return null
|
||||
if (!(slab && hole) || hole.length < 3 || metadata?.source !== 'manual') return null
|
||||
|
||||
return (
|
||||
<PolygonEditor
|
||||
|
||||
Reference in New Issue
Block a user