- fence: split into two paint slots — panel (posts/base/infill, default charcoal) and rail (cap, default wood-finewood27) — as separate meshes with userData.slotId. Fix applyFenceUVs to continuous world-space 1 UV unit = 1 m (drop the per-part min origin that broke tiling across parts). New generateFenceSlotGeometries. - roof: real catalog defaults for the segment surfaces via getRoofMaterialArray (the actual default path): wall/trim concrete-plate (matches walls), deck + soffit soft-white, shingle terracotta; textures-off role escape hatch kept. Align nodes getRoofMaterials no-parent fallback to match. - stair: body slot default -> preset-lightgrey. - (biome formatting normalization of the round-1 merged renderer files rides along.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21 lines
755 B
TypeScript
21 lines
755 B
TypeScript
import type { SlotDeclaration, StairNode } from '@pascal-app/core'
|
|
|
|
export type StairSlotId = 'treads' | 'body' | 'railing'
|
|
|
|
export const STAIR_TREADS_SLOT_DEFAULT = 'library:wood-woodplank48'
|
|
export const STAIR_BODY_SLOT_DEFAULT = 'library:preset-lightgrey'
|
|
export const STAIR_RAILING_SLOT_DEFAULT = 'library:metal-steel'
|
|
|
|
export function stairSlots(node: StairNode): SlotDeclaration[] {
|
|
const slots: SlotDeclaration[] = [
|
|
{ slotId: 'treads', label: 'Treads', default: STAIR_TREADS_SLOT_DEFAULT },
|
|
{ slotId: 'body', label: 'Body', default: STAIR_BODY_SLOT_DEFAULT },
|
|
]
|
|
|
|
if (node.railingMode && node.railingMode !== 'none') {
|
|
slots.push({ slotId: 'railing', label: 'Railing', default: STAIR_RAILING_SLOT_DEFAULT })
|
|
}
|
|
|
|
return slots
|
|
}
|