//corneel cannaerts 2010
//www.introspector.be
//import libraries
import peasy.*;
import processing.opengl.*;
//global variables
String[] strNodes;
String[] strLinks;
String[] strTriangles;
Node[] nodes;
Link[] links;
Triangle[] triangles;
PeasyCam cam;
PFont font;
float t = 0;
float r = 0.5;
float waveScaleX = 0.005;
float waveScaleY = 0.0080;
boolean timer;
boolean drawNod=true;
boolean drawId=false;
boolean drawLin=true;
boolean drawBas=true;
boolean drawTri=true;
//setup function, runs once at the beginning
void setup() {
size(900,500,OPENGL);
smooth();
curveTightness(0.5);
cam = new PeasyCam(this,455,300,0,600);
font = loadFont("LucidaConsole-16.vlw");
textFont(font, 16);
initMesh();
}
//draw function, runs continiuosly
void draw() {
background(0);
lights();
//update and draw the nodes
for(int i=0; i<nodes.length; i++) {
nodes[i].update();
if(drawNod)nodes[i].render();
if(drawId) nodes[i].renderId();
}
//update and draw the links
for(int i=0; i<links.length; i++) {
links[i].update();
if(drawLin)links[i].render();
if(drawBas)links[i].renderBase();
}
//update and draw the triangles
for(int i=0; i<triangles.length; i++) {
if(drawTri)triangles[i].render();
}
//advance timer
if(timer)t += 5;
}
void initMesh() {
//loads data from textfiles and generate geometry
//initialise nodes
strNodes = loadStrings("nodes.txt");
nodes = new Node[strNodes.length];
for (int i=0; i < strNodes.length; i++) {
float[] coord = float(split(strNodes[i], ','));
nodes[i] = new Node(coord[1],coord[2],140*noise(coord[1]*waveScaleX,coord[2]*waveScaleY,t),i);
}
//initialise links
strLinks = loadStrings("links.txt");
links = new Link[strLinks.length];
for (int i=0; i < strLinks.length; i++) {
int[] index = int(split(strLinks[i], ','));
links[i] = new Link(nodes[index[0]],nodes[index[1]]);
}
//initialise triangles
strTriangles = loadStrings("triangles.txt");
triangles = new Triangle[strTriangles.length];
for (int i=0; i < strTriangles.length; i++) {
int[] index = int(split(strTriangles[i], ','));
triangles[i] = new Triangle(nodes[index[0]],nodes[index[1]],nodes[index[2]]);
}
}
// keyboard control
void keyPressed() {
if (key == 's' || key == 'S') {
//saveFrame("kinetic-####" + random(1000)+".tif");
}
else if (key == 'p' || key == 'P') {
timer = !timer;
}
else if (key == 'n' || key == 'N') {
drawNod = !drawNod;
}
else if (key == 'i' || key == 'I') {
drawId = !drawId;
}
else if (key == 'l' || key == 'L') {
drawLin = !drawLin;
}
else if (key == 'b' || key == 'B') {
drawBas = !drawBas;
}
else if (key == 't' || key == 'T') {
drawTri = !drawTri;
}
else if (key == 'o' || key == '0') {
if(r<1) r += 0.01;
println(r);
}
else if (key == 'c' || key == 'C') {
if(r>0) r -= 0.01;
println(r);
}
}
//node or vertex class
class Node {
PVector pos;
int id;
Node (float x, float y, float z,int id) {
this.pos = new PVector(x,y,z);
this.id = id;
}
void update() {
//pos.z = 70 + 70*sin((pos.x+t)*waveScaleX);
pos.z = 70 + 35*sin((pos.x+t)*waveScaleX) + 35*sin((pos.y+t)*waveScaleY);
//pos.z = dist(pos.x,pos.y,mouseX,mouseY)*0.1;
//pos.z = random(140);
}
void render() {
stroke(255,100);
strokeWeight(0.5);
pushMatrix();
float z = constrain(pos.z,0,140);
translate(pos.x,pos.y,z);
ellipse(0,0,5,5);
line(0,0,0,0,0,-pos.z);
popMatrix();
}
void renderId() {
fill(255);
pushMatrix();
float z = constrain(pos.z,0,140);
translate(pos.x,pos.y,z);
text(id, 10,5);
popMatrix();
}
}
//link or edge class
class Link {
Node a, b;
float za, zb;
Link (Node a, Node b) {
this.a = a;
this.b = b;
}
void update() {
za = constrain(a.pos.z,0,140);
zb = constrain(b.pos.z,0,140);
}
void render() {
strokeWeight(2);
stroke(255,200);
line(a.pos.x,a.pos.y,za,b.pos.x,b.pos.y,zb);
}
void renderBase() {
stroke(255,100);
strokeWeight(0.5);
line(a.pos.x,a.pos.y,0,b.pos.x,b.pos.y,0);
}
}
//triangle or face class
class Triangle {
Node a, b, c;
Triangle (Node a, Node b, Node c) {
this.a = a;
this.b = b;
this.c = c;
}
void render() {
fill(200,150,150);
stroke(255,0,0);
PVector center;
center = PVector.add(a.pos, b.pos);
center.add(c.pos);
center.mult(0.3333);
center.add(new PVector(0,0,50));
ellipse(center.x,center.y,4,4);
center.mult(r);
PVector pa = a.pos.get();
pa.mult(1-r);
PVector ca = PVector.add(pa,center);
PVector pb = b.pos.get();
pb.mult(1-r);
PVector cb = PVector.add(pb,center);
PVector pc = c.pos.get();
pc.mult(1-r);
PVector cc = PVector.add(pc,center);
beginShape();
vertex(a.pos.x, a.pos.y, a.pos.z);
bezierVertex(ca.x, ca.y, ca.z, cb.x, cb.y, cb.z, b.pos.x, b.pos.y, b.pos.z);
bezierVertex(cb.x, cb.y, cb.z, cc.x, cc.y, cc.z, c.pos.x, c.pos.y, c.pos.z);
bezierVertex(cc.x, cc.y, cc.z, ca.x, ca.y, ca.z, a.pos.x, a.pos.y, a.pos.z);
endShape();
}
}
Processing sketch for Kinetic Pavillion (http://www.kineticpavilion.com/) by Elise Elsacker and Yannick Bontinckx.
peasyCam for camera
p = pause
n = draw nodes
i = draw ids
l = draw lines
b = draw base
t = draw triangles
r = open
c = close
actual UDP code has been removed in online version