A cube

If we can combine two triangles into a square, we should be able to use triangles to build a cube. After all, a cube is just a mesh of six squares, suitably positioned.

A cube

Not surprisingly, the code for building a cube is more complex than that of a square. One approach assembles six squares in suitable positions and orientations. But we can’t do that yet since we haven’t yet talked about transforming shapes to new positions and orientations. So we’ll go about it by constructing an array of the cube’s 8 vertices and then building 12 triangles on those vertices, 2 triangles for each of the square’s 6 faces. Here’s the code:

function createCube() {
  let geom = new THREE.Geometry();
  let coords = [-1.0, 1.0];
  // construct the 8 vertices and push them into the geometry
  for (let x = 0; x < 2; x++)
    for (let y = 0; y < 2; y++)
      for (let z = 0; z < 2; z++)
         geom.vertices.push(new THREE.Vector3(coords[x], coords[y], coords[z]));
  // construct the 12 triangles
  let faces = [[0, 6, 4], // back face triangles
               [6, 0, 2],
               [1, 7, 3], // front
               [7, 1, 5],
               [5, 6, 7], // right
               [6, 5, 4],
               [1, 2, 0], // left
               [2, 1, 3],
               [2, 7, 6], // top
               [7, 2, 3],
               [5, 0, 4], // bottom
               [0, 5, 1]];
  // push the 12 triangles into the geometry
  for (let i = 0; i < 12; i++)
    geom.faces.push(new THREE.Face3(faces[i][0], faces[i][1], faces[i][2]));
  // build an array mats of different colored materials
  let colorNames = ["red", "green", "blue", "yellow", "cyan", "magenta"];
  let mats = colorNames.map(function(c) {return new THREE.MeshBasicMaterial({color: c});});
  // assign materials to the 12 triangular faces
  for (let i = 0; i < 6; i++)
    for (let j = 0; j < 2; j++)
      geom.faces[2*i+j].materialIndex = i;
  let mesh = new THREE.Mesh(geom, mats);
  return mesh;
}

There’s quite a bit going on here. A few points. First, the 8 vertices that live in the geometry’s vertices array are implicitly number 0 through 7, based on the order they were inserted. When building the 12 triangular faces, this numbering is used to identify each triangle’s 3 vertices. For example, the first subarray [0, 6, 4] builds a triangle on vertices numbered 0, 6, and 4, which makes up half of the cube’s back face. Here’s a picture of the numbering scheme.

Vertex numbers

Second, to build the array mats of materials, we map a function over the array of color names: for each color name, we create a material of that color. (This is an example of functional programming.) Third, to assign each triangular face a material and hence a color, we assign the face’s materialIndex an index into the color. As with the vertices, materials in array mats are referred to by their position (index) in that array. As I said, there’s quite a bit going on here. But it works.