diff --git a/src/viewport-three/ViewportCanvas.tsx b/src/viewport-three/ViewportCanvas.tsx index a0c5690b..991616e8 100644 --- a/src/viewport-three/ViewportCanvas.tsx +++ b/src/viewport-three/ViewportCanvas.tsx @@ -4,6 +4,10 @@ import type { LoadedModelAsset } from "../assets/gltf-model-import"; import type { LoadedImageAsset } from "../assets/image-assets"; import type { ProjectAssetRecord } from "../assets/project-assets"; import type { EditorSelection } from "../core/selection"; +import type { + ArmedTerrainBrushState, + TerrainBrushStrokeCommit +} from "../core/terrain-brush"; import { getWhiteboxSelectionFeedbackLabel } from "../core/whitebox-selection-feedback"; import type { ToolMode } from "../core/tool-mode"; import { type WhiteboxSelectionMode } from "../core/whitebox-selection-mode"; @@ -52,6 +56,7 @@ interface ViewportCanvasProps { viewportGridVisible: boolean; selection: EditorSelection; activeSelectionId: string | null; + terrainBrushState: ArmedTerrainBrushState | null; toolMode: ToolMode; toolPreview: ViewportToolPreview; transformSession: TransformSessionState; @@ -63,6 +68,7 @@ interface ViewportCanvasProps { focusRequestId: number; focusSelection: EditorSelection; onSelectionChange(selection: EditorSelection): void; + onTerrainBrushCommit(commit: TerrainBrushStrokeCommit): boolean; onCommitCreation(toolPreview: CreationViewportToolPreview): boolean; onCameraStateChange(cameraState: ViewportPanelCameraState): void; onToolPreviewChange(toolPreview: ViewportToolPreview): void; @@ -86,6 +92,7 @@ export function ViewportCanvas({ viewportGridVisible, selection, activeSelectionId, + terrainBrushState, toolMode, toolPreview, transformSession, @@ -97,6 +104,7 @@ export function ViewportCanvas({ focusRequestId, focusSelection, onSelectionChange, + onTerrainBrushCommit, onCommitCreation, onCameraStateChange, onToolPreviewChange, @@ -209,6 +217,10 @@ export function ViewportCanvas({ hostRef.current?.setBrushSelectionChangeHandler(onSelectionChange); }, [onSelectionChange]); + useEffect(() => { + hostRef.current?.setTerrainBrushCommitHandler?.(onTerrainBrushCommit); + }, [onTerrainBrushCommit]); + useEffect(() => { hostRef.current?.setWhiteboxHoverLabelChangeHandler( setHoveredWhiteboxLabel @@ -252,6 +264,10 @@ export function ViewportCanvas({ hostRef.current?.setToolMode(toolMode); }, [toolMode]); + useLayoutEffect(() => { + hostRef.current?.setTerrainBrushState?.(terrainBrushState); + }, [terrainBrushState]); + useLayoutEffect(() => { hostRef.current?.setCreationPreview( toolMode === "create" && toolPreview.kind === "create" @@ -280,6 +296,8 @@ export function ViewportCanvas({ const selectedWhiteboxLabel = toolMode === "select" ? getWhiteboxSelectionFeedbackLabel(sceneDocument, selection) : null; + const terrainBrushOverlayVisible = + toolMode === "select" && terrainBrushState !== null; const resolvedViewportBackground = editorSimulationScene !== null && editorSimulationClock !== null ? resolveRuntimeDayNightWorldState( @@ -291,6 +309,7 @@ export function ViewportCanvas({ const showOverlay = previewVisible || transformPreviewVisible || + terrainBrushOverlayVisible || selectedWhiteboxLabel !== null || hoveredWhiteboxLabel !== null; @@ -351,6 +370,14 @@ export function ViewportCanvas({ ] .filter((part) => part !== null) .join(" · ")} + + )} + {!terrainBrushOverlayVisible ? null : ( +
+ terrain · {terrainBrushState.tool}
)} {selectedWhiteboxLabel === null ? null : ( diff --git a/src/viewport-three/ViewportPanel.tsx b/src/viewport-three/ViewportPanel.tsx index f50a52c5..bb64c218 100644 --- a/src/viewport-three/ViewportPanel.tsx +++ b/src/viewport-three/ViewportPanel.tsx @@ -25,6 +25,10 @@ import type { LoadedModelAsset } from "../assets/gltf-model-import"; import type { LoadedImageAsset } from "../assets/image-assets"; import type { ProjectAssetRecord } from "../assets/project-assets"; import type { EditorSelection } from "../core/selection"; +import type { + ArmedTerrainBrushState, + TerrainBrushStrokeCommit +} from "../core/terrain-brush"; import { getWhiteboxSelectionModeLabel, WHITEBOX_SELECTION_MODES, @@ -62,6 +66,7 @@ interface ViewportPanelProps { viewportGridVisible: boolean; selection: EditorSelection; activeSelectionId: string | null; + terrainBrushState: ArmedTerrainBrushState | null; toolMode: ToolMode; toolPreview: ViewportToolPreview; transformSession: TransformSessionState; @@ -85,6 +90,7 @@ interface ViewportPanelProps { displayMode: ViewportDisplayMode ): void; onCommitCreation(toolPreview: CreationViewportToolPreview): boolean; + onTerrainBrushCommit(commit: TerrainBrushStrokeCommit): boolean; onCameraStateChange(cameraState: ViewportPanelCameraState): void; onToolPreviewChange(toolPreview: ViewportToolPreview): void; onBeginTransformOperation(operation: TransformOperation): void; @@ -136,6 +142,7 @@ export function ViewportPanel({ viewportGridVisible, selection, activeSelectionId, + terrainBrushState, toolMode, toolPreview, transformSession, @@ -153,6 +160,7 @@ export function ViewportPanel({ onSetPanelViewMode, onSetPanelDisplayMode, onCommitCreation, + onTerrainBrushCommit, onCameraStateChange, onToolPreviewChange, onBeginTransformOperation, @@ -198,6 +206,7 @@ export function ViewportPanel({ viewportGridVisible={viewportGridVisible} selection={selection} activeSelectionId={activeSelectionId} + terrainBrushState={terrainBrushState} toolMode={toolMode} toolPreview={toolPreview} transformSession={transformSession} @@ -209,6 +218,7 @@ export function ViewportPanel({ focusRequestId={focusRequestId} focusSelection={focusSelection} onSelectionChange={onSelectionChange} + onTerrainBrushCommit={onTerrainBrushCommit} onCommitCreation={onCommitCreation} onCameraStateChange={onCameraStateChange} onToolPreviewChange={onToolPreviewChange}