xxxxxxxxxx
358
// https://kylemcdonald.github.io/cv-examples/
// https://github.com/kylemcdonald/AppropriatingNewTechnologies/wiki/Week-2
// https://www.auduno.com/clmtrackr/docs/reference.html
// https://play.rivescript.com/s/3YBGE0eHuX
// https://play.rivescript.com/s/hSLYBL5zcu
let capture;
let tracker;
let w = 640,
h = 480;
let c;
let positions;
let offset = 80;
let bot = new RiveScript();
let botEmotion = new RiveScript();
let speech = new p5.Speech();
let smiling = null;
let issmile = null;
let autostate = false;
let botFace_createImg;
let courFont;
let voicename;
let voicenames = ["Alex", "Google UK English Female", "Google US English", "Google UK English Male"];
function preload() {
// botFace_createImg = createImg("avatar.gif", "loading error...");
// botFace_createImg.id("avatar");
// botFace_createImg.size(320, 480);
// botFace_createImg.position(0, 0);
// botFace_createImg.parent('body');
courFont = loadFont('cour.ttf');
}
function setup() {
capture = createCapture(VIDEO, ready => {
console.log('capture ready.')
});
capture.elt.setAttribute('playsinline', '');
c = createCanvas(w, h);
capture.size(w, h);
capture.hide();
textFont(courFont);
// background(0);
frameRate(10);
// colorMode(HSB);
// speech.listVoices();
voicename = voicenames[int(random(voicenames.length))];
speech.setVoice(voicename);
// print(voicename);
// speech.setVoice('Google US English');
tracker = new clm.tracker();
tracker.init();
tracker.start(capture.elt);
let userinput = select('#userinput');
let user = select('#user');
let chat = select('#chat');
let button = select('#submit');
bot.loadFile("brain.txt").then(loading_done).catch(loading_error);
let auto = select("#auto");
auto.mousePressed(() => {
autostate = !autostate;
if (autostate == false) {
// console.log(autostate);
askAndReply("stop");
speech.speak("stop");
// autostate=null;
speech.stop();
}
});
function loading_done() {
console.log('bot ready');
bot.sortReplies();
let m = month();
let d = day();
let y = year();
if (m == 1) {
m = 'Janurary';
} else if (m == 2) {
m = 'February';
} else if (m == 3) {
m = 'March';
} else if (m == 4) {
m = 'April';
} else if (m == 5) {
m = 'May';
} else if (m == 6) {
m = 'June';
} else if (m == 7) {
m = 'July';
} else if (m == 8) {
m = 'August';
} else if (m == 9) {
m = 'Sepember';
} else if (m == 10) {
m = 'October';
} else if (m == 11) {
m = 'November';
} else if (m == 12) {
m = 'December';
}
let todaydate = `${m} ${d} ${y}`;
// console.log(todaydate);
let greeting = bot.reply('local-user', `greeting ${todaydate}`).then(greeting => {
let li = createElement('li', `${greeting}`);
speech.speak(`${greeting}`);
li.id('botchat');
li.parent('chat');
console.log(greeting);
});
}
function loading_error() {
console.log('error...');
}
chat.position(width / 2 + offset, 0 + offset);
chat.size(width / 2 - 20 - offset, height - offset);
user.position(width / 2 + offset, 9 * height / 10 + offset);
userinput.size(width / 2);
document.getElementById("userinput").addEventListener("keyup", event => {
if (event.keyCode === 13) {
event.preventDefault();
let input = userinput.value();
askAndReply(input);
userinput.value('');
}
});
button.mousePressed(show => {
let input = userinput.value();
askAndReply(input);
userinput.value('');
});
}
function askAndReply(ask) {
let introdisplay = select("#introdisplay");
let chatreply = select("#chatreply");
chatreply.position(10 + offset, 10 + offset);
chatreply.size(width / 2 - 20, height - 50);
let userli = createElement('li', `${ask}`);
userli.id('userchat');
userli.parent('chat');
let userask = createElement('p', `${ask}`);
userask.id('userask');
userask.parent('chatreply');
let userdisplay = createElement('li', `${ask}`);
userdisplay.id('userdisplay');
userdisplay.parent('introdisplay');
let reply = bot.reply("local-user", ask).then(reply => {
// console.log(reply);
speech.speak(`${reply}`);
let botdisplay = createElement('li', `${reply}`);
botdisplay.id('botdisplay');
botdisplay.parent('introdisplay');
let botreply = createElement('p', `${reply}`);
botreply.id('botreply');
botreply.parent('chatreply');
let li = createElement('li', `${reply}`);
li.id('botchat');
li.parent('chat');
stroke(0, 255, 0);
// noFill();
strokeWeight(2);
textSize(100);
fill(0, 255, 0, 100)
text(`${reply}`, 0, height / 2);
});
}
function draw() {
background(0, 100);
// image(capture, 0, 0, w, h);
positions = tracker.getCurrentPosition();
if (positions) {
stroke(255, 200);
strokeWeight(1);
noFill();
// mouth
beginShape();
for (let i = 44; i < 62; i++) {
// print(positions[i]);
vertex(positions[i][0], positions[i][1]);
}
endShape();
//face
beginShape();
for (let i = 0; i < 14; i++) {
vertex(positions[i][0], positions[i][1]);
}
endShape();
//eyebrows
beginShape();
for (let i = 19; i < 22; i++) {
vertex(positions[i][0], positions[i][1]);
}
endShape();
beginShape();
for (let i = 15; i < 18; i++) {
vertex(positions[i][0], positions[i][1]);
}
endShape();
//nose
beginShape();
for (let i = 33; i < 42; i++) {
vertex(positions[i][0], positions[i][1]);
}
endShape();
//draweyes
// let eye1 = [23, 63, 24, 64, 25, 65, 26, 66].map(getPos);
// let eye2 = [30, 68, 29, 67, 28, 70, 31, 69].map(getPos);
const eye1 = {
outline: [23, 63, 24, 64, 25, 65, 26, 66].map(getPos),
center: getPos(27),
top: getPos(24),
bottom: getPos(26)
};
const eye2 = {
outline: [28, 67, 29, 68, 30, 69, 31, 70].map(getPos),
center: getPos(32),
top: getPos(29),
bottom: getPos(31)
}
drawEye(eye1);
drawEye(eye2);
//detect smile
let mouthLeft = getPos(44);
let mouthRight = getPos(50);
let smile = mouthLeft.dist(mouthRight);
// console.log(smile);
if (smile >= 55) {
smiling = "smiling";
issmile = true;
} else {
smiling = "noSmile";
issmile = false;
}
checkExpression(smiling);
if (autostate == true) {
autoSpeak(issmile);
}
rect(20, 20, smile * 3, 20);
//dots
noStroke();
strokeWeight(5);
for (let i = 0; i < positions.length; i++) {
fill(map(i, 0, positions.length, 150, 255), 0, 0);
ellipse(positions[i][0], positions[i][1], 4, 4);
// textSize(20);
// text(i, positions[i][0], positions[i][1]);
}
} else {
textSize(28);
stroke(0, 255, 0);
text("ERR: No reply matched!", random(width), random(height));
}
}
function getPos(index) {
return createVector(positions[index][0], positions[index][1]);
}
function drawEye(eye) {
noFill();
stroke(255);
drawEyeOutline(eye);
const irisRadius = min(eye.center.dist(eye.top), eye.center.dist(eye.bottom));
const irisSize = irisRadius * 2;
noStroke();
fill(230, 0, 0, 200);
ellipse(eye.center.x, eye.center.y, irisSize, irisSize);
const pupilSize = irisSize / 3;
fill(255, 200);
ellipse(eye.center.x, eye.center.y, pupilSize, pupilSize);
}
function drawEyeOutline(eye) {
beginShape();
const firstPoint = eye.outline[0];
eye.outline.forEach((p, i) => {
// console.log(i);
curveVertex(p.x, p.y);
if (i === 0) {
// Duplicate initial point
curveVertex(firstPoint.x, firstPoint.y);
}
if (i === eye.outline.length - 1) {
// Close the curve and duplicate the closing point
curveVertex(firstPoint.x, firstPoint.y);
curveVertex(firstPoint.x, firstPoint.y);
}
});
endShape();
}
function checkExpression(expression) {
// console.log(expression);
if (expression != null) {
textSize(100);
stroke(255);
textAlign(CENTER);
if (expression == "smiling") {
// console.log(expression);
showExpression("^_^", "Are you smiling?");
fill(255);
strokeWeight(5);
expression = `${expression}?`;
}
if (expression == "noSmile") {
showExpression("-_-", "You look sad.");
noFill();
}
text(`${expression}`, width / 2, height / 2);
}
}
function autoSpeak(issmile) {
if (issmile == true) {
askAndReply("^_^");
issmile = null;
}
if (issmile == false) {
askAndReply("-_-");
issmile = null;
}
}
function showExpression(userdata, botdata) {
let userli = createElement('li', userdata);
userli.id('userchat');
userli.parent('chat');
let li = createElement('li', botdata);
li.id('botchat');
li.parent('chat');
}