diff --git a/src/app/App.tsx b/src/app/App.tsx index 54202ad8..205377a5 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1049,6 +1049,7 @@ export function App({ store, initialStatusMessage }: AppProps) { const [boxVolumeFogPaddingDraft, setBoxVolumeFogPaddingDraft] = useState("0.2"); const [whiteboxSnapEnabled, setWhiteboxSnapEnabled] = useState(true); const [whiteboxSnapStepDraft, setWhiteboxSnapStepDraft] = useState(String(DEFAULT_GRID_SIZE)); + const [viewportGridVisible, setViewportGridVisible] = useState(true); const [uvOffsetDraft, setUvOffsetDraft] = useState(createVec2Draft(createDefaultFaceUvState().offset)); const [uvScaleDraft, setUvScaleDraft] = useState(createVec2Draft(createDefaultFaceUvState().scale)); const [entityPositionDraft, setEntityPositionDraft] = useState(createVec3Draft(DEFAULT_ENTITY_POSITION)); @@ -2111,8 +2112,24 @@ export function App({ store, initialStatusMessage }: AppProps) { return; } - store.setTransformAxisConstraint(axis); - setStatusMessage(`Constrained ${getTransformOperationLabel(transformSession.operation).toLowerCase()} to ${axis.toUpperCase()}.`); + const nextAxisConstraintSpace = + transformSession.axisConstraint === axis ? (transformSession.axisConstraintSpace === "world" ? "local" : "world") : "world"; + + if (nextAxisConstraintSpace === "local" && !supportsLocalTransformAxisConstraint(transformSession, axis)) { + setStatusMessage( + `Local ${getTransformAxisLabel(axis)} is not supported for ${getTransformOperationLabel(transformSession.operation).toLowerCase()} on ${getTransformTargetLabel( + transformSession.target + )}.` + ); + return; + } + + store.setTransformAxisConstraint(axis, nextAxisConstraintSpace); + setStatusMessage( + `Constrained ${getTransformOperationLabel(transformSession.operation).toLowerCase()} to ${getTransformAxisSpaceLabel( + nextAxisConstraintSpace + ).toLowerCase()} ${getTransformAxisLabel(axis)}.` + ); }; const handleViewportQuadResizeStart = @@ -2186,6 +2203,12 @@ export function App({ store, initialStatusMessage }: AppProps) { setStatusMessage(nextEnabled ? `Grid snap enabled at ${whiteboxSnapStep}m.` : "Grid snap disabled for whitebox transforms."); }; + const handleViewportGridToggle = () => { + const nextVisible = !viewportGridVisible; + setViewportGridVisible(nextVisible); + setStatusMessage(nextVisible ? "Viewport grid enabled." : "Viewport grid hidden."); + }; + const handleWhiteboxSnapStepBlur = () => { const normalizedStep = resolveOptionalPositiveNumber(whiteboxSnapStepDraft, DEFAULT_GRID_SIZE); setWhiteboxSnapStepDraft(String(normalizedStep)); @@ -5269,6 +5292,15 @@ export function App({ store, initialStatusMessage }: AppProps) {