CylinderGeometryWireframeFriendly function

GeometryBuilder CylinderGeometryWireframeFriendly(
  1. double radTop,
  2. double radBot,
  3. double height,
  4. int radialSubdivisions
)

Like CylinderGeometry but with duplicate Vertices to make it possible to add aCenter attributes with GenerateWireframeCenters()

Implementation

GeometryBuilder CylinderGeometryWireframeFriendly(
    double radTop, double radBot, double height, int radialSubdivisions) {
  // Compute points on edges
  final double halfHeight = height / 2;
  List<VM.Vector3> top = [];
  List<VM.Vector3> bot = [];
  for (int i = 0; i < radialSubdivisions; i++) {
    double u = i / radialSubdivisions * Math.pi * 2.0;
    double x = Math.sin(u);
    double z = Math.cos(u);
    top.add(VM.Vector3(radTop * x, halfHeight, radTop * z));
    bot.add(VM.Vector3(radBot * x, -halfHeight, radBot * z));
  }
  // repeat three first point so we can safely index with +1
  top.add(top[0]);
  bot.add(bot[0]);
  assert(top.length == radialSubdivisions + 1);
  assert(bot.length == radialSubdivisions + 1);

  final VM.Vector2 zero = VM.Vector2(0.0, 0.0);
  final VM.Vector3 centerTop = VM.Vector3(0.0, halfHeight, 0.0);
  final VM.Vector3 centerBot = VM.Vector3(0.0, -halfHeight, 0.0);

  GeometryBuilder gb = GeometryBuilder();
  gb.EnableAttribute(aTexUV);

  // Q: Why do we have to repeat the vertices?
  // A: Without it example wireframe does not work
  // top and bottom are Face3
  gb.AddFaces3(2 * radialSubdivisions);
  for (int i = 0; i < radialSubdivisions; i++) {
    gb.AddVertices([centerTop, top[i], top[i + 1]]);
    gb.AddVertices([centerBot, bot[i + 1], bot[i]]);
    // TODO: fix these:
    gb.AddAttributesVector2(aTexUV, [zero, zero, zero]);
    gb.AddAttributesVector2(aTexUV, [zero, zero, zero]);
  }

  gb.AddFaces4(radialSubdivisions);
  for (int i = 0; i < radialSubdivisions; i++) {
    gb.AddVertices([top[i + 1], top[i], bot[i], bot[i + 1]]);
    // TODO: fix these:
    gb.AddAttributesVector2(aTexUV, [zero, zero, zero, zero]);
  }
  return gb;
}