Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

3D空間を飛んで移動する

f:id:aa_debdeb:20161103150131j:plain

flying in 3D world - OpenProcessing

/**
* flying in 3D world
*
* @author aa_debdeb
* @date 2016/11/12
*/

Camera cam;
ArrayList<Block> blocks;

void setup(){
  size(640, 640, P3D);
  noStroke();
  blocks = new ArrayList<Block>();
  for(int i = 0; i < 150; i++){
    blocks.add(new Block());
  }
  cam = new Camera();
}

void draw(){
  background(255);
  translate(width / 2, height / 2);
  lights();
  cam.setCamera();
  for(Block b: blocks){
    b.display();
  }
  cam.update();
}

class Block{

  PVector loc, shape;
  float rotation;
  color c;
  
  Block(){
    shape = new PVector(random(5, 40), random(50, 500), random(5, 40));
    float radius = map(sqrt(random(1)), 0, 1, 0, 600);
    float theta = random(TWO_PI);
    loc = new PVector(radius * cos(theta), -shape.y / 2 + 200, radius * sin(theta));
    rotation = random(HALF_PI);
    c = color(random(255), random(255), random(255));
  }
  
  void display(){
    fill(c);
    pushMatrix();
    translate(loc.x, loc.y, loc.z);
    rotateY(rotation);
    box(shape.x, shape.y, shape.z);
    popMatrix();
  }
}

class Camera{
  
  PVector eye;
  float eyeSpeed = 3.0;
  float centerDist = 50;
  float horizontalAng, verticalAng; 
  
  Camera(){
    eye = new PVector(0, 0, 0);
    horizontalAng = 0;
    verticalAng = 0;
  }
  
  void setCamera(){
    PVector center = new PVector(centerDist * cos(horizontalAng),
                                 centerDist * sin(verticalAng),
                                 centerDist * sin(horizontalAng));
    camera(eye.x, eye.y, eye.z, eye.x + center.x, eye.y + center.y, eye.z + center.z, 0, 1, 0);
  }
  
  void update(){
    horizontalAng += map(mouseX, 0, width, -PI / 64, PI / 64);
    if(horizontalAng < 0){horizontalAng += TWO_PI;}
    if(horizontalAng >= TWO_PI){horizontalAng -= TWO_PI;} 
    verticalAng += map(mouseY, 0, height, -PI / 64, PI / 64);
    verticalAng = constrain(verticalAng, -HALF_PI, HALF_PI);
    PVector vel = new PVector(eyeSpeed * cos(horizontalAng),
                              eyeSpeed * sin(verticalAng),
                              eyeSpeed * sin(horizontalAng));
    eye.add(vel);
  }
}