Ziggurat

Ziggurats, which date to ancient Mesopotamia, are formed of tiered platforms of sun-baked bricks of successively smaller size. Ours, though lacking the substance and religious significance of their predecessors, are a bit easier to build and modify.

Ziggurat

We build a ziggurat by specifying the number of blocks, the number of sides per block, and the height of each block. The structure’s total height is equal to nbrLevels × height. The bottom block is a ruled cylinder of radius 1. The radius of each successive block is obtained by scaling the radius of the one below it by sfactor. If we assume 0 < sfactor <1, then the ziggurat shrinks with increasing height. The smaller the value of sfactor, the faster it shrinks.

function ziggurat(nbrLevels, nbrSides, height, sfactor) {
    let sf = sfactor;
    let ypos = 0.0;
    root = new THREE.Object3D();
    for (let i = 0; i < nbrLevels; i++) {
        let base = zigguratBase(nbrSides, height);
        base.position.y += ypos;
        base.scale.set(sf, 1, sf);
        root.add(base);
        ypos += height;
        sf *= sfactor;
    }
    return root;
}

The ziggurat function iteratively adds new blocks to the root node. It maintains the vertical position for the next block in the local variable ypos, and the current scale factor in sf. Note that each block (variable base) is scaled in x and z but the y scale is left unchanged: Every block has the same height. Here’s how we build each new block:

function zigguratBase(nbrSides, height) {
    let radius = 1;
    let geom = new THREE.CylinderGeometry(radius, radius, height, nbrSides);
    let matArgs = {transparent: true, opacity: 0.8, color: getRandomColor()};
    let mat = new THREE.MeshLambertMaterial(matArgs);
    let base = new THREE.Mesh(geom, mat);
    base.position.y = height / 2.0;
    return base;
}

We raise the base vertically by half its height (line 7) so that the ziggurat rests on the xz-plane.

The scene graph returned by ziggurat is shallow. The node it returns contains nbrLevel many children, one for each block.