> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.9SGeuGjnQgA/rev.26
 * 
 * authors: 
 *   GoToLoop

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



/**
 * Simulation of a Universe (v3.13)
 * by  Alejandro Rodriguez (Aroxalot) (2015/Feb/28)
 * mod GoToLoop (2015/Mar/01)
 *
 * forum.Processing.org/two/discussion/9633/3d-universe-simulation-opengl
 * www.YouTube.com/watch?v=HR67FyqCwhw&feature=youtu.be
 * studio.ProcessingTogether.com/sp/pad/export/ro.9cEyzu18dPQIG/latest
 */

static final int DIM = 100, CHANCE = 500, DIAM = 5, DIFF = 3, FPS = 10;
static final float D = 2.5*DIM, RAD90 = 90*DEG_TO_RAD;

static final color[] INKS = {
  #FF0000, #008000, #0000FF
};

final byte matters[][][] = new byte[DIM][DIM][DIM];
boolean isPaused, invertRot;

void setup() {
  size(800, 800, P3D);
  noSmooth();
  noFill();
  frameRate(FPS);
  initUniverse();
}

void draw() {
  background(0);
  float xy = radians(frameCount) * (invertRot? -1 : 1);
  camera(3*DIM, D - 8*DIM*cos(xy), D - 8*DIM*sin(xy), 3*DIM, D, D, 1, 0, 0);
  renderUniverse();
}

void mousePressed() {
  if      (mouseButton == CENTER)  initUniverse();
  else if (mouseButton == RIGHT)   invertRot = !invertRot;
  else if (isPaused ^= true)       noLoop();
  else                             loop();
}

void renderUniverse() {
  for (int i = 0; i != DIM; ++i) {
    byte[][] mi = matters[i];

    for (int j = 0; j != DIM; ++j) {
      byte[] mj = mi[j];

      for (int k = 0; k != DIM; ++k) {
        byte mk = mj[k];

        int x = constrain(i + (int)random(-DIFF, DIFF), 0, DIM-1);
        int y = constrain(j + (int)random(-DIFF, DIFF), 0, DIM-1);
        int z = constrain(k + (int)random(-DIFF, DIFF), 0, DIM-1);

        if ((matters[x][y][z] = mk) >= 0)
          drawMatter(i*DIAM, j*DIAM, k*DIAM, INKS[mk]);
      }
    }
  }
}

void drawMatter(int x, int y, int z, color c) {
  fill(c);
  pushMatrix();
  translate(x, y, z);
  rotateX(RAD90);
  box(DIAM);
  popMatrix();
}

void initUniverse() {
  for (byte[][] i : matters)  for (byte[] j : i)
    for (int rnd = (int)random(CHANCE), k = 0; k != DIM
      ; j[k++] = (byte)(rnd < INKS.length? rnd : -1));
}