buildMesh method
Its triangles, textured by uv.
Implementation
@override
ShapeMesh buildMesh([ShapeUv uv = ShapeUv.natural]) {
final (cx, cy) = _centre;
final hz = Primitive3D.size(depth) / 2;
final n = _steps;
final b = MeshBuilder(uv);
(double, double, double) at(int i, double r, double z) {
final a = _at(i);
return (r * math.cos(a) - cx, -r * math.sin(a) - cy, z);
}
// The curved faces: outside facing out, inside facing the middle.
for (final (r, out) in [(_outer, 1.0), (_inner, -1.0)]) {
if (r <= 0) continue;
final first = b.vertexCount;
final length = uv.anyway(r * _angle);
for (var i = 0; i <= n; i++) {
final a = _at(i);
final nx = math.cos(a) * out, ny = -math.sin(a) * out;
for (final z in [-hz, hz]) {
final (x, y, _) = at(i, r, z);
final u = uv.metres ? length * i / n : i / n;
final v = uv.metres ? z * uv.sz + hz * uv.sz : (z + hz) / (2 * hz);
b.vertex(x, y, z, nx, ny, 0, u, v);
}
}
for (var i = 0; i < n; i++) {
final a = first + i * 2;
b.quad(a, a + 1, a + 3, a + 2);
}
}
// Front and back.
for (var i = 0; i < n; i++) {
for (final z in [-hz, hz]) {
b.face(
[
at(i, _inner, z),
at(i, _outer, z),
at(i + 1, _outer, z),
at(i + 1, _inner, z),
],
0,
0,
z < 0 ? -1 : 1,
);
}
}
// Its two ends.
if (!_closed) {
for (final (i, sign) in [(0, 1.0), (n, -1.0)]) {
final a = _at(i);
b.face(
[
at(i, _inner, -hz),
at(i, _outer, -hz),
at(i, _outer, hz),
at(i, _inner, hz),
],
math.sin(a) * sign,
math.cos(a) * sign,
0,
);
}
}
final mesh = b.build();
return smooth ? mesh : mesh.faceted();
}