<!-- SOLID CITY · part 69 -->

    var pr = PROXY[c.hall] || [20, 18, 20];
    proxy.add(new T.BoxGeometry(pr[0], pr[1], pr[2]), c.x, Y + pr[1] / 2, c.z, 0, c.face, 0);
  });
  var tex = new T.CanvasTexture(ATL.cv); tex.encoding = T.sRGBEncoding; tex.anisotropy = 4;
  var signMat = curve(new T.MeshBasicMaterial({ map: tex }));
  var meshes = [asp.mesh(M.asphalt), gold.mesh(M.gold), red.mesh(M.red), dark.mesh(M.dark), glow.mesh(M.glow), sign.mesh(signMat), proxy.mesh(M.stone)];
  var grp = new T.Group(); grp.name = 'university-roads';
  meshes.forEach(function (m) { if (m) { m.matrixAutoUpdate = false; m.updateMatrix(); grp.add(m); } });
  A.world.add(grp); U.roads = grp;
  // collision for the arch pillars
  [-8.5, 8.5].forEach(function (o) { var x = HUB.x + hubN.x * o, z = HUB.z + hubN.z * o; A.solids.push({ x0: x - 1.1, x1: x + 1.1, z0: z - 1.1, z1: z + 1.1, y0: Y, y1: Y + 14.5, campus: true }); });
}

