feat(paint-slots): prepared-drywall finish + fence 4 slots matching build options
- Add 'concrete-drywall' (Prepared Drywall) catalog finish + 512 KTX2/webp runtime assets; default walls (WALL_SLOT_DEFAULT interior+exterior) and the roof wall/trim band to it so roofs read continuous with walls. - fence: replace the 2-slot panel/rail split with 4 slots that match the panel's build options — posts / infill (showInfill) / base (grounded only) / rail — each its own mesh with userData.slotId; conditional slots track the build state. Defaults: posts/infill/base charcoal, rail wood-finewood27. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e92ee05702
commit
bba0cc5f68
@@ -1,15 +1,32 @@
|
||||
import type { SlotDeclaration } from '@pascal-app/core'
|
||||
import type { FenceNode } from './schema'
|
||||
|
||||
export type FenceSlotId = 'panel' | 'rail'
|
||||
// Slots map 1:1 to the fence panel's build options: the end posts, the infill
|
||||
// slats (the showInfill toggle), the base kickboard, and the top rail.
|
||||
export type FenceSlotId = 'posts' | 'infill' | 'base' | 'rail'
|
||||
|
||||
// Body (posts / base / infill) reads as a dark composite by default; the rail
|
||||
// cap as wood. Both are repaintable per slot.
|
||||
export const FENCE_PANEL_SLOT_DEFAULT = 'library:preset-charcoal'
|
||||
export const FENCE_POSTS_SLOT_DEFAULT = 'library:preset-charcoal'
|
||||
export const FENCE_INFILL_SLOT_DEFAULT = 'library:preset-charcoal'
|
||||
export const FENCE_BASE_SLOT_DEFAULT = 'library:preset-charcoal'
|
||||
export const FENCE_RAIL_SLOT_DEFAULT = 'library:wood-finewood27'
|
||||
|
||||
export function fenceSlots(): SlotDeclaration[] {
|
||||
return [
|
||||
{ slotId: 'panel', label: 'Panel', default: FENCE_PANEL_SLOT_DEFAULT },
|
||||
{ slotId: 'rail', label: 'Rail', default: FENCE_RAIL_SLOT_DEFAULT },
|
||||
export const FENCE_SLOT_DEFAULTS: Record<FenceSlotId, string> = {
|
||||
posts: FENCE_POSTS_SLOT_DEFAULT,
|
||||
infill: FENCE_INFILL_SLOT_DEFAULT,
|
||||
base: FENCE_BASE_SLOT_DEFAULT,
|
||||
rail: FENCE_RAIL_SLOT_DEFAULT,
|
||||
}
|
||||
|
||||
export function fenceSlots(node: FenceNode): SlotDeclaration[] {
|
||||
const slots: SlotDeclaration[] = [
|
||||
{ slotId: 'posts', label: 'Posts', default: FENCE_POSTS_SLOT_DEFAULT },
|
||||
]
|
||||
if (node.showInfill !== false) {
|
||||
slots.push({ slotId: 'infill', label: 'Infill', default: FENCE_INFILL_SLOT_DEFAULT })
|
||||
}
|
||||
if (node.baseStyle !== 'floating') {
|
||||
slots.push({ slotId: 'base', label: 'Base', default: FENCE_BASE_SLOT_DEFAULT })
|
||||
}
|
||||
slots.push({ slotId: 'rail', label: 'Rail', default: FENCE_RAIL_SLOT_DEFAULT })
|
||||
return slots
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user