fix(paste): UTM-precise paste/block base via f64 centroid
entities_centroid summed the f32 points (double-single HIGH half) alone, so at UTM scale (~5.7e6) it both quantized each term ~0.5 m and lost low bits across the running total — drifting the paste base and PASTEBLOCK's block base metres off, which placed the wrapped block at the wrong spot/scale. It now reconstructs each vertex's absolute f64 from points + points_low and accumulates in f64. clipboard_centroid is DVec3; the PASTECLIP commit delta is fully f64; define_block_from_owned_entities takes an f64 base so the block-local fold (Translate(-base)) stays precise. The interactive ghost anchors (PasteCommand, InsertBlockCommand) still take the f32 cast — display only; the committed geometry is f64. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
fe5ff376e5
commit
60d4712179
5 changed files with 31 additions and 21 deletions
|
|
@ -254,25 +254,34 @@ pub(super) fn polar_constrain_near(
|
|||
// ── Clipboard / selection helpers ──────────────────────────────────────────
|
||||
|
||||
/// Compute the centroid of a set of wire models (average of all points).
|
||||
pub(super) fn entities_centroid(wires: &[WireModel]) -> glam::Vec3 {
|
||||
let mut sum = glam::Vec3::ZERO;
|
||||
pub(super) fn entities_centroid(wires: &[WireModel]) -> glam::DVec3 {
|
||||
// Reconstruct each vertex's absolute f64 from the double-single high/low
|
||||
// pair and accumulate in f64: summing the f32 `points` alone at UTM scale
|
||||
// (~5.7e6) both quantizes each term ~0.5 m and loses low bits across the
|
||||
// running total, drifting the paste base / block base metres off.
|
||||
let mut sum = glam::DVec3::ZERO;
|
||||
let mut count = 0usize;
|
||||
for w in wires {
|
||||
for p in &w.points {
|
||||
let v = glam::Vec3::from(*p);
|
||||
for (i, p) in w.points.iter().enumerate() {
|
||||
// Wire models carry NaN points as separators between disjoint
|
||||
// segments; summing them poisons the whole centroid into NaN,
|
||||
// which then makes every paste base point NaN. (#129)
|
||||
if v.is_finite() {
|
||||
sum += v;
|
||||
count += 1;
|
||||
if !p[0].is_finite() || !p[1].is_finite() || !p[2].is_finite() {
|
||||
continue;
|
||||
}
|
||||
let l = w.points_low.get(i).copied().unwrap_or([0.0; 3]);
|
||||
sum += glam::DVec3::new(
|
||||
p[0] as f64 + l[0] as f64,
|
||||
p[1] as f64 + l[1] as f64,
|
||||
p[2] as f64 + l[2] as f64,
|
||||
);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
if count > 0 {
|
||||
sum / count as f32
|
||||
sum / count as f64
|
||||
} else {
|
||||
glam::Vec3::ZERO
|
||||
glam::DVec3::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue