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:
@@ -0,0 +1,18 @@
|
||||
import type { ShelfNode } from './schema'
|
||||
|
||||
function clampShelfDim(value: unknown, lo: number, hi: number, fallback: number): number {
|
||||
const v = typeof value === 'number' && Number.isFinite(value) ? value : fallback
|
||||
return Math.min(Math.max(v, lo), hi)
|
||||
}
|
||||
|
||||
export function sanitizeShelfDimensions(node: ShelfNode): ShelfNode {
|
||||
return {
|
||||
...node,
|
||||
width: clampShelfDim(node.width, 0.3, 3.0, 1.2),
|
||||
depth: clampShelfDim(node.depth, 0.1, 1.0, 0.3),
|
||||
thickness: clampShelfDim(node.thickness, 0.01, 0.1, 0.04),
|
||||
height: clampShelfDim(node.height, 0.05, 2.5, 0.9),
|
||||
rows: Math.round(clampShelfDim(node.rows, 1, 8, 1)),
|
||||
columns: Math.round(clampShelfDim(node.columns, 1, 6, 1)),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user