feat(editor): roof features in standalone Build tab + thumbnail flag fix
- registry: getRoofAccessoryKinds() enumerates kinds declaring the roofAccessory capability, in deterministic builtin-list order (mirrors getSelectableKinds); exported from the registry barrel. - apps/editor build-tab: a "Features" group under the Roof tile, discovered from the registry (no DB) and activating each kind's roof-attach tool — parity with the community editor's roof features. - site-boundary-editor: hide the flag handle group around thumbnail captures (they render on SCENE_LAYER so the thumbnail camera can't layer-filter them), matching handle-arrow.tsx — keeps flags out of preset/snapshot thumbnails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
eb00f9f477
commit
478f0910f7
@@ -3,7 +3,15 @@ import { SCENE_LAYER } from '@pascal-app/viewer'
|
||||
import { useGLTF } from '@react-three/drei/core/Gltf'
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Color, CylinderGeometry, DoubleSide, type Mesh, type Object3D, RingGeometry } from 'three'
|
||||
import {
|
||||
Color,
|
||||
CylinderGeometry,
|
||||
DoubleSide,
|
||||
type Group,
|
||||
type Mesh,
|
||||
type Object3D,
|
||||
RingGeometry,
|
||||
} from 'three'
|
||||
import { MeshBasicNodeMaterial } from 'three/webgpu'
|
||||
import { EDITOR_LAYER } from '../../../lib/constants'
|
||||
import { sfxEmitter } from '../../../lib/sfx-bus'
|
||||
@@ -407,6 +415,26 @@ export const SiteBoundaryEditor: React.FC = () => {
|
||||
}
|
||||
}, [isSiteEditing, siteId])
|
||||
|
||||
// The flag models render on SCENE_LAYER (scene-depth occlusion), so unlike
|
||||
// EDITOR_LAYER affordances the thumbnail camera can't filter them — hide
|
||||
// them around captures (preset/snapshot/auto-save thumbnails), same as
|
||||
// `handle-arrow.tsx`.
|
||||
const handlesRootRef = useRef<Group>(null)
|
||||
useEffect(() => {
|
||||
const hideForCapture = () => {
|
||||
if (handlesRootRef.current) handlesRootRef.current.visible = false
|
||||
}
|
||||
const restoreAfterCapture = () => {
|
||||
if (handlesRootRef.current) handlesRootRef.current.visible = true
|
||||
}
|
||||
emitter.on('thumbnail:before-capture', hideForCapture)
|
||||
emitter.on('thumbnail:after-capture', restoreAfterCapture)
|
||||
return () => {
|
||||
emitter.off('thumbnail:before-capture', hideForCapture)
|
||||
emitter.off('thumbnail:after-capture', restoreAfterCapture)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const activateSiteEditing = useCallback(() => {
|
||||
isDraggingSiteBoundaryRef.current = true
|
||||
setIsDraggingSiteBoundary(true)
|
||||
@@ -483,25 +511,27 @@ export const SiteBoundaryEditor: React.FC = () => {
|
||||
if (!showSiteHandles) return null
|
||||
|
||||
return (
|
||||
<PolygonEditor
|
||||
color={isSiteBoundaryHighlighted ? ARROW_COLOR : '#10b981'}
|
||||
minVertices={3}
|
||||
onBeforeVertexDrag={activateSiteEditing}
|
||||
onDragCommit={() => {
|
||||
sfxEmitter.emit('sfx:item-place')
|
||||
exitSiteEditing()
|
||||
}}
|
||||
onDragStart={() => sfxEmitter.emit('sfx:item-pick')}
|
||||
onDragStateChange={handleSiteBoundaryDragChange}
|
||||
onMidpointHoverChange={setHoveredMidpoint}
|
||||
onPolygonChange={handlePolygonChange}
|
||||
onPolygonPreview={handlePolygonPreview}
|
||||
onVertexHoverChange={setHoveredVertex}
|
||||
polygon={displayPolygon}
|
||||
renderMidpointHandle={renderSiteFlagMidpoint}
|
||||
renderVertexHandle={renderSiteFlagVertex}
|
||||
showBorderLine={isSiteBoundaryHighlighted}
|
||||
showMidpointHandles={showSiteHandles}
|
||||
/>
|
||||
<group ref={handlesRootRef}>
|
||||
<PolygonEditor
|
||||
color={isSiteBoundaryHighlighted ? ARROW_COLOR : '#10b981'}
|
||||
minVertices={3}
|
||||
onBeforeVertexDrag={activateSiteEditing}
|
||||
onDragCommit={() => {
|
||||
sfxEmitter.emit('sfx:item-place')
|
||||
exitSiteEditing()
|
||||
}}
|
||||
onDragStart={() => sfxEmitter.emit('sfx:item-pick')}
|
||||
onDragStateChange={handleSiteBoundaryDragChange}
|
||||
onMidpointHoverChange={setHoveredMidpoint}
|
||||
onPolygonChange={handlePolygonChange}
|
||||
onPolygonPreview={handlePolygonPreview}
|
||||
onVertexHoverChange={setHoveredVertex}
|
||||
polygon={displayPolygon}
|
||||
renderMidpointHandle={renderSiteFlagMidpoint}
|
||||
renderVertexHandle={renderSiteFlagVertex}
|
||||
showBorderLine={isSiteBoundaryHighlighted}
|
||||
showMidpointHandles={showSiteHandles}
|
||||
/>
|
||||
</group>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user