// Spyrofoam
// Dave Bollinger, Oct 2006
// http://www.davebollinger.com
// rewritten for Processing Beta 0119
/**
Press spacebar to generate new attractor
Quality Mode:
1: render with points (aka "explore" mode) (default)
2: render with rectangles (aka "billboard" mode)
3: render with boxes (aka "draft" mode)
4: render with spheres (aka "final" mode)
fast CPU recommended for modes 3 & 4
'[' ']' decrease/increase sphere radius
Camera:
drag mouse to rotate
arrow keys to pan
+/- keys to zoom
'x' resets camera to default
NOTE: most changes in settings will erase
the screen and restart the accumulation.
*/
IfsSystem ifs;
static final int rmPOINTS = 0;
static final int rmRECTS = 1;
static final int rmBOXES = 2;
static final int rmSPHERES = 3;
int renderMode = rmPOINTS;
float sphereSize = 4.0;
float rotationX, rotationY;
float cameraX, cameraY, cameraZ;
int mouseDownX, mouseDownY;
boolean bNeedErase = false;
void setup() {
size(300, 300, P3D);
sphereDetail(8);
ifs = new IfsSystem(6);
next();
}
void next() {
do {
ifs.create();
} while (!ifs.valid());
cameraReset();
}
void draw() {
if (bNeedErase) {
background(#ffffff);
bNeedErase = false;
}
colorMode(RGB);
directionalLight(255,255,255, 0.5,0.5,-0.5);
pointLight(255,255,255, 0,0,0);
translate(width/2+cameraX, height/2+cameraY, cameraZ);
scale(width/ifs.ex.width);
rotateX(rotationX);
rotateY(rotationY);
colorMode(HSB);
ifs.iterate(10,200,1000);
}
void keyPressed() {
if (key==' ') next();
if (key=='1') setQuality(rmPOINTS);
if (key=='2') setQuality(rmRECTS);
if (key=='3') setQuality(rmBOXES);
if (key=='4') setQuality(rmSPHERES);
if (key=='[') sphereResize(-0.5);
if (key==']') sphereResize(0.5);
if (keyCode==LEFT) cameraMove(5,0,0);
if (keyCode==RIGHT) cameraMove(-5,0,0);
if (keyCode==UP) cameraMove(0,5,0);
if (keyCode==DOWN) cameraMove(0,-5,0);
if (key=='+') cameraMove(0,0,5);
if (key=='-') cameraMove(0,0,-5);
if (key=='x') cameraReset();
}
void mouseDragged() {
float rx = (mouseDownY-mouseY) / float(height) * TWO_PI;
float ry = (mouseX-mouseDownX) / float(width) * TWO_PI;
rotationX += (rx - rotationX) * 0.1;
rotationY += (ry - rotationY) * 0.1;
bNeedErase = true;
}
void mousePressed() {
mouseDownX = mouseX;
mouseDownY = mouseY;
}
// cheap pseudo-camera support
void cameraReset() {
cameraX = cameraY = 0.0;
cameraZ = ifs.ex.minz - 200.0;
rotationX = rotationY = 0.0;
bNeedErase = true;
}
void cameraMove(float dx, float dy, float dz) {
cameraX += dx;
cameraY += dy;
cameraZ += dz;
bNeedErase = true;
}
void sphereResize(float ds) {
sphereSize += ds;
sphereSize = min(max(sphereSize,1.0),20.0);
bNeedErase = true;
}
void setQuality(int q) {
renderMode = q;
bNeedErase = true;
}