feat(paint-slots): per-part paint for windows + doors, chrome/brass, world-scale UVs
Builds on the explicit per-mesh slot tagging (currentDoorSlot/currentWindowSlot): - Per-part painting: door = panel/frame/glass/hardware, window = frame/glass, each independently paintable. The recessed door/window body sits behind the wall, so the proud invisible cutout wins the scene raycast over the wall and the shared resolveSlotByReRaycast() re-raycasts the kind's own subtree to pick the exact part under the cursor (panel↔frame↔glass↔hardware). Hover tracks the cursor via a re-eval (idempotent, no flicker). - Door frame is its own slot (separate frameMaterial); hardware = new flat 'metal-chrome'. - Library defaults (generic): panel/frame -> library:preset-softwhite, glass -> library:preset-glass (flipped preset-glass to FrontSide — DoubleSide poisons the WebGPU MRT pass; it's the only glass we use). - Catalog: add flat (non-PBR) 'metal-chrome' + 'metal-brass'; drop metal metalness 1 -> 0.6 so metals are lit by existing lights (no env needed). - World-scale UVs (1 unit = 1m) on door/window box meshes via shared box-uv.ts, so finishes tile at real-world scale instead of stretching. - PaintResolveArgs gains an optional for subtree re-raycasting. 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
c3bd065f2f
commit
8aa179e9cb
@@ -1,5 +1,5 @@
|
||||
import type { ComponentType } from 'react'
|
||||
import type { BufferGeometry, Object3D } from 'three'
|
||||
import type { BufferGeometry, Object3D, Ray } from 'three'
|
||||
import type { ZodObject, z } from 'zod'
|
||||
import type { MaterialSchema } from '../schema/material'
|
||||
import type { SceneMaterial, SceneMaterialId } from '../schema/scene-material'
|
||||
@@ -1212,6 +1212,14 @@ export type PaintResolveArgs = {
|
||||
hitObjectName?: string
|
||||
/** Optional: the three.js object that received the pointer hit. Items read userData.slotId off it. */
|
||||
hitObject?: Object3D
|
||||
/**
|
||||
* Optional: the pointer's world ray, so a kind can re-raycast its OWN subtree
|
||||
* to pick the precise sub-mesh under the cursor — independent of what the
|
||||
* shared scene raycast hit first. Door/window use this: their opening proxy
|
||||
* (a proud invisible cutout) wins the scene raycast over the wall in front of
|
||||
* the recessed door body, then they re-raycast their parts to find the slot.
|
||||
*/
|
||||
ray?: Ray
|
||||
}
|
||||
|
||||
export type PaintPatchArgs = {
|
||||
|
||||
Reference in New Issue
Block a user