From c3d0f6c01d8af6967fc749f4dcfba6a36fd10846 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 24 May 2026 20:51:01 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/components/three/ModelViewer.tsx | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index 5d9c785..992c984 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -1078,6 +1078,43 @@ function GridAutoFollower() { return null; } +/** When gridCalibMode is on, the next click on the model sets the grid Y to + * the world Y of the clicked surface point and disables auto-follow. */ +function GridCalibrationHandler() { + const { camera, scene, gl } = useThree(); + const gridCalibMode = useModelStore((s) => s.gridCalibMode); + const raycaster = useMemo(() => new THREE.Raycaster(), []); + const mouse = useMemo(() => new THREE.Vector2(), []); + useEffect(() => { + if (!gridCalibMode) return; + const canvas = gl.domElement; + const prevCursor = canvas.style.cursor; + canvas.style.cursor = 'crosshair'; + const onPointerUp = (ev: PointerEvent) => { + if (ev.button !== 0) return; + const rect = canvas.getBoundingClientRect(); + mouse.x = ((ev.clientX - rect.left) / rect.width) * 2 - 1; + mouse.y = -((ev.clientY - rect.top) / rect.height) * 2 + 1; + raycaster.setFromCamera(mouse, camera); + const hits = raycaster.intersectObjects(scene.children, true); + const hit = hits.find((h) => isPickableModelMesh(h.object)); + if (!hit) return; + useModelStore.setState({ + gridY: hit.point.y - 0.001, + gridAutoFollow: false, + gridCalibMode: false, + showGrid: true, + }); + }; + canvas.addEventListener('pointerup', onPointerUp); + return () => { + canvas.removeEventListener('pointerup', onPointerUp); + canvas.style.cursor = prevCursor; + }; + }, [gridCalibMode, camera, scene, gl, raycaster, mouse]); + return null; +} + /** Mouse drag handler for desktop "Posicionar" mode: translates/rotates the active model. */ function PositionDragHandler() { const { camera, gl, scene } = useThree();