xxxxxxxxxx
154
// Physics from https://p5js.org/examples/simulate-chain.html
let handPose;
let myVideo;
let myResults;
let gravity = 9.0;
let gravityR = -1.5;
let puppet,
head,
bodyUpper,
bodyLower,
armLeft1,
armRight1,
legLeft1,
legRight1,
armLeft2,
armRight2,
legLeft2,
legRight2;
function setup() {
createCanvas(640, 480);
myVideo = createCapture(VIDEO);
myVideo.size(width, height);
myVideo.hide();
handPose = ml5.handpose();
handPose.detectStart(myVideo, gotResults);
head = new Parts(4, gravity);
bodyUpper = new Parts(3, gravity);
bodyLower = new Parts(3, gravityR);
armLeft1 = new Parts(2, gravity);
armLeft2 = new Parts(2, gravityR);
armRight1 = new Parts(2, gravity);
armRight2 = new Parts(2, gravityR);
legLeft1 = new Parts(3, gravity);
legLeft2 = new Parts(5, gravityR);
legRight1 = new Parts(3, gravity);
legRight2 = new Parts(5, gravityR);
head.connectedTo = [];
bodyUpper.connectedTo = [head, armLeft2, armRight2];
bodyLower.connectedTo = [bodyUpper, legLeft2, legRight2];
armLeft1.connectedTo = [];
armLeft2.connectedTo = [bodyUpper, armLeft1];
armRight1.connectedTo = [];
armRight2.connectedTo = [bodyUpper, armRight1];
legLeft1.connectedTo = [];
legLeft2.connectedTo = [bodyLower, legLeft1];
legRight1.connectedTo = [];
legRight2.connectedTo = [bodyLower, legRight1];
puppet = [
head,
bodyUpper,
bodyLower,
armLeft1,
armRight1,
legLeft1,
legRight1,
armLeft2,
armRight2,
legLeft2,
legRight2,
];
fill(0);
stroke(0);
strokeWeight(16);
}
function gotResults(results) {
myResults = results;
}
function draw() {
background(174, 226, 233);
translate(width, 0); // move to far corner
scale(-1.0, 1.0); // flip x-axis backwards
if (myResults) {
drawKeypoints();
}
puppet[0].displayEllipse();
puppet.forEach((obj) => {
obj.updateAll();
obj.display();
});
}
function drawKeypoints() {
for (let i = 0; i < myResults.length; i++) {
const oneHand = myResults[i];
const kp = oneHand.keypoints;
puppet[0].update(kp[12].x, kp[12].y);
puppet[3].update(kp[8].x, kp[8].y);
puppet[4].update(kp[16].x, kp[16].y);
puppet[5].update(kp[4].x, kp[4].y + 10);
puppet[6].update(kp[20].x, kp[20].y + 10);
}
}
function Parts(m, g) {
this.x = width / 2 - 150 + random() * 300; // The x- and y-coordinates
this.y = height;
this.vx = 0; // The x- and y-axis velocities
this.vy = 0;
this.mass = m;
this.gravity = g;
this.radius = 7 * this.mass;
this.stiffness = 0.6;
this.damping = 0.5;
this.connectedTo = [];
this.update = function (targetX, targetY) {
let forceX = (targetX - this.x) * this.stiffness;
let ax = forceX / this.mass;
this.vx = this.damping * (this.vx + ax);
this.x += this.vx;
let forceY = (targetY - this.y) * this.stiffness;
forceY += this.gravity;
let ay = forceY / this.mass;
this.vy = this.damping * (this.vy + ay);
this.y += this.vy;
this.y = this.y + this.radius > height ? height - this.radius : this.y;
};
this.updateAll = function () {
if (!myResults || myResults.length == 0) {
this.vy = this.damping * (this.vy + gravityR);
this.y += this.vy;
this.y = this.y + this.radius > height ? height - this.radius : this.y;
this.y = this.y - this.radius / 2 < 0 ? 0 + this.radius / 2 : this.y;
}
this.connectedTo.forEach((obj) => {
this.update(obj.x, obj.y);
});
};
this.displayEllipse = function () {
ellipse(this.x, this.y, this.radius * 1.5, this.radius * 1.5);
};
this.display = function () {
this.connectedTo.forEach((obj) => {
line(this.x, this.y, obj.x, obj.y);
});
};
}