feat(editor): preset placement polish — params, move tool, shadows, isolation (#357)
* feat(editor): preset placement polish — params, move tool, shadows - wall/slab/ceiling/roof create paths consume `toolDefaults` so template presets build with their saved params; cleared on tool unmount - wall draw preview reflects the preset's height/thickness (+ HUD labels) - box-select picks up registry-selectable kinds (shelf) via bbox - registry + column move tools: snap to the active grid step, R/T rotation, and ignore the stray trailing click that armed the move (no double-place) - shelf geometry casts + receives shadows like fence/slab Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(viewer): expose isIsolationActive() for isolation-aware consumers Tracks whether an isolation filter is currently applied and exposes it so hosts can avoid acting on the partial view — e.g. skipping project-thumbnail autosave while a single subtree is isolated (preset capture). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8abfc94b99
commit
f7ff60561e
@@ -1,7 +1,13 @@
|
||||
'use client'
|
||||
|
||||
import { emitter, type GridEvent, type LevelNode, useScene } from '@pascal-app/core'
|
||||
import { CursorSphere, EDITOR_LAYER, markToolCancelConsumed, triggerSFX } from '@pascal-app/editor'
|
||||
import {
|
||||
CursorSphere,
|
||||
EDITOR_LAYER,
|
||||
markToolCancelConsumed,
|
||||
triggerSFX,
|
||||
useEditor,
|
||||
} from '@pascal-app/editor'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { BufferGeometry, DoubleSide, type Group, type Line, Shape, Vector3 } from 'three'
|
||||
@@ -46,7 +52,10 @@ function commitCeilingDrawing(levelId: LevelNode['id'], points: Array<[number, n
|
||||
const { createNode, nodes } = useScene.getState()
|
||||
const ceilingCount = Object.values(nodes).filter((n) => n.type === 'ceiling').length
|
||||
const name = `Ceiling ${ceilingCount + 1}`
|
||||
const ceiling = CeilingNode.parse({ name, polygon: points })
|
||||
// A placed ceiling preset seeds `toolDefaults.ceiling` (thickness, height,
|
||||
// material, …) before the tool activates; the drawn polygon always wins.
|
||||
const defaults = useEditor.getState().toolDefaults.ceiling ?? {}
|
||||
const ceiling = CeilingNode.parse({ ...defaults, name, polygon: points })
|
||||
createNode(ceiling, levelId)
|
||||
triggerSFX('sfx:structure-build')
|
||||
return ceiling.id
|
||||
@@ -70,6 +79,10 @@ export const CeilingTool: React.FC = () => {
|
||||
const previousSnappedPointRef = useRef<[number, number] | null>(null)
|
||||
const shiftPressed = useRef(false)
|
||||
|
||||
// Clear preset-seeded defaults on deactivation so a later manual ceiling
|
||||
// draw isn't built with a stale preset's parameters. Unmount-only.
|
||||
useEffect(() => () => useEditor.getState().setToolDefaults('ceiling', null), [])
|
||||
|
||||
const verticalGeo = useMemo(
|
||||
() =>
|
||||
new BufferGeometry().setFromPoints([
|
||||
|
||||
Reference in New Issue
Block a user