Bueno

28 Jan 2013

rainbowVomit from Andrew Bueno on Vimeo.

After talking about my old waterboarding clock processing app in class the other day, I got a bit nostalgic for that old, lo-fi aesthetic. Thus, the crapsaccharine rainbow vomit app. I hooked up the FaceOSCSyphon app to Dan’s FaceOSC template for processing. I kept track mainly of the mouth. When its tracking points become wide enough apart, the vomit begins. It quite a bit of figuring out – Caroline Record was a huge help. Another source of help was a fellow on openProcessing – he is properly credited in my code. Without him, the app wouldn’t have that special brand of ridiculous.

https://github.com/buenoIsHere/RainbowVomit

 
//
// 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
//
// Addendum from Bueno: Thank you florian on openFrameworks for the code!
import codeanticode.syphon.*;
import oscP5.*;

SyphonClient client;
OscP5 oscP5;
float[] rawPoints = new float[131];
float cWidth; 
float cHeight; 
PImage img;
Wave wav;

// num faces found
int found;

// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();

// gesture
float mouthHeight;
float mouthWidth;
float eyeLeft;
float eyeRight;
float eyebrowLeft;
float eyebrowRight;
float jaw;
float nostrils;

void setup() {
  size(640, 480, P3D);
  background (random (256), random (256), 255, random (256));
  smooth();
  frameRate(30);

  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "rawDataReceived", "/raw");

  client = new SyphonClient(this, "FaceOSC");

  colorMode(HSB);
  wav = new Wave(width/2, height/2, 25, PI/18, 0);
}

void draw() {  
  if (client.available()) 
  {
    // The first time getImage() is called with 
    // a null argument, it will initialize the PImage
    // object with the correct size.
    //img = client.getImage(img); // load the pixels array with the updated image info (slow)
    img = client.getImage(img, false); // does not load the pixels array (faster)
    image(img,0,0);
    //background(255,0,0,0);
    if(found > 0) {
      float lastNum = 0; 
      int Idx = 0; 

      noFill();
      noStroke();
      if(dist(rawPoints[122], rawPoints[123], rawPoints[128], rawPoints[129]) > 25)
      {
        wav.paint = true;
      }
      else
      {
        wav.paint = false;  
      }

      wav.offsetX = (rawPoints[120] + rawPoints[124])/2;
      wav.offsetY = (rawPoints[121] + rawPoints[125])/2;
      wav.amplitude = rawPoints[124] - rawPoints[120] - 40;
      wav.display();
      wav.update();
   // ellipse (rawPoints[130],rawPoints[131], 2,2);  

    }
    else
    {
      println ("not found");
    }
  }
}

void mousePressed() {
  background (random (256), random (256), 255, random (256));
}

// OSC CALLBACK FUNCTIONS

public void found(int i) {
  println("found: " + i);
  found = i;
}

public void rawDataReceived(float [] f){
    for (int i = 0; i < f.length; i++)
    {
      rawPoints[i] = f[i];
    }
}

// all other OSC messages end up here
void oscEvent(OscMessage m) {
  if (m.isPlugged() == false) {
    println("UNPLUGGED: " + m);
  }
}
 
/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/46795*@* */
/* !do not delete the line above, required for linking your tweak if you re-upload */
/* Some fun with the sin function
 once you press the left button of the mouse, you can modulate
 the scale and the frequency of a  sine wave*/

// I tried to keep things clean, using OOP
//i'm 100% not sure about the grammar and the vocabulary in the comments

//this script is inspired by the awesome book "PROCESSING a Programming Handbook for Visual Designers and Artists"
// written by  Casey Reas and Ben Fry

class Wave {

  float offsetX; // this will position our wave on the X axis
  float offsetY;
  float amplitude;// this is for the wave height
  float frequency;//this will set the frequency(from batshit fast to insanely zoombastic)
  float angle;// it's an angle, every body knows that!
  boolean paint;

  //constructor
  Wave(float offX, float offY, float amp, float fre, float ang) {
    offsetX = offX;
    offsetY = offY;
    amplitude = amp;
    frequency = fre;
    angle = ang;
    paint = false;
  }

  void display() {

    // for each pixel on the x axis, A.K.A: on all the width of the screen
    for (float y = offsetY; y < = height ; y+=.2) {   

      /*So this is when it's getting all maths and stuff
       it's a neat formula that updates the y position of the ellipse you'll draw
       so, after some movement, it will look like a wave*/
      float posx = offsetX + (sin(angle)*(amplitude + map(y, offsetY, height,20,100)));

      /*you draw an ellipse
       the y position is increasing everytime you loop
       the x position is going up and down and up and down, and...
       my ellipse is 5 pixel high and 10 pixel width. this is how I like my ellipse*/
      ellipse(posx, y, 10,10);

      /* a nice and easy way to get RAINBOW colours
       (don't forget to set the colorMode to HSB in the setup function)
       h will set the hue
       the h value is calculated wirh a sin function and is mapped in order to get a value between 0 and 130*/
      float h = map(sin(angle), -1, 1, 0, 130);
      //here is our h again, for hue. saturation and brightness are at 255

      if(paint)
      {
        fill(h, 255, 255);
      }
      else
      {
        noFill();  
      }

      //don't forget to increase the angle by adding frequency
      // or your wave will be flat; you don't want that
      angle += frequency/2;
    }
  }

  /*this function will be called each frame
   it modifies amplitude and frequency, depending on the x and y coordinates of the mouse,
   once you press the left button*/
  void update() {
  }
}