FaceOSC to Processing

The above example uses FaceOSC to send face tracking data to Rhino. If you scroll down on the FaceOSC page you will see the download for windows and mac osx. Once you run FaceOSC make sure you only have “raw” selected in the menu at the top right. This sends the X & Y coordinates for the track points over port 8338.

The code below reads the OSC message from FaceOSC and draws the track points in processing. Below is a break down of the elements of the code and the full code is at the bottom of this page.

import oscP5.*;
import controlP5.*;

OscP5 oscP5;

ControlP5 cp5;

ArrayList<PVector> facepoints = new ArrayList<PVector>();  

int face_point;

Above I am loading the oscP5 and controlP5 libraries. I initialize the OscP% object, the ControlP5 object, and create a list of PVectors to hold the track points.

void setup() {
  size(1280, 960);
  
  cp5 = new ControlP5(this);
  
  cp5.addSlider("face_point")
    .setPosition(40,40)
    .setRange(0,66)
    .setSize(200,20)
    .setValue(2)
    .setColorForeground(color(20,200,200))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(0,255,255))
  ;

  oscP5 = new OscP5(this, 8338);

}

In the setup I am adding the slider to cycle through the points and initializing the oscP% object so it is listening to port 8338.

void draw() {  
  background(0);

  for (int i = 0; i < facepoints.size(); i++) {
    PVector p = facepoints.get(i);
    fill(255);
    ellipse(p.x, p.y, 3, 3);
    if(i == face_point){
      fill(255,0,0);
      ellipse(p.x, p.y, 20,20);
    }
  }
}

The draw function only contains a loop that looks through the facepoints list and adds points at the vector positions.

void oscEvent(OscMessage theOscMessage) {
  facepoints = new ArrayList(); 
  if(theOscMessage.checkAddrPattern("/raw")==true) {
    for(int i = 0; i < 132; i++){
      float xp = theOscMessage.get(i).floatValue()*2;
      i++;
      float yp = theOscMessage.get(i).floatValue()*2;
      PVector pt = new PVector(xp,yp);
      facepoints.add(pt);
    }
  }
}

This function is listening to see if there is an OSC message recieved. If there is and there is a set of data sent with the pattern flag “/raw” it will add those data points to the facepoints list.

The full code is below:

import oscP5.*;
OscP5 oscP5;
import controlP5.*;

ControlP5 cp5;

ArrayList facepoints = new ArrayList();  

int face_point;

void setup() {
  size(1280, 960);
  
  cp5 = new ControlP5(this);
  
  cp5.addSlider("face_point")
    .setPosition(40,40)
    .setRange(0,66)
    .setSize(200,20)
    .setValue(2)
    .setColorForeground(color(20,200,200))
     .setColorLabel(color(255))
     .setColorBackground(color(70,70,70))
     .setColorValue(color(0,0,0))
     .setColorActive(color(0,255,255))
  ;

  oscP5 = new OscP5(this, 8338);

}

void draw() {  
  background(0);

  for (int i = 0; i < facepoints.size(); i++) {
    PVector p = facepoints.get(i);
    fill(255);
    ellipse(p.x, p.y, 3, 3);
    if(i == face_point){
      fill(255,0,0);
      ellipse(p.x, p.y, 20,20);
    }
  }
}

void oscEvent(OscMessage theOscMessage) {
  facepoints = new ArrayList(); 
  if(theOscMessage.checkAddrPattern("/raw")==true) {
    for(int i = 0; i < 132; i++){
      float xp = theOscMessage.get(i).floatValue()*2;
      i++;
      float yp = theOscMessage.get(i).floatValue()*2;
      PVector pt = new PVector(xp,yp);
      facepoints.add(pt);
    }
  }
}