IcosahedronGeometry function

GeometryBuilder IcosahedronGeometry({
  1. int subdivisions = 4,
  2. double scale = 1.0,
  3. bool computeNormals = true,
})

Implementation

GeometryBuilder IcosahedronGeometry(
    {int subdivisions = 4, double scale = 1.0, bool computeNormals = true}) {
  List<Face3> faces = [];
  List<VM.Vector3> vertices = [];

  // start with 12 vertices and 20 faces of a Icosahedron
  faces.addAll(IcosahedronFaceList);
  vertices.addAll(IcosahedronVertexList);
  //print("@@@@ ${vertices.length} ${faces.length}");

  // subdivide faces to refine the triangles
  // Each time we make 4 triangles out of one
  for (int i = 0; i < subdivisions; i++) {
    List<Face3> tmp = [];
    for (Face3 f in faces) {
      // Note: a,b,c are unit vectors
      VM.Vector3 a = VM.Vector3.copy(vertices[f.a]);
      a
        ..add(vertices[f.b])
        ..scale(0.5)
        ..normalize();
      VM.Vector3 b = VM.Vector3.copy(vertices[f.b]);
      b
        ..add(vertices[f.c])
        ..scale(0.5)
        ..normalize();
      VM.Vector3 c = VM.Vector3.copy(vertices[f.c]);
      c
        ..add(vertices[f.a])
        ..scale(0.5)
        ..normalize();
      final int ia = vertices.length;
      vertices.add(a);
      final int ib = vertices.length;
      vertices.add(b);
      final int ic = vertices.length;
      vertices.add(c);

      tmp.add(Face3(f.a, ia, ic));
      tmp.add(Face3(f.b, ib, ia));
      tmp.add(Face3(f.c, ic, ib));
      tmp.add(Face3(ia, ib, ic));
    }
    //print("@@@@ ${vertices.length} ${tmp.length}");
    faces = tmp;
  }

  GeometryBuilder gb = GeometryBuilder();
  gb.EnableAttribute(aTexUV);
  if (computeNormals) {
    gb.EnableAttribute(aNormal);
  }
  // create final vertices and uvs of a Icosahedron
  for (Face3 f in faces) {
    VM.Vector3 v1 = vertices[f.a];
    assert(v1.length < 1.01 && v1.length > 0.99);
    VM.Vector3 v2 = vertices[f.b];
    assert(v2.length < 1.01 && v2.length > 0.99);
    VM.Vector3 v3 = vertices[f.c];
    assert(v3.length < 1.01 && v3.length > 0.99);

    //print ("@ ${v1.subtract(v2).length()}");
    //print ("@ ${v2.subtract(v3).length()}");
    //print ("@ ${v3.subtract(v1).length()}");
    VM.Vector2 t1 = VM.Vector2(getU2(v1.z, v1.x), getV2(v1.y));
    VM.Vector2 t2 = VM.Vector2(getU2(v2.z, v2.x), getV2(v2.y));
    VM.Vector2 t3 = VM.Vector2(getU2(v3.z, v3.x), getV2(v3.y));
    if (computeNormals) {
      gb.AddAttributesVector3(aNormal, [v1, v2, v3]);
    }
    gb.AddVerticesFace3([v1.scaled(scale), v2.scaled(scale), v3.scaled(scale)]);
    gb.AddAttributesVector2(aTexUV, [t1, t2, t3]);
  }
  return gb;
}