From a769d51d9f9d328a6b39a7a3c5def0c99a706089 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:50:18 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/components/three/ModelViewer.tsx | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index 14cbf51..9fa1ffa 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -1035,34 +1035,39 @@ function GridLayer() { ); } -/** Continuously aligns the grid Y to the bottom of all visible models so the - * piece always looks like it is sitting on the grid — including after - * calibration, fine-tuning, repositioning or scale changes. */ +/** Continuously aligns the grid Y to the bottom of all registered model + * groups (not the entire scene), so the piece always sits on the grid — + * including after calibration, fine-tuning or repositioning. */ function GridAutoFollower() { - const { scene } = useThree(); const lastY = useRef(Number.NaN); const acc = useRef(0); useFrame((_, dt) => { const auto = useModelStore.getState().gridAutoFollow; if (!auto) return; - // Throttle to ~10 Hz to keep this cheap. acc.current += dt; if (acc.current < 0.1) return; acc.current = 0; + const groups = getAllModelLocalGroups(); + if (groups.length === 0) return; const box = new THREE.Box3(); let has = false; - scene.traverse((obj) => { - if (obj instanceof THREE.Mesh && obj.geometry) { + const tmp = new THREE.Box3(); + for (const g of groups) { + g.updateWorldMatrix(true, true); + tmp.makeEmpty(); + g.traverse((obj) => { + if (!(obj instanceof THREE.Mesh) || !obj.geometry) return; if (obj.geometry instanceof THREE.SphereGeometry) return; if (obj.geometry instanceof THREE.RingGeometry) return; if (obj.userData.__edgeLine) return; const b = new THREE.Box3().setFromObject(obj); - if (isFinite(b.min.y)) { - if (!has) { box.copy(b); has = true; } - else box.union(b); - } + if (isFinite(b.min.y)) tmp.union(b); + }); + if (!tmp.isEmpty() && isFinite(tmp.min.y)) { + if (!has) { box.copy(tmp); has = true; } + else box.union(tmp); } - }); + } if (!has) return; const target = box.min.y - 0.005; if (!Number.isFinite(lastY.current) || Math.abs(target - lastY.current) > 1e-4) {