float zlen = 900, blockSize = 10; ArrayList nodes = new ArrayList(); ArrayList cubes = new ArrayList(); PVector cam = new PVector(); void setup() { size(900, 500, P3D); hint(DISABLE_DEPTH_TEST); for (int i = 0; i < 100; i++) nodes.add(new Node()); smooth(); } void draw() { background(0, 20, 40); cam.x += mouseX < width / 2 ? -0.1 : 0.1; cam.y += mouseY < height / 2 ? -0.1 : 0.1; pushMatrix(); translate(width/2, height/2, zlen/2 + -700); rotateX(radians(-cam.y)); rotateY(radians(cam.x)); for(Node node : nodes) node.display(); for(int i = 0; i < cubes.size(); i++) if (!cubes.get(i).display()) cubes.remove(i--); popMatrix(); } class Cube { PVector loc; int initFrame = 0; Cube(PVector _loc, int fr) { loc = new PVector(_loc.x, _loc.y, _loc.z); initFrame = fr; } boolean display() { if (frameCount > initFrame) { float life = sin((frameCount-initFrame)*0.05); if (life < 0) return false; //Delete when non visible stroke(lerpColor(color(0, 0, 50, 10), color(255, 255, 255, 30), life)); strokeWeight(3); noFill(); pushMatrix(); translate(loc.x-width/2, loc.y-height/2, loc.z-zlen/2); box(blockSize*2); popMatrix(); } return true; } } class Node { PVector loc = new PVector(random(0.0, width), random(0.0, height), random(0.0, zlen)), dir = PVector.random3D(); float speed = random(-.5, 2.0); void display() { dir.div(dir.mag()); //normalize loc.add(PVector.mult(new PVector(dir.x,dir.y,dir.z), speed)); //move if (loc.x < 0 || loc.x > width) { dir.x *= -1; spawnCube(loc, new int[]{0,1,1}); } if (loc.y < 0 || loc.y > height) { dir.y *= -1; spawnCube(loc, new int[]{1,0,1}); } if (loc.z < 0 || loc.z > zlen) { dir.z *= -1; spawnCube(loc, new int[]{1,1,0}); } ArrayList neighbors = new ArrayList(); for (Node o : nodes) if (this != o && PVector.dist(loc, o.loc) < 120) neighbors.add(o); pushMatrix(); translate(-width/2, -height/2, -zlen/2); if (neighbors.size() > 0) { float lerpV = constrain(map(neighbors.size(), 0, 6, 0.0, 1.0), 0.0, 1.0); color col = lerpColor(color(0, 255, 255, 100), color(255, 0, 255, 100), lerpV); stroke(col); // Draw line for (Node o : neighbors) line(loc.x, loc.y, loc.z, o.loc.x, o.loc.y, o.loc.z); pointColorWeight(color(120, 120, 190, 20), neighbors.size()*10, loc.x, loc.y, loc.z); pointColorWeight(col,neighbors.size()*4,loc.x, loc.y, loc.z); pointColorWeight(255,neighbors.size(),loc.x, loc.y, loc.z); } pointColorWeight(255,1,loc.x, loc.y, loc.z); speed = constrain(speed * ((neighbors.size() > 2) ? 0.96 : 1.02), 0.20, 7); popMatrix(); } } void pointColorWeight(color c, float weight, float x, float y, float z) { stroke(c); strokeWeight(weight); point(x,y,z); } void spawnCube(PVector pos, int[] axis) {//String[] axis) { PVector loc = new PVector(pos.x, pos.y, pos.z); for (int i = 0, n = (int)random(2, 10); i < n; i++) { cubes.add(new Cube(new PVector(loc.x, loc.y, loc.z), frameCount+6*i)); loc.add( (random(0, 2)<1 ? -1:1)*blockSize*2 * axis[0], (random(0, 2)<1 ? -1:1)*blockSize*2 * axis[1], (random(0, 2)<1 ? -1:1)*blockSize*2 * axis[2]); } }
Processing 3D demo
The mouse position controls the rotation around the scene.
The main idea of the demo is there are little dots that bounce in a three-dimensional rectangular space. When the dots hit the walls, a series of tiny cubes are generated in a sequence, which slowly disappear. If the dots are close to other dots, then they slow down, and otherwise they speed up. When dots are very close to other dots, two additional effects are drawn: a line connecting the dot to its neighbors, and a pink and white translucent circle is drawn around the dot that grows as it gains more neighbors. The whole scene rotates in 3D based off of your mouse position, which is the only input that the user can provide.
[raw]
[/raw]