faceted method
The same triangles, each with vertices of its own and its face's normal: hard edges everywhere, the low-poly look.
Implementation
ShapeMesh faceted() {
final n = indices.length;
final p = Float32List(n * 3),
nn = Float32List(n * 3),
t = Float32List(n * 2);
final idx = Uint32List(n);
for (var tri = 0; tri < n; tri += 3) {
final a = indices[tri] * 3,
b = indices[tri + 1] * 3,
c = indices[tri + 2] * 3;
final ux = positions[b] - positions[a],
uy = positions[b + 1] - positions[a + 1],
uz = positions[b + 2] - positions[a + 2];
final vx = positions[c] - positions[a],
vy = positions[c + 1] - positions[a + 1],
vz = positions[c + 2] - positions[a + 2];
var fx = uy * vz - uz * vy,
fy = uz * vx - ux * vz,
fz = ux * vy - uy * vx;
final len = math.sqrt(fx * fx + fy * fy + fz * fz);
if (len > 0) {
fx /= len;
fy /= len;
fz /= len;
}
for (var k = 0; k < 3; k++) {
final src = indices[tri + k];
final dst = tri + k;
p[dst * 3] = positions[src * 3];
p[dst * 3 + 1] = positions[src * 3 + 1];
p[dst * 3 + 2] = positions[src * 3 + 2];
nn[dst * 3] = fx;
nn[dst * 3 + 1] = fy;
nn[dst * 3 + 2] = fz;
t[dst * 2] = uvs[src * 2];
t[dst * 2 + 1] = uvs[src * 2 + 1];
idx[dst] = dst;
}
}
return ShapeMesh(positions: p, normals: nn, uvs: t, indices: idx);
}