> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.Cqt$H-sk9Lz/rev.147
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// Level-2 Mosely Fractal Assembler (modded)
// by hargsquare

// http://forum.processing.org/topic
// /rotating-a-composite-shape-made-of-many-cubes-around-a-single-center-point

import processing.opengl.*;

static final short gw  = 800/2, gh = 600/2, gd = 50;
static final byte  fps = 25;

final  color fg = color(220, 190, 0, 180);
final  color bg = color(175, 50, 50);

static final short lux = 220, luxDist = 1800, ang = 180;

static final byte  cubeSize  = 30;
static final byte  cube3Size = cubeSize*3;

static float rX = 0, rY = 0, s = 3;
static float rXInc = 1e-2f, rYInc = 9e-3f, sInc = 3e-3f;

static final byte[][] cubeCenters = {
    {-1,  0,  0}, { 1,  0,  0}, {-1,  0, -1}, 
    { 0,  0, -1}, { 1,  0, -1}, {-1,  0,  1}, 
    { 0,  0,  1}, { 1,  0,  1}, {-1,  1,  0}, 
    { 0,  1,  0}, { 1,  1,  0}, {-1, -1,  0}, 
    { 0, -1,  0}, { 1, -1,  0}, { 0,  1, -1}, 
    { 0,  1,  1}, { 0, -1, -1}, { 0, -1,  1}
};

static final byte cubeCentersLength = (byte) cubeCenters.length;

static boolean    isRunning = true;

static MoselyTwo  moselySecond;


final void setup() {
    
    size(800, 600, OPENGL);
    frameRate(fps);
    
    moselySecond = new MoselyTwo(gw, gh, gd);
}

final void draw() {
    
    background(bg);
    spotLight (lux, lux, lux, 400, 200, luxDist, 0, 0, -1, ang, 50);
    pushMatrix();
    translate(gw, gh);
    scale(s);
    rotateX(rX); rotateY(rY);
    translate(-gw, -gh);
    moselySecond.displayTwo();
    popMatrix();

    rX += rXInc; rY += rYInc; s -= sInc;
}

final void mousePressed() {

    if (isRunning = !isRunning)   loop();
    else                          noLoop();
}

final void keyPressed() {

    rXInc = -rXInc; rYInc = -rYInc; sInc = -sInc;
}

final class Cube {  
    final short cubeX, cubeY, cubeZ;  // final cube x,y,z positions relative to sponge center

    Cube(final short CubeX, final short CubeY, final short CubeZ) {
        cubeX = CubeX; cubeY = CubeY; cubeZ = CubeZ;
    }

    final void display() {
        pushMatrix();
        translate(cubeX, cubeY, cubeZ);
        fill(fg);
        box(cubeSize);
        popMatrix();
    }
}

final class MoselyOne {
    final   short spongeOneCenterX, spongeOneCenterY, spongeOneCenterZ;
    private byte  i;

    final private Cube[] cubesInOne = new Cube[cubeCentersLength];

    MoselyOne(final short SpongeOneCenterX, final short SpongeOneCenterY, final short SpongeOneCenterZ) {
        spongeOneCenterX = SpongeOneCenterX;
        spongeOneCenterY = SpongeOneCenterY;
        spongeOneCenterZ = SpongeOneCenterZ;

        for (i = 0; i < cubeCentersLength; ++i)
            cubesInOne[i] = new Cube(
            (short) (spongeOneCenterX + cubeCenters[i][0]*cubeSize), 
            (short) (spongeOneCenterY + cubeCenters[i][1]*cubeSize), 
            (short) (spongeOneCenterZ + cubeCenters[i][2]*cubeSize));
    }

    final void displayOne() {
        for (i = 0; i < cubeCentersLength; cubesInOne[i++].display());
    }
}

final class MoselyTwo {
    final   short spongeTwoCenterX, spongeTwoCenterY, spongeTwoCenterZ;
    private byte  i;

    final private MoselyOne[] spongesInTwo = new MoselyOne[cubeCentersLength];

    MoselyTwo(final short SpongeTwoCenterX, final short SpongeTwoCenterY, final short SpongeTwoCenterZ) {
        spongeTwoCenterX = SpongeTwoCenterX;
        spongeTwoCenterY = SpongeTwoCenterY;
        spongeTwoCenterZ = SpongeTwoCenterZ;

        for (i = 0; i < cubeCentersLength; ++i)
            spongesInTwo[i] = new MoselyOne(
            (short) (spongeTwoCenterX + cubeCenters[i][0]*cube3Size), 
            (short) (spongeTwoCenterY + cubeCenters[i][1]*cube3Size), 
            (short) (spongeTwoCenterZ + cubeCenters[i][2]*cube3Size));
    }

    final void displayTwo() {
        for (i = 0; i < cubeCentersLength; spongesInTwo[i++].displayOne());
    }
}