harsh-Body

1. Wolly-Willy

This was a reference to the children's toy Wolly-Willy, but done in a digital format.

2. Beard of Boids

Here's a beard made out of tiny hair follicles that behave like boids.

3. Animate Artworks

Here I tried to bring to life already made artwork - I liked the recursion in the Dali piece and how computation enabled changing it dynamically.

Bonus: Here's one with Mona-Lisa

 

Code: Wolly Willy

//
// a template for receiving face tracking osc messages from
// Kyle McDonald's FaceOSC https://github.com/kylemcdonald/ofxFaceTracker
//
// 2012 Dan Wilcox danomatika.com
// for the IACD Spring 2012 class at the CMU School of Art
//
// adapted from from Greg Borenstein's 2011 example
// http://www.gregborenstein.com/
// https://gist.github.com/1603230
//
import oscP5.*;
OscP5 oscP5;
import processing.video.*;
 
 
// num faces found
int found;
 
float[] rawArray;
 
// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();
 
int numPoints = 4000;
Vehicle[] vehicles;
PVector[] lowPoints;
 
float prevMouseX;
float prevMouseY;
 
PImage img;
PImage lightOff;
PImage lightOn;
Capture cam;
 
float mappedPoseScale;
 
float[][] mouseCircle;
 
float[][] setupPoints;
float[][] centDist;
 
String mode;
 
void setup() {
  size(640, 480);
  frameRate(30);
  rawArray = new float[132];
  cam = new Capture(this, 640, 480, 30);
  cam.start();
  img = loadImage("hair.png");
  lightOff = loadImage("lightoff.png");
  lightOn = loadImage("lighton.png");
 
 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "rawData", "/raw");
  oscP5.plug(this, "poseScale", "/pose/scale");
  oscP5.plug(this, "posePosition", "/pose/position");
  oscP5.plug(this, "poseOrientation", "/pose/orientation");
 
  vehicles = new Vehicle[numPoints];
  lowPoints = new PVector[numPoints];
  initializeVehicles();
 
  setupPoints = new float[numPoints][2];
  centDist = new float[numPoints][2];
 
  mode = "setup";
}
 
void draw() {  
  //println(posePosition.x,posePosition.y);
  background(255);
  stroke(0);  
  mappedPoseScale = map(poseScale,0,6,0,1);
 
  if(keyPressed){
    if(key == ' '){
      mode = "follow";
    }
    if(key == 'r'){
      mode = "reset";
    }
  }
 
 ////////////////////// DISPLAY WEBCAM IMAGE //////////////////////
  if(cam.available()) {
    cam.read();
  }
  image(cam,0,0);
  //////////////////////////////////////////////////////////////////
  if(mode == "setup"){  
    mouseCircle = getCirclePoints(30, mouseX, mouseY);   
 
    moveBoidsInside(mouseCircle, mouseX,mouseY,30);
    for(int i=0; i<numPoints; i++){
      float[] curLoc = new float[2];
      curLoc[0] = vehicles[i].location.x;
      curLoc[1] = vehicles[i].location.y;
 
      float[] curDist = new float[2];
      curDist[0] = vehicles[i].location.x-posePosition.x;
      curDist[1] = vehicles[i].location.y-posePosition.y;   
      setupPoints[i] = curLoc;
      centDist[i] = curDist;
    }
    //if(mousePressed){ 
    //    image(lightOn,mouseX,mouseY);
    //}
    //else{
    //    image(lightOff,mouseX,mouseY);
    //}
  }
 
 
  if(mode == "follow" && found != 0){
    for(int i=0; i<numPoints; i++){
      Vehicle curBoid = vehicles[i];
      float[] curBoidLoc = new float[2];
      curBoidLoc[0] = curBoid.location.x;
      curBoidLoc[1] = curBoid.location.y;
      curBoid.maxspeed = 5;
      curBoid.maxforce = 0.2;
 
      if(curBoid.location.y < height-60){
        PVector newLoc = new PVector(posePosition.x+centDist[i][0]*mappedPoseScale,posePosition.y+centDist[i][1]*mappedPoseScale);
        //println(newLoc);
        curBoid.arrive(newLoc);
        curBoid.update();
        curBoid.display();
      }
    }
  }
 
  if(mode == "reset"){
    int num = 0;
    for(int i=0; i< numPoints; i++){
      Vehicle curBoid = vehicles[i];
      curBoid.maxspeed = 50;
      curBoid.maxforce = 10;
      curBoid.jiggleRadius = 1;
      curBoid.arrive(lowPoints[i]);
      curBoid.update();
      curBoid.display();
      if((curBoid.location.y-lowPoints[i].y) < 2){ num++; } } if(num >= numPoints){
        mode = "setup";
      }
  }
 
}
 
 
 
////////////////////////////////////////////////////////////////////////
/////////////////////Vehicle Settings //////////////////////////////////
////////////////////////////////////////////////////////////////////////
 
void initializeVehicles(){
  for(int i=0; i<numPoints; i++){
    PVector pos = new PVector(random(width), random(height-30,height));
    lowPoints[i] = pos;
    Vehicle new_vehicle = new Vehicle(pos.x,pos.y);
    vehicles[i] = new_vehicle;
  }
}
 
void jiggle(){
  for(int i=0; i<numPoints; i++){
    Vehicle v = vehicles[i];
    v.arrive(v.location);
    v.update();
    v.display();
  }
}
 
