mesh v2 at /v2/mesh
This commit is contained in:
parent
aee9fd6ed7
commit
6566c45f9a
85 changed files with 138198 additions and 1 deletions
128
src2/geo/points.js
Normal file
128
src2/geo/points.js
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
"use strict";
|
||||
|
||||
import { newPoint } from '../geo/point.js';
|
||||
|
||||
const { config } = base;
|
||||
|
||||
/**
|
||||
* converts a geometry point array into a kiri point array
|
||||
* with optional decimation
|
||||
*/
|
||||
export function verticesToPoints(array, options) {
|
||||
let parr = new Array(array.length / 3),
|
||||
i = 0,
|
||||
j = 0,
|
||||
t = Date.now(),
|
||||
hash = {},
|
||||
unique = 0,
|
||||
passes = 0,
|
||||
points,
|
||||
oldpoints = parr.length,
|
||||
newpoints;
|
||||
|
||||
let {threshold, precision, maxpass} = options || {};
|
||||
// threshold = point count for triggering decimation
|
||||
// precision = under which points are merged
|
||||
// maxpass = max number of decimations
|
||||
threshold = threshold > 0 ? threshold : config.decimate_threshold;
|
||||
precision = precision >= 0 ? precision : config.precision_decimate;
|
||||
maxpass = maxpass >= 0 ? maxpass : 0;
|
||||
|
||||
// replace point objects with their equivalents
|
||||
if (maxpass) {
|
||||
while (i < array.length) {
|
||||
let p = newPoint(array[i++], array[i++], array[i++]),
|
||||
k = p.key,
|
||||
m = hash[k];
|
||||
if (!m) {
|
||||
m = p;
|
||||
hash[k] = p;
|
||||
unique++;
|
||||
}
|
||||
parr[j++] = m;
|
||||
}
|
||||
} else {
|
||||
while (i < array.length) {
|
||||
parr[j++] = newPoint(array[i++], array[i++], array[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
// decimate until all point spacing > precision
|
||||
if (maxpass && precision > 0.0)
|
||||
while (parr.length > threshold) {
|
||||
let lines = [], line, dec = 0;
|
||||
for (i=0; i<oldpoints; ) {
|
||||
let p1 = parr[i++],
|
||||
p2 = parr[i++],
|
||||
p3 = parr[i++];
|
||||
lines.push( {p1:p1, p2:p2, d:Math.sqrt(p1.distToSq3D(p2))} );
|
||||
lines.push( {p1:p1, p2:p3, d:Math.sqrt(p1.distToSq3D(p3))} );
|
||||
lines.push( {p1:p2, p2:p3, d:Math.sqrt(p2.distToSq3D(p3))} );
|
||||
}
|
||||
// sort by ascending line length
|
||||
lines.sort(function(a,b) {
|
||||
return a.d - b.d
|
||||
});
|
||||
// create offset mid-points
|
||||
for (i=0; i<lines.length; i++) {
|
||||
line = lines[i];
|
||||
// skip lines longer than precision threshold
|
||||
if (line.d >= precision) break;
|
||||
// skip lines where one of the points is already offset
|
||||
if (line.p1.op || line.p2.op) continue;
|
||||
// todo skip dropping lines where either point is a "sharp" on 3 vectors
|
||||
// todo skip dropping lines where either point connects to a "long" line
|
||||
line.p1.op = line.p2.op = line.p1.midPointTo3D(line.p2);
|
||||
dec++;
|
||||
}
|
||||
// exit if nothing to decimate
|
||||
if (dec === 0) break;
|
||||
passes++;
|
||||
// create new facets
|
||||
points = new Array(oldpoints);
|
||||
newpoints = 0;
|
||||
for (i=0; i<oldpoints; ) {
|
||||
let p1 = parr[i++],
|
||||
p2 = parr[i++],
|
||||
p3 = parr[i++];
|
||||
// drop facets with two offset points
|
||||
if (p1.op && p1.op === p2.op) continue;
|
||||
if (p1.op && p1.op === p3.op) continue;
|
||||
if (p2.op && p2.op === p3.op) continue;
|
||||
// otherwise emit altered facet
|
||||
points[newpoints++] = p1.op || p1;
|
||||
points[newpoints++] = p2.op || p2;
|
||||
points[newpoints++] = p3.op || p3;
|
||||
}
|
||||
parr = points.slice(0,newpoints);
|
||||
oldpoints = newpoints;
|
||||
if (passes >= maxpass) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if (passes) console.trace({passes, threshold, precision, maxpass});
|
||||
|
||||
if (passes) console.log({
|
||||
before: array.length / 3,
|
||||
after: parr.length,
|
||||
unique: unique,
|
||||
decimations: passes,
|
||||
time: (Date.now() - t)
|
||||
});
|
||||
|
||||
return parr;
|
||||
}
|
||||
|
||||
export function pointsToVertices(points) {
|
||||
let vertices = new Float32Array(points.length * 3),
|
||||
i = 0, vi = 0;
|
||||
while (i < points.length) {
|
||||
vertices[vi++] = points[i].x;
|
||||
vertices[vi++] = points[i].y;
|
||||
vertices[vi++] = points[i++].z;
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
Loading…
Reference in a new issue