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]
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]);
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *