Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-24 20:50:18 +00:00
parent 15f2bdfbb2
commit a769d51d9f
+17 -12
View File
@@ -1035,34 +1035,39 @@ function GridLayer() {
); );
} }
/** Continuously aligns the grid Y to the bottom of all visible models so the /** Continuously aligns the grid Y to the bottom of all registered model
* piece always looks like it is sitting on the grid — including after * groups (not the entire scene), so the piece always sits on the grid —
* calibration, fine-tuning, repositioning or scale changes. */ * including after calibration, fine-tuning or repositioning. */
function GridAutoFollower() { function GridAutoFollower() {
const { scene } = useThree();
const lastY = useRef<number>(Number.NaN); const lastY = useRef<number>(Number.NaN);
const acc = useRef(0); const acc = useRef(0);
useFrame((_, dt) => { useFrame((_, dt) => {
const auto = useModelStore.getState().gridAutoFollow; const auto = useModelStore.getState().gridAutoFollow;
if (!auto) return; if (!auto) return;
// Throttle to ~10 Hz to keep this cheap.
acc.current += dt; acc.current += dt;
if (acc.current < 0.1) return; if (acc.current < 0.1) return;
acc.current = 0; acc.current = 0;
const groups = getAllModelLocalGroups();
if (groups.length === 0) return;
const box = new THREE.Box3(); const box = new THREE.Box3();
let has = false; let has = false;
scene.traverse((obj) => { const tmp = new THREE.Box3();
if (obj instanceof THREE.Mesh && obj.geometry) { 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.SphereGeometry) return;
if (obj.geometry instanceof THREE.RingGeometry) return; if (obj.geometry instanceof THREE.RingGeometry) return;
if (obj.userData.__edgeLine) return; if (obj.userData.__edgeLine) return;
const b = new THREE.Box3().setFromObject(obj); const b = new THREE.Box3().setFromObject(obj);
if (isFinite(b.min.y)) { if (isFinite(b.min.y)) tmp.union(b);
if (!has) { box.copy(b); has = true; } });
else box.union(b); if (!tmp.isEmpty() && isFinite(tmp.min.y)) {
} if (!has) { box.copy(tmp); has = true; }
else box.union(tmp);
} }
}); }
if (!has) return; if (!has) return;
const target = box.min.y - 0.005; const target = box.min.y - 0.005;
if (!Number.isFinite(lastY.current) || Math.abs(target - lastY.current) > 1e-4) { if (!Number.isFinite(lastY.current) || Math.abs(target - lastY.current) > 1e-4) {