diff --git a/src/viewport-three/ViewportCanvas.tsx b/src/viewport-three/ViewportCanvas.tsx index 63f5dd50..e86b43e1 100644 --- a/src/viewport-three/ViewportCanvas.tsx +++ b/src/viewport-three/ViewportCanvas.tsx @@ -4,7 +4,9 @@ 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 { getWhiteboxSelectionFeedbackLabel } from "../core/whitebox-selection-feedback"; import type { ToolMode } from "../core/tool-mode"; +import { getWhiteboxSelectionModeLabel, type WhiteboxSelectionMode } from "../core/whitebox-selection-mode"; import type { Vec3 } from "../core/vector"; import type { ActiveTransformSession, TransformSessionState } from "../core/transform-session"; import type { SceneDocument } from "../document/scene-document"; @@ -32,6 +34,7 @@ interface ViewportCanvasProps { projectAssets: Record; loadedModelAssets: Record; loadedImageAssets: Record; + whiteboxSelectionMode: WhiteboxSelectionMode; whiteboxSnapEnabled: boolean; whiteboxSnapStep: number; selection: EditorSelection; @@ -61,6 +64,7 @@ export function ViewportCanvas({ projectAssets, loadedModelAssets, loadedImageAssets, + whiteboxSelectionMode, whiteboxSnapEnabled, whiteboxSnapStep, selection, @@ -85,6 +89,7 @@ export function ViewportCanvas({ const containerRef = useRef(null); const hostRef = useRef(null); const [viewportMessage, setViewportMessage] = useState(null); + const [hoveredWhiteboxLabel, setHoveredWhiteboxLabel] = useState(null); useEffect(() => { const container = containerRef.current; @@ -138,6 +143,10 @@ export function ViewportCanvas({ hostRef.current?.setWhiteboxSnapSettings(whiteboxSnapEnabled, whiteboxSnapStep); }, [whiteboxSnapEnabled, whiteboxSnapStep]); + useEffect(() => { + hostRef.current?.setWhiteboxSelectionMode(whiteboxSelectionMode); + }, [whiteboxSelectionMode]); + useEffect(() => { hostRef.current?.updateDocument(sceneDocument, selection); }, [sceneDocument, selection]); @@ -158,6 +167,10 @@ export function ViewportCanvas({ hostRef.current?.setBrushSelectionChangeHandler(onSelectionChange); }, [onSelectionChange]); + useEffect(() => { + hostRef.current?.setWhiteboxHoverLabelChangeHandler(setHoveredWhiteboxLabel); + }, []); + useEffect(() => { hostRef.current?.setCameraStateChangeHandler(onCameraStateChange); }, [onCameraStateChange]); @@ -213,8 +226,10 @@ export function ViewportCanvas({ const previewVisible = toolMode === "create" && toolPreview.kind === "create" && toolPreview.center !== null; const transformPreviewVisible = transformSession.kind === "active"; + const selectionModeVisible = toolMode === "select"; + const selectedWhiteboxLabel = selectionModeVisible ? getWhiteboxSelectionFeedbackLabel(sceneDocument, selection) : null; const showViewModeOverlay = layoutMode === "quad"; - const showOverlay = showViewModeOverlay || previewVisible || transformPreviewVisible; + const showOverlay = showViewModeOverlay || selectionModeVisible || previewVisible || transformPreviewVisible || selectedWhiteboxLabel !== null || hoveredWhiteboxLabel !== null; return (
{getViewportViewModeLabel(viewMode)}
+ {!selectionModeVisible ? null : ( +
+ {getWhiteboxSelectionModeLabel(whiteboxSelectionMode)} +
+ )} +
+ )} + {showViewModeOverlay || !selectionModeVisible ? null : ( +
+
+ {getWhiteboxSelectionModeLabel(whiteboxSelectionMode)} +
)} {!previewVisible ? null : ( @@ -251,6 +284,16 @@ export function ViewportCanvas({ : `${transformSession.operation}${transformSession.axisConstraint === null ? "" : ` ยท ${transformSession.axisConstraint.toUpperCase()}`}`} )} + {selectedWhiteboxLabel === null ? null : ( +
+ Selected: {selectedWhiteboxLabel} +
+ )} + {hoveredWhiteboxLabel === null ? null : ( +
+ Hover: {hoveredWhiteboxLabel} +
+ )} )} diff --git a/src/viewport-three/ViewportPanel.tsx b/src/viewport-three/ViewportPanel.tsx index def6a583..168ef04a 100644 --- a/src/viewport-three/ViewportPanel.tsx +++ b/src/viewport-three/ViewportPanel.tsx @@ -16,6 +16,7 @@ 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 { WhiteboxSelectionMode } from "../core/whitebox-selection-mode"; import type { ActiveTransformSession, TransformSessionState } from "../core/transform-session"; import type { ToolMode } from "../core/tool-mode"; import type { SceneDocument } from "../document/scene-document"; @@ -33,6 +34,7 @@ interface ViewportPanelProps { projectAssets: Record; loadedModelAssets: Record; loadedImageAssets: Record; + whiteboxSelectionMode: WhiteboxSelectionMode; whiteboxSnapEnabled: boolean; whiteboxSnapStep: number; selection: EditorSelection; @@ -66,6 +68,7 @@ export function ViewportPanel({ projectAssets, loadedModelAssets, loadedImageAssets, + whiteboxSelectionMode, whiteboxSnapEnabled, whiteboxSnapStep, selection, @@ -102,6 +105,18 @@ export function ViewportPanel({ onFocusCapture={() => onActivatePanel(panelId)} >
+ {layoutMode !== "quad" ? null : ( +
+
+
{getViewportPanelLabel(panelId)}
+ {!isActive ? null : ( +
+ Active +
+ )} +
+
+ )}
{VIEWPORT_VIEW_MODES.map((viewMode) => ( @@ -142,6 +157,7 @@ export function ViewportPanel({ projectAssets={projectAssets} loadedModelAssets={loadedModelAssets} loadedImageAssets={loadedImageAssets} + whiteboxSelectionMode={whiteboxSelectionMode} whiteboxSnapEnabled={whiteboxSnapEnabled} whiteboxSnapStep={whiteboxSnapStep} selection={selection}