void display(){
    for(int i=0; i<numPoints; i++){
    Vehicle v = vehicles[i];
    v.update();
    v.display();
  }
}
 
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
 
// OSC CALLBACK FUNCTIONS
 
public void found(int i) {
  //println("found: " + i);
  found = i;
}
 
public void poseScale(float s) {
  //println("scale: " + s);
  poseScale = s;
}
 
public void posePosition(float x, float y) {
  //println("pose position\tX: " + x + " Y: " + y );
  posePosition.set(x, y, 0);
}
 
public void poseOrientation(float x, float y, float z) {
  //println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
  poseOrientation.set(x, y, z);
}
 
public void rawData(float[] raw) {
  rawArray = raw; // stash data in array
}
 
// all other OSC messages end up here
void oscEvent(OscMessage m) {
  if(m.isPlugged() == false) {
    //println("UNPLUGGED: " + m);
  }
}

Code: Artwork

 

// Processing 3.0x template for receiving raw points from
// Kyle McDonald's FaceOSC v.1.1 
// https://github.com/kylemcdonald/ofxFaceTracker
//
// Adapted by Kaleb Crawford and Golan Levin, 2016-7, after:
// 2012 Dan Wilcox danomatika.com
// for the IACD Spring 2012 class at the CMU School of Art
// adapted from from Greg Borenstein's 2011 example
// https://gist.github.com/1603230
 
import oscP5.*;
OscP5 oscP5;
int found;
float[] rawArray;
int highlighted; //which point is selected
float poseScale;
 
PImage background;
PImage mouth;
PImage left_eyebrow;
PImage right_eyebrow;
PImage small_eyebrows;
PImage smallest_eyebrows;
PImage eyes;
 
 
 
float mouthOff;
 
float rightBrowOff;
float leftBrowOff;
float smallBrowOff;
 
float prevRightBrowOff;
float prevLeftBrowOff;
float mappedScale;
 
//--------------------------------------------
void setup() {
  size(800, 682);
  frameRate(30);
 
  rawArray = new float[132]; 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "rawData", "/raw");
  oscP5.plug(this, "poseScale", "/pose/scale");
 
  background = loadImage("base.png");
  mouth = loadImage("mouths.png");
  left_eyebrow = loadImage("left eyebrow.png");
  right_eyebrow = loadImage("right eyebrow.png");
  small_eyebrows = loadImage("small eyebrows.png");
  eyes = loadImage("eyes.png");
  smallest_eyebrows = loadImage("smallest eyebrows.png");
 
 
}
 
//--------------------------------------------
void draw() {  
  mappedScale = map(poseScale, 0,5,0,1);
 
  prevRightBrowOff = rightBrowOff;
  prevLeftBrowOff = leftBrowOff;
 
  rightBrowOff = (getLeftBrowHeight());
 
  leftBrowOff =  (getRightBrowHeight());
 
  smallBrowOff = (getRightBrowHeight());
 
  image(background, 0, 0);
 
  pushMatrix();
  translate(0,-(rightBrowOff*2));
  image(left_eyebrow, 0, -2);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff*8));
  image(right_eyebrow, 0, 0);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff));
  image(small_eyebrows, 0, 0);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff*0.5));
  image(smallest_eyebrows, 0, 0);
  popMatrix();
 
  if(leftEyeClosed() || rightEyeClosed()){
    image(eyes, 0, 0);
  }
 
  pushMatrix();
  tint(255, 300-(getMouthMovement())*5);
  image(mouth, 0, 0);
  popMatrix();
 
 
 
 
}
 
//--------------------------------------------
void drawFacePoints() {
  int nData = rawArray.length;
  for (int val=0; val<nData; val+=2) {
    if (val == highlighted) { 
      fill(255, 0, 0);
      ellipse(rawArray[val], rawArray[val+1], 11, 11);
    } else {
      fill(100);
      ellipse(rawArray[val], rawArray[val+1], 8, 8);
    }
  }
}
 
//--------------------------------------------
void drawFacePolygons() {
  noFill(); 
  stroke(100); 
 
  // Face outline
  beginShape();
  for (int i=0; i<34; i+=2) { vertex(rawArray[i], rawArray[i+1]); } for (int i=52; i>32; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Eyes
  beginShape();
  for (int i=72; i<84; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
  beginShape();
  for (int i=84; i<96; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Upper lip
  beginShape();
  for (int i=96; i<110; i+=2) { vertex(rawArray[i], rawArray[i+1]); } for (int i=124; i>118; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Lower lip
  beginShape();
  for (int i=108; i<120; i+=2) { vertex(rawArray[i], rawArray[i+1]); } vertex(rawArray[96], rawArray[97]); for (int i=130; i>124; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Nose bridge
  beginShape();
  for (int i=54; i<62; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape();
 
  // Nose bottom
  beginShape();
  for (int i=62; i<72; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape();
}
 
 
//--------------------------------------------
public void found(int i) {
  found = i;
}
public void rawData(float[] raw) {
  rawArray = raw; // stash data in array
}
 
public void poseScale(float s) {
  //println("scale: " + s);
  poseScale = s;
}
 
//--------------------------------------------
void keyPressed() {
  int len = rawArray.length; 
  if (keyCode == RIGHT) {
    highlighted = (highlighted + 2) % len;
  }
  if (keyCode == LEFT) {
    highlighted = (highlighted - 2 + len) % len;
  }
}