kadoin-FaceOSC
Behind all that metal and code might there really be… a soul?
What’s happening?
- Eyes light up as eyebrows are raised
- Mouth shows the amplitude of the song over time
- Music gets louder as mouth is opened almost like you/the robot is singing it
Melodramatic musings aside, I had a lot of fun with this project. It sort of just started with playing around with the sample code. I didn’t have a strong concept of what I wanted to do and it was my first time playing around with 3D so I didn’t really want to get into fancy shapes, but I could make a box move around in a space, and what do boxes look like? Robots. And what kind of space could this robot be in? Outer space. Nothing I was going to make would look super realistic, so the cartooniness of all the simple shapes worked well.
I really liked the new Star Trek movie that came out this summer, it was very reminiscent of the original series. I worked at a movie theater so I got to keep the poster, but I digress. A Beastie Boys song blew up a fleet of robot ships, which was actually very fun to watch.
So I figured Intergalactic by the Beastie Boys would be a nice touch while also giving the mouth something to do.
Add a bit of interaction, map a few things, and bada bing bada boom, I got a fun space robot. It’s not the most conceptual thing maybe not even the most original, but it was really fun to make and I really like how it turned out. It’s pretty fun.
Since I can upload video for FaceOSC to analyze, I was thinking about making a music video type thing by putting different Star Trek clips through the program, but that would probably include a decent amount of editing to make it look nice, which I didn’t have time for. It’s still something I think I’ll do eventually, though. Maybe I’ll experiment more with light sources while I’m at it.
// 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
//also Golan's 'face controlled box' sample code towards the bottom of the assignment page was pretty helpful
//./deliverables/deliverables-05/
import processing.sound.*;
SoundFile file;
Amplitude amp;
import oscP5.*;
OscP5 oscP5;
Star[] stars = new Star[100];
int found; // global variable, indicates if a face is found
float poseScale;
PVector poseOrientation = new PVector(); // stores an (x,y,z)
PVector posePosition = new PVector();
float eyebrowLeft;
float eyebrowRight;
float mouthHeight;
int isPlaying = 0;
ArrayList amps= new ArrayList ();
float curAmp =0;
//----------------------------------
void setup() {
size(640, 480, P3D);
oscP5 = new OscP5(this, 8338);
oscP5.plug(this, "found", "/found");
oscP5.plug(this, "poseScale", "/pose/scale");
oscP5.plug(this, "poseOrientation", "/pose/orientation");
oscP5.plug(this, "posePosition", "/pose/position");
oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
file = new SoundFile(this, "intergalactic1.wav");
amp = new Amplitude(this);
for (int i =0; i <stars.length; i++) {
stars[i] = new Star();
}
for (int j = 0; j<28; j++) {
amps.add(0, 0.0);
}
}
//----------------------------------
void draw() {
int millis = millis();
background (0);
noStroke();
lights();
for (int i =0; i <stars.length; i++) {
stars[i].update();
stars[i].show();
}
if (found != 0) {
if (isPlaying == 0) {
file.loop();
amp.input(file);
isPlaying = 1;
}
curAmp = amp.analyze();
amps.add(0, curAmp);
amps.remove(amps.size()-1);
float eyeBrightL = map(eyebrowLeft, 7.5, 9, 0, 1);
float eyeBrightR = map(eyebrowRight, 7.5, 9, 0, 1);
float beacon = map(millis%566, 50, 565, 0, 0.85);
float mouthAmp = map(mouthHeight, 2, 11, .1, 1);
file.amp(mouthAmp);
pushMatrix();
translate(posePosition.x, posePosition.y, posePosition.z);
rotateY (0 - poseOrientation.y);
rotateX (0 - poseOrientation.x);
rotateZ ( poseOrientation.z);
scale(poseScale, poseScale, poseScale);
//eyeLights
lightFalloff(0.01, 0.0005, 0.00075);
//antena light
lightFalloff(1, 0.001, 0.0001);
pointLight(255-255*beacon, 0, 0, 0, -45, 0);
fill(200, 200, 250);
box(40, 40, 40);//head
translate(0, -20, 0);
fill(150, 150, 200);
box(10, 5, 10); //top peg
fill(150, 150, 200);
box(3, 25, 3);//antena
translate(0, -15, 0);
fill(255-255*beacon, 50-50*beacon, 50-50*beacon);
sphere(4); //beep boop
translate(0, 15, 0);
fill(150, 150, 200);
translate(0, 20, 0);
translate(-20, 0, 0);
box(10, 20, 20);//left peg 1
translate(20, 0, 0);
translate(20, 0, 0);
box(10, 20, 20);//right peg 1
translate(-20, 0, 0);
fill(255, 255, 255);
translate(-8, -8, 18);
pointLight(255*eyeBrightL, 240*eyeBrightL, 0, -8, 0, 30);
sphere(6);//left eye
translate(8, 8, -18);
translate(8, -8, 18);
pointLight(255*eyeBrightR, 240*eyeBrightR, 0, 8, 0, 30);
sphere(6);//right eye
translate(-8, 8, -18);
noLights();
lights();
translate(0, 8, 20);
fill(150, 150, 200);
box(30, 10, 5);//mouth
fill(0);
box(28, 8, 5.01);
pushMatrix();
for (int i = -14; i<14; i++) {
float h = amps.get(i+14)*10;//*mouthAmp;
translate(i+0.5, 0, 2.52);
fill(0, 0, 255);
box(1, h, .1);
translate(-i-0.5, 0, -2.52);
}
popMatrix();
translate(0, -8, -20);
popMatrix();
}
}
//----------------------------------
// Event handlers for receiving FaceOSC data
public void found (int i) {
found = i;
}
public void poseScale(float s) {
poseScale = s;
}
public void poseOrientation(float x, float y, float z) {
poseOrientation.set(x, y, z);
}
public void posePosition(float x, float y) {
posePosition.set(x, y, 0);
}
public void eyebrowLeftReceived(float f) {
eyebrowLeft = f;
}
public void eyebrowRightReceived(float f) {
eyebrowRight = f;
}
public void mouthHeightReceived(float h) {
mouthHeight = h;
}
//Dan Shiffman had a cool video about how to make a warpspeed-like star field
//I thought it'd be a pretty sweet setting for my little bot
//https://www.youtube.com/watch?v=17WoOqgXsRM
class Star {
float x;
float y;
float z;
Star() {
x = random(-width/2, width/2);
y = random(-height/2, height/2);
z = random(0, width);
}
void update() {
z -= 15;
if (z<1) {
z=width;
x = random(-width/2, width/2);
y = random(-height/2, height/2);
}
}
void show() {
fill(255);
float sx = map(x/z, 0, 1, 0, width);
float sy = map(y/z, 0, 1, 0, height);
pushMatrix();
translate(width/2, height/2, -50);
float r = map(z, 0, width, 16, 0);
ellipse(sx, sy, r, r);
popMatrix();
}
}