xxxxxxxxxx
152
// p5.js + BRFv4 face tracker (via handsfree.js)
//
// We're using a specific version of handsfree.js
// that has the (commercial, trial) BRFv4 tracker baked in:
// https://unpkg.com/handsfree@4.0.3/dist/handsfree.js
// more information about the BRFv4 tracker is at:
// https://github.com/Tastenkunst/brfv4_javascript_examples
var myHandsfree;
var prevSec;
var hearts = [];
var increment;
var easing = 0.05;
//---------------------------------------------
function setup() {
createCanvas(640, 480);
rectMode(CENTER);
angleMode(DEGREES);
myVideoInput = createCapture(VIDEO);
myVideoInput.size(width, height);
myVideoInput.hide();
var myConfig = {
hideCursor: true
};
myHandsfree = new Handsfree(myConfig);
myHandsfree.start();
}
//---------------------------------------------
function draw() {
image(myVideoInput, 0, 0, width, height);
//background(255);
var viewer = 0;
var S = second();
if (prevSec != S) {
millisRolloverTime = millis();
}
prevSec = S;
var mils = floor(millis() - millisRolloverTime);
if (myHandsfree.isTracking) {
if (myHandsfree.pose.length > 0) {
viewer = 1;
var face0 = myHandsfree.pose[0].face;
var nPoints = face0.vertices.length;
var noseX = face0.vertices[60];
var noseY = face0.vertices[61];
var leftMX = face0.vertices[96];
var leftMY = face0.vertices[97];
var rightMX = face0.vertices[108];
var rightMY = face0.vertices[109];
var left = face0.vertices[4];
var right = face0.vertices[28];
var faceWidth = int(right-left);
noStroke();
fill(255, 0, 0, 100);
ellipse(noseX, noseY, 9, 9, 200);
ellipse(leftMX, leftMY, 9, 9, 200);
ellipse(rightMX, rightMY, 9, 9, 200);
var mouthDistance = int(dist(leftMX, leftMY, rightMX, rightMY));
var noseDistance = int(dist(leftMX, leftMY, noseX, noseY))
var smileRatio = mouthDistance / noseDistance; //smile is wider than the distance between nose and mouth, still works if people move closer or further from camera
// Rotations of the head, in radians
var rx = face0.rotationX; // pitch
var ry = face0.rotationY; // yaw
var rz = face0.rotationZ; // roll
if (smileRatio >= 1.2) {
increment = 10;
} else {
increment = 0;
}
if (mils % increment == 0 && increment != 0) {
hearts.push(new makeHeart(random(left,right),500,noseX,noseY,faceWidth));
}
for (i = 0; i < hearts.length; i++) {
hearts[i].display();
hearts[i].move();
}
}
}
}
function makeHeart(x, y,nx,ny,w) {
var firstAngle = atan(abs(y / x));
var secondAngle = abs(45 - firstAngle);
var hypo = abs(y) / sin(firstAngle);
this.x = cos(secondAngle) * hypo;
this.y = sin(secondAngle) * hypo;
this.noseX = nx;
this.noseY = ny;
this.fWidth = w;
var size = map(this.fWidth,120,200,30,50);
var S = second();
this.display = function() {
noStroke();
var red = map(this.noseX, 100,600,100,240);
var green = map(this.noseY, 100,400,150,190);
fill(red, green, 220, 200);
push();
rotate(45);
rect(this.x, this.y, size+1, size+1);
arc(this.x - (size / 2), this.y, size + 10, size, 90, 270, CHORD);
arc(this.x, this.y - (size / 2), size, size + 10, 180, 360, CHORD);
pop();
}
this.move = function() {
var speed = 15;
this.x -= speed;
this.y -= speed;
}
}