// flying through a world of slowly shifting blocks
import processing.opengl.*;
// I dont think this is in the default download
import oscP5.*;
import netP5.*;
// keeping track of time for ourselves
int globalClock;
// number of blocks in the space
int totalBlocks = 400;
// these are the variables set buy the incoming osc messages
float mainAxisX, mainAxisY, mainAxisZ, mainAxisThrottle;
// the matrix for the camera
PMatrix3D cam;
// for the location of the camera in the world
PVector loc;
// the osc receiver object
OscP5 oscP5;
// the blocks object array of Bloxen
Bloxen[] theblocks = new Bloxen[totalBlocks];
//
-------------------------------------------------------------------------
void setup() {
size(800, 600, OPENGL);
smooth();
hint(ENABLE_OPENGL_4X_SMOOTH);
frameRate(30);
// This is to set the clipping plane closer than default
float fov = PI/3.0;
float cameraZ = (height/2.0) / tan(fov/2.0);
perspective(fov, float(width)/float(height),
cameraZ/100.0, cameraZ*10.0);
// initiate the bloxen
for ( int x = 0; x < totalBlocks; x++ ) {
theblocks[x] = new Bloxen(random(-200, 200), random(-200, 200),
random(-200,200));
theblocks[x].bloxColor = color(random(255), random(255),
random(255));
}
// setting up the matrx and vector
cam = new PMatrix3D();
loc = new PVector(0,0,0);
// the osc receiver
oscP5 = new OscP5(this,12345);
// sets things to stillness when launching.
mainAxisX = mainAxisY = mainAxisZ = mainAxisThrottle = 0.5;
globalClock = 0;
}
void draw(){
// just habit.
globalClock+=1;
cam.rotateX(-(mainAxisX - 0.5) / 20);
cam.rotateY((mainAxisZ - 0.5) / 20);
cam.rotateZ((mainAxisY - 0.5) / 20);
// I still don't really understand these three lines gleaned from:
//
http://processing.org/discourse/yabb2/YaBB.pl?num=1242982102
PVector x = cam.mult(new PVector(1, 0, 0), new PVector(0,0,0));
PVector y = cam.mult(new PVector(0, 1, 0), new PVector(0,0,0));
PVector d = x.cross(y); d.normalize();
background(0);
noStroke();
// set the location to be moved by the throttle in the direction of
the camera vector!
loc.x -= d.x * ((mainAxisThrottle - 0.5) * 10);
loc.y -= d.y * ((mainAxisThrottle - 0.5) * 10);
loc.z -= d.z * ((mainAxisThrottle - 0.5) * 10);
camera(0, 0, 0, d.x, d.y, d.z, y.x, y.y, y.z);
// translate the world!
pushMatrix();
translate(loc.x, loc.y, loc.z);
// sets background of the world to throbbing colors
background(192 + (64*cos(radians(globalClock%360))),
192 + (64*cos(radians((globalClock*2.103029)%360))),
192 + (64*cos(radians((globalClock*3.22144)%360)))
);
fill(255);
stroke(0);
strokeWeight(2);
// randomly set some blocks to have new targets
for ( int w = 0; w < totalBlocks; w++ ) {
if(random(1,400) < 2) {
theblocks[w].xtarget += random(-40,40);
}
if(random(1,400) < 2) {
theblocks[w].ytarget += random(-40,40);
}
if(random(1,400) < 2) {
theblocks[w].ztarget += random(-40,40);
}
theblocks[w].update();
theblocks[w].draw();
}
// end of everything
popMatrix();
}
// ------------------------------------------------------- Bloxen
class
class Bloxen {
float xpos, ypos, zpos, xtarget, ytarget, ztarget;
color bloxColor = color(255,0,0);
float bloxSize;
float speed = 0.01;
Bloxen(float x, float y, float z) {
xtarget = xpos = x; ytarget = ypos = y; ztarget = zpos = z;
bloxSize = random(1,30);
}
void update() {
// moving towards target positions.
// the ifs apparently save time in easing, instead of doing the
math on every object every frame
if ( abs(xtarget - xpos) > 0.1) {
xpos += (xtarget - xpos) * speed;
}
if ( abs(ytarget - ypos) > 0.1) {
ypos += (ytarget - ypos) * speed;
}
if ( abs(ztarget - zpos) > 0.1) {
zpos += (ztarget - zpos) * speed;
}
}
void draw() {
pushMatrix();
fill(bloxColor);
translate(xpos, ypos, zpos);
// when doing teapots, this was a loaded obj object told to draw
box(bloxSize);
popMatrix();
}
}
// handle the OSC events for control
// the incoming values will be from 0-1. controls at rest = 0.5.
void oscEvent(OscMessage theOscMessage) {
if(theOscMessage.checkAddrPattern("/mainAxisX")==true) {mainAxisX =
theOscMessage.get(0).floatValue(); }
if(theOscMessage.checkAddrPattern("/mainAxisY")==true) {mainAxisY =
theOscMessage.get(0).floatValue(); }
if(theOscMessage.checkAddrPattern("/mainAxisZ")==true) {mainAxisZ =
theOscMessage.get(0).floatValue(); }
if(theOscMessage.checkAddrPattern("/mainAxisThrottle")==true)
{mainAxisThrottle = theOscMessage.get(0).floatValue();}
}