topical media & game development

talk show tell print

graphic-processing-site-examples-3D-Transform-PushPopCubes-PushPopCubes.pde / pde



  
PushPop Cubes by Ira Greenberg. Array of rotating cubes creates dynamic field patterns. Color controlled by light sources. Example of pushMatrix() and popMatrix().

  
  
  // Cube class required
  float ang;
  int rows = 21;
  int cols = 21;
  int cubeCount = rows*cols;
  int colSpan, rowSpan;
  float rotspd = 2.0;
  Cube[] cubes = new Cube[cubeCount];
  float[] angs = new float[cubeCount];
  float[] rotvals = new float[cubeCount];
  
  void setup(){
    size(640, 360, P3D);
  
    colSpan = width/(cols-1);
    rowSpan = height/(rows-1);
    noStroke(); 
  
    // instantiate cubes
    for (int i = 0; i < cubeCount; i++){
      cubes[i] = new Cube(12, 12, 6, 0, 0, 0);
      /* 3 different rotation options
         - 1st option: cubes each rotate uniformly
         - 2nd option: cubes each rotate randomly
         - 3rd option: cube columns rotate as waves
         To try the different rotations, leave one 
         of the rotVals[i] lines uncommented below
         and the other 2 commented out. */
      
      //rotvals[i] = rotspd;
      //rotvals[i] = random(-rotspd * 2, rotspd * 2);
      rotvals[i] = rotspd += .01;
    }
  }
  
  void draw(){
    int cubeCounter = 0;
    background(0);
    fill(200);
    
    // Set up some different colored lights
    pointLight(51, 102, 255, width/3, height/2, 100); 
    pointLight(200, 40, 60,  width/1.5, height/2, -150);
  
    // Raise overall light in scene 
    ambientLight(170, 170, 100); 
  
    // Translate, rotate and draw cubes
    for (int i = 0; i < cols; i++){
      for (int j = 0; j < rows; j++){
        pushMatrix();
        /* Translate each block.
           pushmatix and popmatrix add each cube
           translation to matrix, but restore
           original, so each cube rotates around its
           owns center */
        translate(i * colSpan, j * rowSpan, -20);
        //rotate each cube around y and x axes
        rotateY(radians(angs[cubeCounter]));
        rotateX(radians(angs[cubeCounter]));
        cubes[cubeCounter].drawCube();
        popMatrix();
        cubeCounter++;
      }
    }
    // Angs used in rotate function calls above
    for (int i = 0; i < cubeCount; i++){
      angs[i] += rotvals[i];
    }
  }
  
  // Simple Cube class, based on Quads
  class Cube {
  
    // Properties
    int w, h, d;
    int shiftX, shiftY, shiftZ;
  
    // Constructor
    Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){
      this.w = w;
      this.h = h;
      this.d = d;
      this.shiftX = shiftX;
      this.shiftY = shiftY;
      this.shiftZ = shiftZ;
    }
  
    /* Main cube drawing method, which looks 
       more confusing than it really is. It's 
       just a bunch of rectangles drawn for 
       each cube face */
    void drawCube(){
      
      // Front face
      beginShape(QUADS);
      vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); 
      vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); 
  
      // Back face
      vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); 
      vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); 
      vertex(w + shiftX, h + shiftY, d + shiftZ); 
      vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
  
      // Left face
      vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); 
      vertex(-w/2 + shiftX, h + shiftY, d + shiftZ); 
      vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); 
  
      // Right face
      vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); 
      vertex(w + shiftX, h + shiftY, d + shiftZ); 
      vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); 
  
      // Top face
      vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, -h/2 + shiftY, d + shiftZ); 
      vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ); 
  
      // Bottom face
      vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, h + shiftY, -d/2 + shiftZ); 
      vertex(w + shiftX, h + shiftY, d + shiftZ); 
      vertex(-w/2 + shiftX, h + shiftY, d + shiftZ); 
      endShape(); 
    }
  }
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.