xxxxxxxxxx
188
// class to manage the hand tracking
let pincher;
// spring variables
let particles = [];
let springs = [];
let anchors = [];
let grabbed = {Left: null, Right:null};
let spacing = 1;
let k = 0.08;
let grabDist = 40;
let numParticels = 80;
let anchorNum = 16;
let gravity;
//handpose variables
let video;
let W = 640;
let H = 480;
function preload() {
pincher = new PinchTracker(ml5, W, H);
}
function setup() {
createCanvas(W, H);
angleMode(DEGREES);
//handpose setup
video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
pincher.setup(video);
//spring setup
gravity = createVector(0,-0.01);
// create all particles
for (let i=0; i < numParticels; i++){
// random position
let nx = 100 + random(width-100);
let ny = 100 + random(height-100);
createParticle(i, nx, ny);
}
}
function draw() {
background(208,226,192);
// Handpose draw
translate(width, 0);
scale(-1, 1);
tint(255,50);
// image(video, 0, 0, width, height);
// connect pinches to anchors
connectPinchToAnchor("Left");
connectPinchToAnchor("Right");
// springs
for (let s=0; s<springs.length; s++){
springs[s].update();
let positive = map(s, 0, springs.length, 0, 255);
let negative = map(s, 0,springs.length , 255, 0);
springs[s].show(positive, negative);
}
// particles
for (let p=0; p < particles.length; p++){
particles[p].applyForce(gravity);
particles[p].update();
let negative = map(p, 0, particles.length, 255, 0);
particles[p].show(negative, p);
}
}
function createParticle(i, x, y){
// instantiate a new particle with position
particles.push(new Particle(x, y));
// is it a regular particle?
if (i!=0){
let a = particles[i];
let b = particles[floor(random(1, i-1))];
let spring = new Spring(k, spacing, a, b);
springs.push(spring);
}
// is it an anchor?
// for first, last and every n particles
if( i == 0 || i == numParticels-1 || i%anchorNum == 0){
anchors.push(particles[i]);
particles[i].locked = true;
}
}
function connectPinchToAnchor(side){
let pinches = pincher.getPinches();
// pinches.Left || Right >> {x: 0, y: 0} || null
// grabbed.Left || Right >> anchor || null
// Left || Right
// pinch grabbed
// ------------------
// Y | Y
// N | Y
// Y | N
// N | N
if(pinches[side] === null){
// if still grabbing -> release particle
if(grabbed[side] !== null){
grabbed[side].influencer = null;
grabbed[side] = null;
}
}else{
// has pinch
if(grabbed[side] === null){
// go find a particle to grab
grabbed[side] = findClosestAnchor(pinches[side]);
if(grabbed[side] !== null){
// turn on influencing
grabbed[side].influencer = pinches[side];
}
}else{
// update grabbed position with pinch position
if(grabbed[side].influencer !== null){
grabbed[side].influencer.x = pinches[side].x;
grabbed[side].influencer.y = pinches[side].y;
}
}
}
}
// find the anchor particle that is closest to the pinch.
// if not close enough just return null
function findClosestAnchor(pinch){
if(pinch === null){
// no pinch :(
return null;
}
let closest;
let minD = 1000;
// go over the anchors
for (let p of anchors){
let d = dist(pinch.x, pinch.y, p.position.x, p. position.y);
if(d < minD){
closest = p;
minD = d;
}
}
// found a match - return it
if( minD < grabDist){
return closest;
}
// no match :(
return null;
}