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:
@@ -7,6 +7,7 @@ import {
|
||||
type RenderShading,
|
||||
} from '@pascal-app/viewer'
|
||||
import { BoxGeometry, FrontSide, Group, type Material, Mesh } from 'three'
|
||||
import { sanitizeShelfDimensions } from './dimensions'
|
||||
import type { ShelfNode } from './schema'
|
||||
|
||||
/**
|
||||
@@ -69,10 +70,11 @@ function getShelfMaterial(node: ShelfNode, shading: RenderShading): Material {
|
||||
}
|
||||
|
||||
export function buildShelfGeometry(
|
||||
node: ShelfNode,
|
||||
rawNode: ShelfNode,
|
||||
_ctx?: unknown,
|
||||
shading: RenderShading = 'rendered',
|
||||
): Group {
|
||||
const node = sanitizeShelfDimensions(rawNode)
|
||||
const group = new Group()
|
||||
group.name = 'shelf-geometry'
|
||||
|
||||
@@ -343,8 +345,9 @@ function addCornerPosts(
|
||||
* can host in the lowest cell.
|
||||
*/
|
||||
export function shelfRowSurfaceYs(node: ShelfNode): number[] {
|
||||
const ys = boardCenterYs(node).map((y) => y + node.thickness / 2)
|
||||
const bottomApplies = node.style === 'cubby' || node.style === 'bookshelf'
|
||||
if (node.withBottom && bottomApplies) ys.unshift(node.thickness)
|
||||
const safe = sanitizeShelfDimensions(node)
|
||||
const ys = boardCenterYs(safe).map((y) => y + safe.thickness / 2)
|
||||
const bottomApplies = safe.style === 'cubby' || safe.style === 'bookshelf'
|
||||
if (safe.withBottom && bottomApplies) ys.unshift(safe.thickness)
|
||||
return ys
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user