From e6e40246ce849600db44c332ee224b9f11bf664e Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Sat, 11 Apr 2026 03:22:03 +0200 Subject: [PATCH] Update App.tsx and ViewportHost.ts to include viewport camera sync request ID and resolve object scale constraint axis --- src/app/App.tsx | 2 ++ src/viewport-three/viewport-host.ts | 29 +++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index 921d0e56..0d59df5e 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1252,6 +1252,8 @@ export function App({ store, initialStatusMessage }: AppProps) { String(DEFAULT_GRID_SIZE) ); const [viewportGridVisible, setViewportGridVisible] = useState(true); + const [viewportCameraSyncRequestId, setViewportCameraSyncRequestId] = + useState(0); const [uvOffsetDraft, setUvOffsetDraft] = useState( createVec2Draft(createDefaultFaceUvState().offset) ); diff --git a/src/viewport-three/viewport-host.ts b/src/viewport-three/viewport-host.ts index f55dbeb6..f64d54c5 100644 --- a/src/viewport-three/viewport-host.ts +++ b/src/viewport-three/viewport-host.ts @@ -166,6 +166,7 @@ import { } from "../rendering/water-material"; import { resolveViewportFocusTarget } from "./viewport-focus"; import { createSoundEmitterMarkerMeshes } from "./viewport-entity-markers"; +import { resolveDominantLocalAxisForWorldAxis } from "./transform-axis-mapping"; import { getViewportViewModeDefinition, isOrthographicViewportViewMode, @@ -1425,6 +1426,18 @@ export class ViewportHost { }; } + private resolveObjectScaleConstraintAxis( + session: Extract, + worldAxis: TransformAxis + ): TransformAxis { + const rotationDegrees = + session.target.kind === "brush" + ? session.target.initialRotationDegrees + : session.target.initialRotationDegrees; + + return resolveDominantLocalAxisForWorldAxis(rotationDegrees, worldAxis); + } + private normalizeDegrees(value: number): number { const normalized = value % 360; return normalized < 0 ? normalized + 360 : normalized; @@ -2476,6 +2489,10 @@ export class ViewportHost { session.target.initialSize.z * uniformFactor ); } else { + const scaleAxis = this.resolveObjectScaleConstraintAxis( + session, + axisConstraint + ); const scaleFactor = 1 + this.getAxisMovementDistance( @@ -2485,8 +2502,8 @@ export class ViewportHost { current ) * 0.45; - nextSize[axisConstraint] = this.snapWhiteboxSizeValue( - session.target.initialSize[axisConstraint] * scaleFactor + nextSize[scaleAxis] = this.snapWhiteboxSizeValue( + session.target.initialSize[scaleAxis] * scaleFactor ); } @@ -2529,6 +2546,10 @@ export class ViewportHost { session.target.initialScale.z * uniformFactor ); } else { + const scaleAxis = this.resolveObjectScaleConstraintAxis( + session, + axisConstraint + ); const scaleFactor = 1 + this.getAxisMovementDistance( @@ -2538,8 +2559,8 @@ export class ViewportHost { current ) * 0.45; - nextScale[axisConstraint] = this.snapScaleValue( - session.target.initialScale[axisConstraint] * scaleFactor + nextScale[scaleAxis] = this.snapScaleValue( + session.target.initialScale[scaleAxis] * scaleFactor ); }