//// facialExpressions.js// A script to set different emotions using blend shapes//// Author: Elisa Lupin-Jimenez// Copyright High Fidelity 2018//// Licensed under the Apache 2.0 License// See accompanying license file or http://apache.org///// All assets are under CC Attribution Non-Commerical// http://creativecommons.org/licenses/// (function() { var TABLET_BUTTON_NAME = "EMOTIONS"; // TODO: ADD HTML LANDING PAGE var TRANSITION_TIME_SECONDS = 0.25; var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var icon = Script.getExternalPath(Script.ExternalPaths.HF_Content, "/elisalj/emoji_scripts/icons/emoji-i.svg"); var activeIcon = Script.getExternalPath(Script.ExternalPaths.HF_Content, "/elisalj/emoji_scripts/icons/emoji-a.svg"); var isActive = true; var controllerMappingName; var controllerMapping; var tabletButton = tablet.addButton({ icon: icon, activeIcon: activeIcon, text: TABLET_BUTTON_NAME, isActive: true }); var toggle = function() { isActive = !isActive; tabletButton.editProperties({isActive: isActive}); if (isActive) { Controller.enableMapping(controllerMappingName); } else { setEmotion(DEFAULT); Controller.disableMapping(controllerMappingName); } }; tabletButton.clicked.connect(toggle); var DEFAULT = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.00, "EyeBlink_R": 0.00, "EyeSquint_L": 0.00, "EyeSquint_R": 0.00, "BrowsD_L": 0.00, "BrowsD_R": 0.00, "BrowsU_L": 0.00, "BrowsU_C": 0.00, "JawOpen": 0.00, "JawFwd": 0.00, "MouthFrown_L": 0.00, "MouthFrown_R": 0.00, "MouthSmile_L": 0.00, "MouthSmile_R": 0.00, "MouthDimple_L": 0.00, "MouthDimple_R": 0.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.00, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.00, "Sneer": 0.00, "Puff": 0.00 }; var SMILE = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.30, "EyeBlink_R": 0.30, "EyeSquint_L": 0.90, "EyeSquint_R": 0.90, "BrowsD_L": 1.00, "BrowsD_R": 1.00, "BrowsU_L": 0.00, "BrowsU_C": 0.00, "JawOpen": 0.00, "JawFwd": 0.00, "MouthFrown_L": 0.00, "MouthFrown_R": 0.00, "MouthSmile_L": 1.00, "MouthSmile_R": 1.00, "MouthDimple_L": 1.00, "MouthDimple_R": 1.00, "LipsUpperClose": 0.40, "LipsLowerClose": 0.30, "LipsLowerOpen": 0.25, "ChinUpperRaise": 0.35, "Sneer": 0.00, "Puff": 0.00 }; var LAUGH = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.45, "EyeBlink_R": 0.45, "EyeSquint_L": 0.75, "EyeSquint_R": 0.75, "BrowsD_L": 0.00, "BrowsD_R": 0.00, "BrowsU_L": 0.00, "BrowsU_C": 0.50, "JawOpen": 0.50, "JawFwd": 0.00, "MouthFrown_L": 0.00, "MouthFrown_R": 0.00, "MouthSmile_L": 1.00, "MouthSmile_R": 1.00, "MouthDimple_L": 1.00, "MouthDimple_R": 1.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.00, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.30, "Sneer": 1.00, "Puff": 0.30 }; var FLIRT = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.50, "EyeBlink_R": 0.50, "EyeSquint_L": 0.25, "EyeSquint_R": 0.25, "BrowsD_L": 0.00, "BrowsD_R": 1.00, "BrowsU_L": 0.55, "BrowsU_C": 0.00, "JawOpen": 0.00, "JawFwd": 0.00, "MouthFrown_L": 0.00, "MouthFrown_R": 0.00, "MouthSmile_L": 0.50, "MouthSmile_R": 0.00, "MouthDimple_L": 1.00, "MouthDimple_R": 1.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.00, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.00, "Sneer": 0.00, "Puff": 0.00 }; var SAD = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.30, "EyeBlink_R": 0.30, "EyeSquint_L": 0.30, "EyeSquint_R": 0.30, "BrowsD_L": 0.00, "BrowsD_R": 0.00, "BrowsU_L": 0.00, "BrowsU_C": 0.50, "JawOpen": 0.00, "JawFwd": 0.80, "MouthFrown_L": 0.80, "MouthFrown_R": 0.80, "MouthSmile_L": 0.00, "MouthSmile_R": 0.00, "MouthDimple_L": 0.00, "MouthDimple_R": 0.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.50, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.00, "Sneer": 0.00, "Puff": 0.00 }; var ANGRY = { "EyeOpen_L": 1.00, "EyeOpen_R": 1.00, "EyeBlink_L": 0.00, "EyeBlink_R": 0.00, "EyeSquint_L": 1.00, "EyeSquint_R": 1.00, "BrowsD_L": 1.00, "BrowsD_R": 1.00, "BrowsU_L": 0.00, "BrowsU_C": 0.00, "JawOpen": 0.00, "JawFwd": 0.00, "MouthFrown_L": 0.50, "MouthFrown_R": 0.50, "MouthSmile_L": 0.00, "MouthSmile_R": 0.00, "MouthDimple_L": 0.00, "MouthDimple_R": 0.00, "LipsUpperClose": 0.50, "LipsLowerClose": 0.50, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.00, "Sneer": 0.50, "Puff": 0.00 }; var FEAR = { "EyeOpen_L": 1.00, "EyeOpen_R": 1.00, "EyeBlink_L": 0.00, "EyeBlink_R": 0.00, "EyeSquint_L": 0.00, "EyeSquint_R": 0.00, "BrowsD_L": 0.00, "BrowsD_R": 0.00, "BrowsU_L": 0.00, "BrowsU_C": 1.00, "JawOpen": 0.15, "JawFwd": 0.00, "MouthFrown_L": 0.30, "MouthFrown_R": 0.30, "MouthSmile_L": 0.00, "MouthSmile_R": 0.00, "MouthDimple_L": 0.00, "MouthDimple_R": 0.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.00, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.00, "Sneer": 0.00, "Puff": 0.00 }; var DISGUST = { "EyeOpen_L": 0.00, "EyeOpen_R": 0.00, "EyeBlink_L": 0.25, "EyeBlink_R": 0.25, "EyeSquint_L": 1.00, "EyeSquint_R": 1.00, "BrowsD_L": 1.00, "BrowsD_R": 1.00, "BrowsU_L": 0.00, "BrowsU_C": 0.00, "JawOpen": 0.00, "JawFwd": 0.00, "MouthFrown_L": 1.00, "MouthFrown_R": 1.00, "MouthSmile_L": 0.00, "MouthSmile_R": 0.00, "MouthDimple_L": 0.00, "MouthDimple_R": 0.00, "LipsUpperClose": 0.00, "LipsLowerClose": 0.75, "LipsLowerOpen": 0.00, "ChinUpperRaise": 0.75, "Sneer": 1.00, "Puff": 0.00 }; function mixValue(valueA, valueB, percentage) { return valueA + ((valueB - valueA) * percentage); } var lastEmotionUsed = DEFAULT; var emotion = DEFAULT; var isChangingEmotion = false; var changingEmotionPercentage = 0.0; Script.update.connect(function(deltaTime) { if (!isChangingEmotion) { return; } changingEmotionPercentage += deltaTime / TRANSITION_TIME_SECONDS; if (changingEmotionPercentage >= 1.0) { changingEmotionPercentage = 1.0; isChangingEmotion = false; if (emotion === DEFAULT) { MyAvatar.hasScriptedBlendshapes = false; } } for (var blendshape in emotion) { MyAvatar.setBlendshape(blendshape, mixValue(lastEmotionUsed[blendshape], emotion[blendshape], changingEmotionPercentage)); } }); function setEmotion(currentEmotion) { if (emotion !== lastEmotionUsed) { lastEmotionUsed = emotion; } if (currentEmotion !== lastEmotionUsed) { changingEmotionPercentage = 0.0; emotion = currentEmotion; isChangingEmotion = true; MyAvatar.hasScriptedBlendshapes = true; } } controllerMappingName = 'Hifi-FacialExpressions-Mapping'; controllerMapping = Controller.newMapping(controllerMappingName); controllerMapping.from(Controller.Hardware.Keyboard.H).to(function(value) { if (value !== 0) { setEmotion(SMILE); } }); controllerMapping.from(Controller.Hardware.Keyboard.J).to(function(value) { if (value !== 0) { setEmotion(LAUGH); } }); controllerMapping.from(Controller.Hardware.Keyboard.K).to(function(value) { if (value !== 0) { setEmotion(FLIRT); } }); controllerMapping.from(Controller.Hardware.Keyboard.L).to(function(value) { if (value !== 0) { setEmotion(SAD); } }); controllerMapping.from(Controller.Hardware.Keyboard.V).to(function(value) { if (value !== 0) { setEmotion(ANGRY); } }); controllerMapping.from(Controller.Hardware.Keyboard.B).to(function(value) { if (value !== 0) { setEmotion(FEAR); } }); controllerMapping.from(Controller.Hardware.Keyboard.M).to(function(value) { if (value !== 0) { setEmotion(DISGUST); } }); controllerMapping.from(Controller.Hardware.Keyboard.N).to(function(value) { if (value !== 0) { setEmotion(DEFAULT); } }); Controller.enableMapping(controllerMappingName); Script.scriptEnding.connect(function() { tabletButton.clicked.disconnect(toggle); tablet.removeButton(tabletButton); Controller.disableMapping(controllerMappingName); if (emotion !== DEFAULT || isChangingEmotion) { isChangingEmotion = false; for (var blendshape in DEFAULT) { MyAvatar.setBlendshape(blendshape, DEFAULT[blendshape]); } MyAvatar.hasScriptedBlendshapes = false; } }); }());
//
// facialExpressions.js
// A script to set different emotions using blend shapes
//
// Author: Elisa Lupin-Jimenez
// Copyright High Fidelity 2018
//
// Licensed under the Apache 2.0 License
// See accompanying license file or http://apache.org/
//
// All assets are under CC Attribution Non-Commerical
// http://creativecommons.org/licenses/
//
(function() {
var TABLET_BUTTON_NAME = "EMOTIONS";
// TODO: ADD HTML LANDING PAGE
var TRANSITION_TIME_SECONDS = 0.25;
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var icon = Script.getExternalPath(Script.ExternalPaths.HF_Content, "/elisalj/emoji_scripts/icons/emoji-i.svg");
var activeIcon = Script.getExternalPath(Script.ExternalPaths.HF_Content, "/elisalj/emoji_scripts/icons/emoji-a.svg");
var isActive = true;
var controllerMappingName;
var controllerMapping;
var tabletButton = tablet.addButton({
icon: icon,
activeIcon: activeIcon,
text: TABLET_BUTTON_NAME,
isActive: true
});
var toggle = function() {
isActive = !isActive;
tabletButton.editProperties({isActive: isActive});
if (isActive) {
Controller.enableMapping(controllerMappingName);
} else {
setEmotion(DEFAULT);
Controller.disableMapping(controllerMappingName);
}
};
tabletButton.clicked.connect(toggle);
var DEFAULT = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.00,
"EyeBlink_R": 0.00,
"EyeSquint_L": 0.00,
"EyeSquint_R": 0.00,
"BrowsD_L": 0.00,
"BrowsD_R": 0.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.00,
"JawOpen": 0.00,
"JawFwd": 0.00,
"MouthFrown_L": 0.00,
"MouthFrown_R": 0.00,
"MouthSmile_L": 0.00,
"MouthSmile_R": 0.00,
"MouthDimple_L": 0.00,
"MouthDimple_R": 0.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.00,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.00,
"Sneer": 0.00,
"Puff": 0.00
};
var SMILE = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.30,
"EyeBlink_R": 0.30,
"EyeSquint_L": 0.90,
"EyeSquint_R": 0.90,
"BrowsD_L": 1.00,
"BrowsD_R": 1.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.00,
"JawOpen": 0.00,
"JawFwd": 0.00,
"MouthFrown_L": 0.00,
"MouthFrown_R": 0.00,
"MouthSmile_L": 1.00,
"MouthSmile_R": 1.00,
"MouthDimple_L": 1.00,
"MouthDimple_R": 1.00,
"LipsUpperClose": 0.40,
"LipsLowerClose": 0.30,
"LipsLowerOpen": 0.25,
"ChinUpperRaise": 0.35,
"Sneer": 0.00,
"Puff": 0.00
};
var LAUGH = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.45,
"EyeBlink_R": 0.45,
"EyeSquint_L": 0.75,
"EyeSquint_R": 0.75,
"BrowsD_L": 0.00,
"BrowsD_R": 0.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.50,
"JawOpen": 0.50,
"JawFwd": 0.00,
"MouthFrown_L": 0.00,
"MouthFrown_R": 0.00,
"MouthSmile_L": 1.00,
"MouthSmile_R": 1.00,
"MouthDimple_L": 1.00,
"MouthDimple_R": 1.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.00,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.30,
"Sneer": 1.00,
"Puff": 0.30
};
var FLIRT = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.50,
"EyeBlink_R": 0.50,
"EyeSquint_L": 0.25,
"EyeSquint_R": 0.25,
"BrowsD_L": 0.00,
"BrowsD_R": 1.00,
"BrowsU_L": 0.55,
"BrowsU_C": 0.00,
"JawOpen": 0.00,
"JawFwd": 0.00,
"MouthFrown_L": 0.00,
"MouthFrown_R": 0.00,
"MouthSmile_L": 0.50,
"MouthSmile_R": 0.00,
"MouthDimple_L": 1.00,
"MouthDimple_R": 1.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.00,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.00,
"Sneer": 0.00,
"Puff": 0.00
};
var SAD = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.30,
"EyeBlink_R": 0.30,
"EyeSquint_L": 0.30,
"EyeSquint_R": 0.30,
"BrowsD_L": 0.00,
"BrowsD_R": 0.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.50,
"JawOpen": 0.00,
"JawFwd": 0.80,
"MouthFrown_L": 0.80,
"MouthFrown_R": 0.80,
"MouthSmile_L": 0.00,
"MouthSmile_R": 0.00,
"MouthDimple_L": 0.00,
"MouthDimple_R": 0.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.50,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.00,
"Sneer": 0.00,
"Puff": 0.00
};
var ANGRY = {
"EyeOpen_L": 1.00,
"EyeOpen_R": 1.00,
"EyeBlink_L": 0.00,
"EyeBlink_R": 0.00,
"EyeSquint_L": 1.00,
"EyeSquint_R": 1.00,
"BrowsD_L": 1.00,
"BrowsD_R": 1.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.00,
"JawOpen": 0.00,
"JawFwd": 0.00,
"MouthFrown_L": 0.50,
"MouthFrown_R": 0.50,
"MouthSmile_L": 0.00,
"MouthSmile_R": 0.00,
"MouthDimple_L": 0.00,
"MouthDimple_R": 0.00,
"LipsUpperClose": 0.50,
"LipsLowerClose": 0.50,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.00,
"Sneer": 0.50,
"Puff": 0.00
};
var FEAR = {
"EyeOpen_L": 1.00,
"EyeOpen_R": 1.00,
"EyeBlink_L": 0.00,
"EyeBlink_R": 0.00,
"EyeSquint_L": 0.00,
"EyeSquint_R": 0.00,
"BrowsD_L": 0.00,
"BrowsD_R": 0.00,
"BrowsU_L": 0.00,
"BrowsU_C": 1.00,
"JawOpen": 0.15,
"JawFwd": 0.00,
"MouthFrown_L": 0.30,
"MouthFrown_R": 0.30,
"MouthSmile_L": 0.00,
"MouthSmile_R": 0.00,
"MouthDimple_L": 0.00,
"MouthDimple_R": 0.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.00,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.00,
"Sneer": 0.00,
"Puff": 0.00
};
var DISGUST = {
"EyeOpen_L": 0.00,
"EyeOpen_R": 0.00,
"EyeBlink_L": 0.25,
"EyeBlink_R": 0.25,
"EyeSquint_L": 1.00,
"EyeSquint_R": 1.00,
"BrowsD_L": 1.00,
"BrowsD_R": 1.00,
"BrowsU_L": 0.00,
"BrowsU_C": 0.00,
"JawOpen": 0.00,
"JawFwd": 0.00,
"MouthFrown_L": 1.00,
"MouthFrown_R": 1.00,
"MouthSmile_L": 0.00,
"MouthSmile_R": 0.00,
"MouthDimple_L": 0.00,
"MouthDimple_R": 0.00,
"LipsUpperClose": 0.00,
"LipsLowerClose": 0.75,
"LipsLowerOpen": 0.00,
"ChinUpperRaise": 0.75,
"Sneer": 1.00,
"Puff": 0.00
};
function mixValue(valueA, valueB, percentage) {
return valueA + ((valueB - valueA) * percentage);
}
var lastEmotionUsed = DEFAULT;
var emotion = DEFAULT;
var isChangingEmotion = false;
var changingEmotionPercentage = 0.0;
Script.update.connect(function(deltaTime) {
if (!isChangingEmotion) {
return;
}
changingEmotionPercentage += deltaTime / TRANSITION_TIME_SECONDS;
if (changingEmotionPercentage >= 1.0) {
changingEmotionPercentage = 1.0;
isChangingEmotion = false;
if (emotion === DEFAULT) {
MyAvatar.hasScriptedBlendshapes = false;
}
}
for (var blendshape in emotion) {
MyAvatar.setBlendshape(blendshape,
mixValue(lastEmotionUsed[blendshape], emotion[blendshape], changingEmotionPercentage));
}
});
function setEmotion(currentEmotion) {
if (emotion !== lastEmotionUsed) {
lastEmotionUsed = emotion;
}
if (currentEmotion !== lastEmotionUsed) {
changingEmotionPercentage = 0.0;
emotion = currentEmotion;
isChangingEmotion = true;
MyAvatar.hasScriptedBlendshapes = true;
}
}
controllerMappingName = 'Hifi-FacialExpressions-Mapping';
controllerMapping = Controller.newMapping(controllerMappingName);
controllerMapping.from(Controller.Hardware.Keyboard.H).to(function(value) {
if (value !== 0) {
setEmotion(SMILE);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.J).to(function(value) {
if (value !== 0) {
setEmotion(LAUGH);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.K).to(function(value) {
if (value !== 0) {
setEmotion(FLIRT);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.L).to(function(value) {
if (value !== 0) {
setEmotion(SAD);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.V).to(function(value) {
if (value !== 0) {
setEmotion(ANGRY);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.B).to(function(value) {
if (value !== 0) {
setEmotion(FEAR);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.M).to(function(value) {
if (value !== 0) {
setEmotion(DISGUST);
}
});
controllerMapping.from(Controller.Hardware.Keyboard.N).to(function(value) {
if (value !== 0) {
setEmotion(DEFAULT);
}
});
Controller.enableMapping(controllerMappingName);
Script.scriptEnding.connect(function() {
tabletButton.clicked.disconnect(toggle);
tablet.removeButton(tabletButton);
Controller.disableMapping(controllerMappingName);
if (emotion !== DEFAULT || isChangingEmotion) {
isChangingEmotion = false;
for (var blendshape in DEFAULT) {
MyAvatar.setBlendshape(blendshape, DEFAULT[blendshape]);
}
MyAvatar.hasScriptedBlendshapes = false;
}
});
}());