topical media & game development
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.