/* ======================= the eight landmark halls ======================= */
var PROXY = { observatory: [22, 12, 22], ziggurat: [30, 14, 30], truss: [30, 12, 18], shell: [26, 10, 18], temple: [26, 12, 14], cross: [12, 14, 28], rotunda: [22, 12, 22], towers: [8, 30, 8] };
function hallSolids(kind) {   // local boxes [cx, cz, w, d, h]
  return {
    observatory: [[0, 0, 30, 30, 26], [22, 4, 4, 4, 18]], ziggurat: [[0, 0, 40, 40, 26]], truss: [[0, -2, 40, 24, 16], [-24, -2, 8, 8, 36]],
    shell: [[0, -2, 38, 26, 18], [22, -4, 6, 12, 16]], temple: [[0, 0, 36, 22, 16]], cross: [[0, 0, 40, 14, 17], [0, 0, 14, 40, 17], [20, 14, 4, 4, 22]],
    rotunda: [[0, 0, 38, 38, 28]], towers: [[-9, -2, 12, 12, 42], [9, -2, 12, 12, 34]]
  }[kind] || [[0, 0, 24, 24, 16]];
}
function buildHall(c) {
  var M = mats(), dk = new Merger(), gd = new Merger(), rd = new Merger(), gl = new Merger(), st = new Merger(), k = c.hall, i, a;
  var B = function (m, w, h, d, x, y, z, ry) { m.add(new T.BoxGeometry(w, h, d), x, y, z, 0, ry || 0, 0); };
  var C = function (m, rt, rb, h, x, y, z, seg) { m.add(new T.CylinderGeometry(rt, rb, h, seg || 12, 1), x, y, z); };
  st.add(new T.CylinderGeometry(26, 27, 0.6, 40, 1), 0, 0.3, 0);   // plinth
  if (k === 'observatory') {
    C(dk, 14, 14, 12, 0, 6.6, 0, 28); st.add(new T.SphereGeometry(14, 28, 12, 0, Math.PI * 2, 0, Math.PI / 2), 0, 12.6, 0);
    B(rd, 2.2, 0.5, 26, 0, 25.5, 0); B(rd, 2.2, 14, 0.5, 0, 19.5, 13.2);           // the dome slit
    for (i = 0; i < 10; i++) { a = i / 10 * Math.PI * 2; B(gl, 2, 4, 0.4, Math.sin(a) * 14.1, 6, Math.cos(a) * 14.1, a); }
    C(dk, 0.5, 0.6, 16, 22, 8, 4, 8); gd.add(new T.SphereGeometry(1.4, 12, 8), 22, 18, 4);
    [0, 1.05, 2.1].forEach(function (r) { gd.add(new T.TorusGeometry(4.2, 0.14, 4, 32), 22, 18, 4, Math.PI / 2 + r * 0.6, r, 0); });
  } else if (k === 'ziggurat') {
    for (i = 0; i < 5; i++) { var w = 40 - i * 7; B(i % 2 ? dk : st, w, 5, w, 0, 2.5 + i * 5, 0); B(rd, w + 0.2, 0.25, w + 0.2, 0, 5 + i * 5, 0); }
    gd.add(new T.BoxGeometry(5, 5, 5), 0, 29, 0, Math.PI / 4, 0, Math.PI / 4);
    for (i = 0; i < 8; i++) B(gl, 1.2, 3.2, 0.3, -14 + i * 4, 3, 20.1);
    for (i = 0; i < 6; i++) B(gd, 0.6, 4 + (i * 37 % 5) * 2, 0.6, -15 + i * 6, 2 + (i * 37 % 5), 24);
  } else if (k === 'truss') {
    B(dk, 40, 14, 24, 0, 7.2, -2); B(gl, 34, 3, 0.3, 0, 9, 10.2); B(gd, 41, 0.8, 25, 0, 14.6, -2);
    for (i = -1; i <= 1; i += 2) for (var j = -1; j <= 1; j += 2) B(gd, 0.7, 36, 0.7, -24 + i * 3.4, 18, -2 + j * 3.4);
    for (i = 0; i < 9; i++) { var yy = 3 + i * 4; B(rd, 7.4, 0.35, 0.35, -24, yy, -2 + 3.4); B(rd, 7.4, 0.35, 0.35, -24, yy, -2 - 3.4); gd.add(new T.BoxGeometry(0.3, 5.6, 0.3), -24, yy + 2, -2 + 3.4, 0, 0, i % 2 ? 0.9 : -0.9); }
    gd.add(new T.TorusGeometry(10, 0.5, 6, 24, Math.PI), 6, 14.8, 12, 0, 0, 0);
  } else if (k === 'shell') {
    [[0, 14, 0], [11, 11, 0.5], [-11, 10, -0.4]].forEach(function (s) { st.add(new T.SphereGeometry(s[1], 20, 10, 0, Math.PI, 0, Math.PI / 2), s[0], 0.6, -2, 0, s[2], 0); });
    B(gl, 30, 5, 0.4, 0, 3, 8); B(dk, 38, 1.2, 22, 0, 0.9, -4);
    for (i = 0; i < 9; i++) C(gd, 0.55, 0.55, 6 + Math.abs(4 - i) * -1 + 8, 22, (6 + Math.abs(4 - i) * -1 + 8) / 2 + 0.6, -8 + i * 1.5, 10);
  } else if (k === 'temple') {
    B(st, 36, 1.2, 22, 0, 1.2, 0); B(st, 34, 1.2, 20, 0, 2.4, 0); B(dk, 26, 10, 12, 0, 8, -2); B(gl, 4, 7, 0.4, 0, 6.5, 4.1);
    for (i = 0; i < 8; i++) C(st, 0.9, 1, 10, -14 + i * 4, 8, 9, 12);
    for (i = 0; i < 4; i++) { C(st, 0.9, 1, 10, -14, 8, 5 - i * 4.5, 12); C(st, 0.9, 1, 10, 14, 8, 5 - i * 4.5, 12); }
    B(gd, 33, 1.6, 21, 0, 13.8, 0); gd.add(new T.CylinderGeometry(4.2, 4.2, 33, 3, 1), 0, 16.1, 0, 0, 0, Math.PI / 2, 1, 1, 1);
  } else if (k === 'cross') {
    B(dk, 40, 14, 14, 0, 7.6, 0); B(dk, 14, 14, 40, 0, 7.6, 0); B(st, 41, 1, 15, 0, 15, 0); B(st, 15, 1, 41, 0, 15, 0);
    B(rd, 8, 2.4, 0.5, 0, 9.5, 20.3); B(rd, 2.4, 8, 0.5, 0, 9.5, 20.3);
    for (i = 0; i < 6; i++) B(gl, 1.4, 3, 0.3, -18 + i * 7.2 + (i > 2 ? 0 : 0), 7, 7.2);
    C(dk, 0.6, 0.7, 20, 20, 10, 14, 8); for (i = 0; i < 6; i++) gd