52/100 di schifo
Chiami un parametro `cap` e poi raccogli TUTTI i punti nel raggio in un array per poi buttarne via la maggior parte: il limite non limita il lavoro, limita solo la dignità della RAM. I nomi li hai lasciati a casa: `c`, `R`, `g`, `b`, `lo`, `hi` — manca solo `x` e sembra l'alfabeto caduto dalle scale. Il magico `12000` decide se fare la cosa furba o spazzolare tutti i vertici, e i tre numeri primi nell'hash sono incantesimi senza un commento a spiegarli. E se `cap` è 0, `step` diventa Infinity: nel codice, 'infinito' non è mai una buona risposta.
function collectNear(geo, c, R, cap) {
const pos = geo.attributes.position;
const nor = geo.attributes.normal;
if (!pos || !nor) return { P: [], N: [] };
const pa = pos.array, na = nor.array;
const g = vertexGrid(geo);
const R2 = R * R;
const idx = [];
const lo = (v, o) => Math.max(0, Math.floor((v - R - o) * g.inv));
const hi = (v, o) => Math.floor((v + R - o) * g.inv);
const ix0 = lo(c.x, g.ox), ix1 = hi(c.x, g.ox);
const iy0 = lo(c.y, g.oy), iy1 = hi(c.y, g.oy);
const iz0 = lo(c.z, g.oz), iz1 = hi(c.z, g.oz);
const cells = (ix1 - ix0 + 1) * (iy1 - iy0 + 1) * (iz1 - iz0 + 1);
const test = i => {
const j = i * 3;
const dx = pa[j] - c.x, dy = pa[j + 1] - c.y, dz = pa[j + 2] - c.z;
if (dx * dx + dy * dy + dz * dz <= R2) idx.push(i);
};
if (cells > 0 && cells < 12000) {
for (let ix = ix0; ix <= ix1; ix++)
for (let iy = iy0; iy <= iy1; iy++)
for (let iz = iz0; iz <= iz1; iz++) {
const b = g.map.get((ix * 73856093) ^ (iy * 19349663) ^ (iz * 83492791));
if (b) for (let n = 0; n < b.length; n++) test(b[n]);
}
} else {
for (let i = 0; i < pos.count; i++) test(i);
}
const step = Math.max(1, Math.ceil(idx.length / cap));
const P = [], N = [];
for (let n = 0; n < idx.length; n += step) {
const j = idx[n] * 3;
P.push(new THREE.Vector3(pa[j], pa[j + 1], pa[j + 2]));
N.push(new THREE.Vector3(na[j], na[j + 1], na[j + 2]));
}
return { P, N };
}