Files
Zos/Skills/@be/node_modules/jibo-anim-db/lib/jibo-anim-db.js

1361 lines
52 KiB
JavaScript

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jiboAnimDb = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Utils_1 = require("./Utils");
const Classes_1 = require("./Classes");
const AnimUtils_1 = require("./AnimUtils");
class AnimCollection {
constructor(parent) {
this.parent = parent;
this.animations = [];
this.categories = [];
this._animationsByName = new Map();
this._categoriesByName = new Map();
}
addAnimation(animation) {
const nameLower = animation.name.toLowerCase();
if (!this._animationsByName.has(nameLower)) {
this._animationsByName.set(nameLower, animation);
this.animations.push(animation);
}
}
addCategory(category) {
const nameLower = category.name.toLowerCase();
if (!this._categoriesByName.has(nameLower)) {
this._categoriesByName.set(nameLower, category);
this.categories.push(category);
}
}
getCategoryByName(name) {
return this._categoriesByName.get(name.toLowerCase());
}
getAnimByName(name) {
return this._animationsByName.get(name.toLowerCase());
}
getAnimationNames() {
return Array.from(this._animationsByName.keys());
}
getAnimationCategories() {
return Array.from(this._categoriesByName.keys());
}
search(searchTerm) {
let term = searchTerm.toLowerCase();
let res = new Classes_1.SearchResults();
this._search(term, res);
return res;
}
query(query) {
AnimUtils_1.AnimUtils.insertDefaultAnimQueryParams(query);
let res = new Classes_1.AnimResults();
this._query(query, res);
let matchingNoDupes = [];
new Set(res.matching).forEach(elm => matchingNoDupes.push(elm));
res.matching = matchingNoDupes;
let nonMatchingNoDupes = [];
new Set(res.nonMatching).forEach(elm => nonMatchingNoDupes.push(elm));
res.nonMatching = nonMatchingNoDupes;
return res;
}
_search(term, res) {
let catByName = this._categoriesByName.get(term);
if (catByName) {
res.category = catByName;
}
let animByName = this._animationsByName.get(term);
if (animByName) {
res.name = animByName;
}
this.animations.forEach(anim => {
anim.meta.metaTerms.forEach(meta => {
if (meta === term) {
res.meta.push(anim);
}
});
});
}
_query(query, res) {
if (query.categories.length) {
query.categories.forEach(catName => {
let category = this._categoriesByName.get(catName);
if (category) {
category._query(query, res);
}
});
}
else {
Utils_1.Utils.getAnimationsByQuery(this.animations, res, query);
}
}
}
exports.AnimCollection = AnimCollection;
},{"./AnimUtils":4,"./Classes":7,"./Utils":10}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Classes_1 = require("./Classes");
const AnimUtils_1 = require("./AnimUtils");
class AnimDB {
constructor(jibo) {
this.collections = [];
this.jibo = jibo;
}
push(animCollection) {
this.collections.push(animCollection);
}
pop() {
return this.collections.pop();
}
getAnimByName(animName) {
let anim;
for (let i = 0; i < this.collections.length; i++) {
let animDB = this.collections[i];
let a = animDB.getAnimByName(animName);
if (a) {
anim = a;
break;
}
}
return anim;
}
getAnimationNames() {
let names = [];
for (let i = 0; i < this.collections.length; i++) {
names = names.concat(this.collections[i].getAnimationNames());
}
return names;
}
getAnimationCategories() {
let names = [];
for (let i = 0; i < this.collections.length; i++) {
names = names.concat(this.collections[i].getAnimationCategories());
}
return names;
}
search(searchTerm) {
let term = searchTerm.toLowerCase();
let res = new Classes_1.SearchResults();
this.collections.forEach(animColl => {
animColl._search(term, res);
});
return res;
}
query(query) {
AnimUtils_1.AnimUtils.insertDefaultAnimQueryParams(query);
let res = new Classes_1.AnimResults();
this.collections.forEach(animColl => {
animColl._query(query, res);
});
let matchingNoDupes = [];
new Set(res.matching).forEach(elm => matchingNoDupes.push(elm));
res.matching = matchingNoDupes;
let nonMatchingNoDupes = [];
new Set(res.nonMatching).forEach(elm => nonMatchingNoDupes.push(elm));
res.nonMatching = nonMatchingNoDupes;
return res;
}
}
exports.AnimDB = AnimDB;
},{"./AnimUtils":4,"./Classes":7}],3:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fs = require("fs");
const jibo_cai_utils_1 = require("jibo-cai-utils");
const AnimDB_1 = require("./AnimDB");
const AnimCollection_1 = require("./AnimCollection");
const Animation_1 = require("./Animation");
const Category_1 = require("./Category");
const AnimUtils_1 = require("./AnimUtils");
const Utils_1 = require("./Utils");
const Classes_1 = require("./Classes");
const Range_1 = require("./Range");
const stringify = require('json-stable-stringify');
class AnimDBParser {
static readAnimDB(jibo, animDBPath, ...moreAnimDBPaths) {
moreAnimDBPaths.unshift(animDBPath);
let animDB = new AnimDB_1.AnimDB(jibo);
let promises = moreAnimDBPaths.map((rootDir) => {
return AnimDBParser.readAndAddAnimCollection(animDB, rootDir);
});
return Promise.all(promises)
.then(() => animDB);
}
static readAndAddAnimCollection(animDB, animDBPath) {
const rootDir = path.dirname(animDBPath);
return jibo_cai_utils_1.FileUtils.readFile(animDBPath)
.then(animStr => {
const animMetaMap = JSON.parse(animStr);
AnimDBParser.addAnimCollection(animDB, rootDir, animMetaMap);
});
}
static addAnimCollection(animDB, rootDir, animMetaMap) {
let collection = new AnimCollection_1.AnimCollection(animDB);
AnimDBParser.addToAnimCollection(collection, rootDir, animMetaMap);
animDB.push(collection);
}
static addToAnimCollection(collection, rootDir, animMetadataCollection) {
let kvAnimMetaArray;
if (animMetadataCollection instanceof Array) {
kvAnimMetaArray = animMetadataCollection;
}
else {
kvAnimMetaArray = [];
Object.keys(animMetadataCollection).forEach(key => {
kvAnimMetaArray.push([key, animMetadataCollection[key]]);
});
}
for (let [animName, animMeta] of kvAnimMetaArray) {
if (!animMeta.name) {
throw new Error(`Missing anim name: ${animName}`);
}
animName = animMeta.name.toLowerCase();
const anim = new Animation_1.Animation(collection, animMeta, rootDir);
let existingAnim = collection.getAnimByName(anim.name);
if (existingAnim) {
const paths = [existingAnim.meta.path, animMeta.path];
throw new Error(`Duplicate animation name: '${animName}' at paths: ${paths}`);
}
collection.addAnimation(anim);
anim.meta.categories.forEach(categoryName => {
let cat = collection.getCategoryByName(categoryName);
if (!cat) {
cat = new Category_1.Category(categoryName);
collection.addCategory(cat);
}
cat.addAnimation(anim);
});
}
}
static createAndWriteAnimMetaData(jibo, rootDir, outName) {
return AnimDBParser.createAnimMetaData(jibo, rootDir)
.then(allAnimData => {
const outPath = path.join(rootDir, outName + '.json');
const outData = stringify(allAnimData, { space: ' ' });
return jibo_cai_utils_1.PromiseUtils.promisify(h => fs.writeFile(outPath, outData, 'utf8', h));
});
}
static createAnimMetaData(jibo, rootDir) {
const animsDir = path.join(rootDir, 'animations');
return jibo_cai_utils_1.FileUtils.findAllFilesWithExt(animsDir, 'keys')
.then((filePaths) => {
const goodPaths = filePaths.filter(filePath => {
const relFilePath = path.relative(animsDir, filePath);
const pathElements = relFilePath.split(path.sep);
return !pathElements.some(el => el.startsWith('_'));
});
return AnimDBParser._createAnimMetaData(jibo, rootDir, goodPaths);
});
}
static _createAnimMetaData(jibo, rootDir, paths) {
return __awaiter(this, void 0, void 0, function* () {
let cachedAnimDB = jibo.animDB._animDB;
jibo.animDB._animDB = new AnimDB_1.AnimDB(jibo);
let collection = new AnimCollection_1.AnimCollection(jibo.animDB._animDB);
jibo.animDB.push(collection);
let completeMetadata = {};
let unparsed = [];
let parsed = [];
while (paths.length > 0) {
const unparsedCount = paths.length;
for (const path of paths) {
try {
const meta = yield AnimDBParser.parseAnimation(jibo, path, rootDir);
parsed.push(meta);
}
catch (err) {
if (err instanceof ReferenceError) {
unparsed.push(path);
}
else {
throw err;
}
}
}
if (unparsedCount === unparsed.length) {
throw new Error(`Could not resolve ${unparsedCount} animations: ${unparsed}`);
}
else {
paths = unparsed;
}
const rootDirResolved = path.resolve(rootDir);
let kvAnimMetaArray = [];
parsed.forEach(animData => {
const firstPart = animData.path.substring(0, rootDirResolved.length);
if (firstPart !== rootDirResolved) {
throw new Error(`Animation doesn't have the expected root path: ${[animData.path, rootDirResolved]}`);
}
animData.path = animData.path.substring(rootDirResolved.length + path.sep.length);
kvAnimMetaArray.push([animData.name, animData]);
});
AnimDBParser.addToAnimCollection(collection, rootDir, kvAnimMetaArray);
let tempAnimMetaMap = {};
kvAnimMetaArray.forEach(([key, value]) => {
tempAnimMetaMap[key] = value;
});
Object.assign(completeMetadata, tempAnimMetaMap);
parsed = [];
unparsed = [];
}
jibo.animDB._animDB = cachedAnimDB;
return completeMetadata;
});
}
static parseAnimation(jibo, filePath, rootDir) {
return __awaiter(this, void 0, void 0, function* () {
const animData = yield AnimDBParser.loadKeys(jibo, filePath, rootDir);
return AnimDBParser.parseAnimationFromAnim(animData, filePath);
});
}
static loadKeys(jibo, keysPath, rootDir) {
return __awaiter(this, void 0, void 0, function* () {
return new jibo.rendering.animation.KeysLoader(keysPath, rootDir).load();
});
}
static parseAnimationFromAnim(animData, filePath) {
let animdbTag;
let scale, speed, name;
try {
const defaultName = filePath ? path.basename(filePath, path.extname(filePath)) : 'UNKNOWN_ANIM';
animdbTag = animData.animdb || {};
name = Utils_1.Utils.parseString(animdbTag.name, defaultName);
scale = [
Utils_1.Utils.parseNumber(animdbTag.scaleMin, 1),
Utils_1.Utils.parseNumber(animdbTag.scaleMax, 1)
];
speed = [
Utils_1.Utils.parseNumber(animdbTag.speedMin, 1),
Utils_1.Utils.parseNumber(animdbTag.speedMax, 1)
];
}
catch (error) {
throw new Error(`Error parsing animation at path '${filePath}': '${error}'`);
}
if ((speed[0] <= 0) || (speed[0] > speed[1])) {
throw new Error(`Invalid speed bounds '${JSON.stringify(speed)}' for animation '${filePath}'`);
}
if (scale[0] > scale[1]) {
throw new Error(`Invalid scale bounds '${JSON.stringify(scale)}' for animation '${filePath}'`);
}
const categoryString = animdbTag.categories || '';
let categories = [];
categoryString.split(',').forEach(category => {
let catName = category.trim().toLowerCase();
if (catName.length) {
categories.push(catName);
}
});
const metaString = animdbTag.meta || '';
let metaTerms = [];
metaString.split(',').forEach(_metaTerm => {
let metaName = _metaTerm.trim().toLowerCase();
if (metaName.length) {
metaTerms.push(metaName);
}
});
const holdSafeKF = AnimUtils_1.AnimUtils.hasHoldSafe(animData, name);
let durationRange = [
speed[0] * animData.duration,
speed[1] * animData.duration
];
if (holdSafeKF !== -1) {
durationRange[1] = Range_1.INFINITE_DURATION;
}
let layers = AnimUtils_1.AnimUtils.checkLayers(animData);
if (metaTerms.indexOf(AnimUtils_1.AUDIO_ONLY_META) !== -1) {
Object.keys(layers).forEach(layer => {
if (layers[layer] && (layer !== Classes_1.LayerName.AudioEvent.short)) {
layers[layer] = false;
}
});
}
const animMetadata = {
name,
scale,
speed,
durationRange,
categories,
metaTerms,
holdSafeKF,
path: filePath,
duration: animData.duration,
startsNeutral: AnimUtils_1.AnimUtils.startsNeutral(animData),
endsNeutral: AnimUtils_1.AnimUtils.endsNeutral(animData),
hasAudio: AnimUtils_1.AnimUtils.hasAudio(animData),
orientation: AnimUtils_1.AnimUtils.calculateOrientation(animData),
layers
};
return animMetadata;
}
}
exports.AnimDBParser = AnimDBParser;
},{"./AnimCollection":1,"./AnimDB":2,"./AnimUtils":4,"./Animation":5,"./Category":6,"./Classes":7,"./Range":9,"./Utils":10,"fs":undefined,"jibo-cai-utils":undefined,"json-stable-stringify":undefined,"path":undefined}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Classes_1 = require("./Classes");
const LayerMocks_1 = require("./animation_formats/LayerMocks");
const BODY_ANGLE_EPSILON = 3;
const HOLD_SAFE_EVENT_NAME = 'HOLD_SAFE';
exports.AUDIO_ONLY_META = "audio-only";
class AnimUtils {
static _addMockLayer(animData, type) {
animData.layers.push(LayerMocks_1.LayerTemplate.generateLayer(type, type));
}
static scaleTimeInPlace(animData, scale) {
animData.layers.forEach((layer) => {
layer.keyframes.forEach(kf => {
kf.time = Math.round(kf.time * scale);
});
});
animData.duration = Math.round(animData.duration * scale);
}
static scaleBodyInPlace(animData, scale) {
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Body, (layer) => {
layer.keyframes.forEach(kf => {
kf.value.Head *= scale;
kf.value.Pelvis *= scale;
kf.value.Torso *= scale;
});
});
}
static flipScreenLeftRight(animData) {
let handler = (layer) => {
layer.keyframes.forEach(kf => {
kf.value.Translate.x *= -1;
});
};
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Eye, handler);
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Overlay, handler);
}
static startsNeutral(animData) {
let ret = true;
let earliestFrame = animData.duration;
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Body, (layer) => {
if (layer.keyframes.length) {
let kf = layer.keyframes[0];
if (kf.time < earliestFrame) {
earliestFrame = kf.time;
if (Math.abs(kf.value.Pelvis) > BODY_ANGLE_EPSILON ||
Math.abs(kf.value.Head) > BODY_ANGLE_EPSILON ||
Math.abs(kf.value.Torso) > BODY_ANGLE_EPSILON) {
ret = false;
}
}
}
});
return ret;
}
static endsNeutral(animData) {
let ret = true;
let latestTime = -1;
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Body, (layer) => {
if (layer.keyframes.length) {
let kf = layer.keyframes[layer.keyframes.length - 1];
if (kf.time > latestTime) {
latestTime = kf.time;
if (Math.abs(kf.value.Pelvis) > BODY_ANGLE_EPSILON ||
Math.abs(kf.value.Head) > BODY_ANGLE_EPSILON ||
Math.abs(kf.value.Torso) > BODY_ANGLE_EPSILON) {
ret = false;
}
}
}
});
return ret;
}
static checkLayers(animData, strict = true) {
let layerPresence = {};
Classes_1.LayerName.Layers.forEach(layerName => {
if (AnimUtils.hasLayer(animData, layerName, strict)) {
layerPresence[layerName.short] = true;
}
});
return layerPresence;
}
static hasAudio(animData) {
return AnimUtils.hasLayer(animData, Classes_1.LayerName.AudioEvent);
}
static hasLayer(animData, layerName, strict = true) {
let layerCheck = [];
AnimUtils.forEachLayerType(animData, layerName, (layer) => {
if (strict) {
layerCheck.push(layer.visible && (layer.keyframes.length !== 0));
}
else {
layerCheck.push(true);
}
});
return layerCheck.some(hasContent => hasContent);
}
static hasHoldSafe(animData, name) {
let kf = -1;
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Event, (layer) => {
layer.keyframes.forEach(layerKF => {
if (layerKF.value.Event.name === HOLD_SAFE_EVENT_NAME) {
if (kf !== -1) {
throw new Error(`Two HOLD_SAFE keyframes defined in animation` +
` '${name}' at frames ${kf} and ${layerKF.time}`);
}
kf = layerKF.time;
}
});
});
return kf;
}
static calculateOrientation(animData) {
let headSum = 0;
let pelvisSum = 0;
let torsoSum = 0;
let numFrames = 0;
AnimUtils.forEachLayerType(animData, Classes_1.LayerName.Body, (layer) => {
layer.keyframes.forEach(layerKF => {
numFrames++;
headSum += layerKF.value.Head;
pelvisSum += layerKF.value.Pelvis;
torsoSum += layerKF.value.Torso;
});
});
headSum /= numFrames;
pelvisSum /= numFrames;
torsoSum /= numFrames;
let bodySum = (torsoSum + pelvisSum) / 2;
if (Math.abs(bodySum) > 10) {
return (bodySum > 0) ? Classes_1.Orientation.LEFT : Classes_1.Orientation.RIGHT;
}
else {
return (headSum > 0) ? Classes_1.Orientation.LEFT : Classes_1.Orientation.RIGHT;
}
}
static forEachLayerType(animData, layerTypeName, handler) {
let name = layerTypeName.long || layerTypeName.short;
animData.layers.forEach(layer => {
if (layer.type === name) {
handler(layer);
}
});
}
static insertDefaultAnimQueryParams(query) {
if (!query.categories) {
query.categories = [];
}
if (query.category) {
query.categories.push(query.category);
}
for (let i = 0; i < query.categories.length; i++) {
query.categories[i] = query.categories[i].toLowerCase();
}
query.includeCat = query.includeCat || [];
query.includeSomeCat = query.includeSomeCat || [];
query.excludeCat = query.excludeCat || [];
query.includeMeta = query.includeMeta || [];
query.includeSomeMeta = query.includeSomeMeta || [];
query.excludeMeta = query.excludeMeta || [];
const filters = [query.includeCat, query.includeSomeCat, query.excludeCat, query.includeMeta, query.includeSomeMeta, query.excludeMeta];
filters.forEach(array => {
for (let i = 0; i < array.length; i++) {
array[i] = array[i].toLowerCase();
}
});
if (!query.durationError) {
query.durationError = 0;
}
if (!query.duration) {
query.duration = -1;
}
if (typeof query.hasAudio === 'undefined') {
query.hasAudio = Classes_1.HasAudio.DONT_CARE;
}
}
}
exports.AnimUtils = AnimUtils;
},{"./Classes":7,"./animation_formats/LayerMocks":12}],5:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Range_1 = require("./Range");
const Utils_1 = require("./Utils");
const Playback_1 = require("./Playback");
const Classes_1 = require("./Classes");
const log_1 = require("./log");
const log = log_1.default.createChild("Animation");
class Animation {
constructor(parent, meta, resourceRoot, animData) {
this.parent = parent;
this.meta = meta;
this.resourceRoot = resourceRoot;
this.animData = animData;
this.animDataCache = {};
this.name = meta.name;
this.durationRange = new Range_1.Range(meta.durationRange[0], meta.durationRange[1]);
}
createFromConfig(config = { cache: null }) {
return __awaiter(this, void 0, void 0, function* () {
log.debug(`Configuring Animation ${this.name} for configuration: `, config);
let transformation = this._getTransformation(config);
const playback = new Playback_1.Playback(transformation, config.cache, this);
return playback.init(config);
});
}
play(config = { cache: null }, options) {
log.debug(`Configuring Animation ${this.name} with config: `, config, ` for immediate playback with options: `, options);
let transformation = this._getTransformation(config);
const playback = new Playback_1.Playback(transformation, config.cache, this);
return {
playback: playback,
result: playback.initAndPlay(config, options)
};
}
_getTransformation(options) {
let trans = new Classes_1.Transform();
if (options) {
if (options.orientation) {
let reqOrientation = options.orientation;
if (reqOrientation !== this.meta.orientation) {
trans.shouldFlipLeftRight = true;
}
}
if (options.speed) {
trans.speed = Utils_1.Utils.limitToRange(options.speed, this.meta.speed);
}
if (options.exaggerate) {
trans.exaggerate = Utils_1.Utils.limitToRange(options.exaggerate, this.meta.scale);
}
if (options.duration) {
if (options.duration < this.meta.durationRange[0]) {
trans.speed = this.meta.speed[0];
}
else if (options.duration < trans.speed * this.meta.duration) {
trans.speed = options.duration / this.meta.duration;
trans.speed = Utils_1.Utils.limitToRange(trans.speed, this.meta.speed);
}
else if (this.meta.holdSafeKF !== -1) {
trans.framesToHold = options.duration - trans.speed * this.meta.duration;
}
else if (options.duration > trans.speed * this.meta.duration) {
if (typeof options.speed !== 'number') {
trans.speed = options.duration / this.meta.duration;
trans.speed = Utils_1.Utils.limitToRange(trans.speed, this.meta.speed);
}
}
}
}
return trans;
}
}
exports.Animation = Animation;
},{"./Classes":7,"./Playback":8,"./Range":9,"./Utils":10,"./log":15}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Utils_1 = require("./Utils");
const AnimUtils_1 = require("./AnimUtils");
const Classes_1 = require("./Classes");
class Category {
constructor(name) {
this.name = name;
this.animations = [];
this.animationsByName = new Map();
}
addAnimation(anim) {
this.animations.push(anim);
this.animationsByName.set(anim.name, anim);
}
query(query) {
AnimUtils_1.AnimUtils.insertDefaultAnimQueryParams(query);
let res = new Classes_1.AnimResults();
this._query(query, res);
return res;
}
_query(query, res) {
Utils_1.Utils.getAnimationsByQuery(this.animations, res, query);
}
}
exports.Category = Category;
},{"./AnimUtils":4,"./Classes":7,"./Utils":10}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Transform {
constructor() {
this.framesToHold = -1;
this.speed = 1;
this.exaggerate = 1;
this.shouldFlipLeftRight = false;
}
}
exports.Transform = Transform;
var Orientation;
(function (Orientation) {
Orientation["LEFT"] = "LEFT";
Orientation["RIGHT"] = "RIGHT";
})(Orientation = exports.Orientation || (exports.Orientation = {}));
var HasAudio;
(function (HasAudio) {
HasAudio["YES"] = "YES";
HasAudio["NO"] = "NO";
HasAudio["DONT_CARE"] = "DONT_CARE";
})(HasAudio = exports.HasAudio || (exports.HasAudio = {}));
class AnimResults {
constructor() {
this.matching = [];
this.nonMatching = [];
}
}
exports.AnimResults = AnimResults;
class SearchResults {
constructor() {
this.meta = [];
}
}
exports.SearchResults = SearchResults;
class LayerName {
constructor(short, long) {
this.short = short;
this.long = long;
}
}
LayerName.Body = new LayerName('Body');
LayerName.Eye = new LayerName('Eye');
LayerName.EyeTexture = new LayerName('EyeTexture', 'Eye Texture');
LayerName.Overlay = new LayerName('Overlay');
LayerName.OverlayTexture = new LayerName('OverlayTexture', 'Overlay Texture');
LayerName.AudioEvent = new LayerName('AudioEvent', 'Audio Event');
LayerName.Event = new LayerName('Event');
LayerName.Pixi = new LayerName('Pixi');
LayerName.BackgroundTexture = new LayerName('BackgroundTexture', 'Background Texture');
LayerName.LED = new LayerName('LED');
LayerName.Layers = [
LayerName.Body,
LayerName.Eye,
LayerName.EyeTexture,
LayerName.Overlay,
LayerName.OverlayTexture,
LayerName.AudioEvent,
LayerName.Event,
LayerName.Pixi,
LayerName.BackgroundTexture,
LayerName.LED
];
exports.LayerName = LayerName;
var BuilderLayer;
(function (BuilderLayer) {
BuilderLayer["BEAT"] = "beat";
BuilderLayer["DEFAULT"] = "default";
BuilderLayer["POSTURE"] = "posture";
})(BuilderLayer = exports.BuilderLayer || (exports.BuilderLayer = {}));
},{}],8:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const uuid = require("uuid");
const path = require("path");
const events = require("events");
const jibo_cai_utils_1 = require("jibo-cai-utils");
const jibo_expression_client_1 = require("jibo-expression-client");
const Classes_1 = require("./Classes");
const AnimUtils_1 = require("./AnimUtils");
const log_1 = require("./log");
const log = log_1.default.createChild("Playback");
const FRAMERATE = 30;
const defaultOptions = {
ownerInformation: 'AnimDB',
disableSetFaceAnim: false,
screenCenterOverride: true
};
class ExtPromise {
constructor() {
this.promise = new Promise((res, rej) => {
this.resolve = res;
this.reject = rej;
});
}
}
class Playback extends events.EventEmitter {
constructor(transform, cacheName, animation) {
super();
this.transform = transform;
this.cacheName = cacheName;
this.animation = animation;
this.runtimeKeys = false;
this.holdSafeDuration = 0;
this.runtimeKeys = !this.animation.meta.path;
this.jibo = this.animation.parent.parent.jibo;
}
init(config) {
return __awaiter(this, void 0, void 0, function* () {
this._init(config);
this.keysAnimation = yield this.loadAnimation();
this.instance = this.keysAnimation.instance;
log.debug(`Initialized playback ${this.animation.name}`);
return this;
});
}
initAndPlay(config, options) {
return __awaiter(this, void 0, void 0, function* () {
this.playExtPr = new ExtPromise();
this._init(config);
this.resolvePlaybackOptions(options);
this.keysAnimation = yield this.loadAnimation(true);
this.instance = this.keysAnimation.instance;
this.registerEventsAndHandlers();
const state = yield this.playExtPr.promise;
yield this.handlePlaybackCompletion(state);
return state;
});
}
play(options) {
return __awaiter(this, void 0, void 0, function* () {
this.playExtPr = new ExtPromise();
this.resolvePlaybackOptions(options);
this.registerEventsAndHandlers();
if ((this.options.screenCenterOverride === false) && this.hasScreenDOFs) {
try {
yield this.jibo.expression.centerRobot({
requestor: this.options.ownerInformation,
centerGlobally: false,
dofs: this.jibo.expression.dofs.SCREEN
});
}
catch (err) {
this.playExtPr.reject(err);
}
}
try {
if (!this.hasBeenStopped) {
log.debug(`Playback ${this.animation.name} playing with these options: `, this.options);
yield this.keysAnimation.instance.play(this.options.ownerInformation);
}
}
catch (err) {
this.playExtPr.reject(err);
}
const state = yield this.playExtPr.promise;
yield this.handlePlaybackCompletion(state);
return state;
});
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
if (this.keysAnimation) {
try {
yield this.keysAnimation.instance.stop();
}
catch (error) {
log.warn(`Could not stop instance that no longer exists: `, error);
}
}
if (this.assetToken) {
this.assetToken.unload();
this.assetToken = null;
}
});
}
_init(config) {
if (!config) {
config = {
cache: this.jibo.loader.activeCache
};
}
log.debug(`Initializing playback ${this.animation.name} with config: `, config);
if (this.runtimeKeys) {
this.filePath = this.animation.resourceRoot;
}
else {
this.filePath = path.join(this.animation.resourceRoot, this.animation.meta.path);
}
if (this.animation.meta.metaTerms.indexOf(AnimUtils_1.AUDIO_ONLY_META) !== -1) {
config.layer = Classes_1.BuilderLayer.BEAT;
}
if (this.transform.shouldFlipLeftRight || this.transform.exaggerate) {
let flipMult = this.transform.shouldFlipLeftRight ? -1 : 1;
let flipAndExagMult = flipMult * (this.transform.exaggerate || 1);
if ((flipMult !== 1) || (flipAndExagMult !== 1)) {
let dofs = {
bottomSection_r: 1,
middleSection_r: 1,
topSection_r: 1,
eyeSubRootBn_t: 1
};
Object.keys(dofs).forEach(dof => {
if (dof === "eyeSubRootBn_t_2") {
dofs[dof] *= flipMult;
}
else {
dofs[dof] *= flipAndExagMult;
}
});
config.scale = dofs;
}
}
if (this.transform.framesToHold !== -1) {
this.holdSafeDuration = ((this.transform.framesToHold / FRAMERATE) * 1000);
}
if (this.transform.speed !== 1) {
config.speed = this.transform.speed;
}
this.duration = this.animation.meta.duration;
if (this.transform.speed !== -1) {
this.duration *= this.transform.speed;
}
if (this.transform.framesToHold !== -1) {
this.duration += this.transform.framesToHold;
}
this.config = config;
}
resolvePlaybackOptions(options) {
const playOptions = Object.assign({}, defaultOptions, options);
this.options = playOptions;
}
registerEventsAndHandlers() {
const dofsInScreen = this.jibo.expression.dofs.SCREEN;
const dofsInAnim = this.keysAnimation.instance.dofs;
const dofsNotInAnim = dofsInScreen.minus(dofsInAnim);
this.hasScreenDOFs = (dofsNotInAnim.getDOFs().length !== dofsInScreen.getDOFs().length);
if (this.hasScreenDOFs && !this.options.disableSetFaceAnim) {
this.jibo.face.eye.addAnimation(this.keysAnimation);
}
const stopHandler = (state) => {
this.hasBeenStopped = true;
log.debug(`Playback ${this.animation.name} was stopped with state ${state}`);
this._cleanup();
this.playExtPr.resolve(state);
};
const holdSafeHandler = () => __awaiter(this, void 0, void 0, function* () {
try {
if (this.keysAnimation) {
yield this.keysAnimation.instance.pause();
yield jibo_cai_utils_1.TimeUtils.wait(this.holdSafeDuration);
}
if (this.keysAnimation) {
yield this.keysAnimation.instance.resume();
}
}
catch (error) {
log.warn(`Error in hold-safe logic for animation ${this.animation.name}: `, error);
}
});
this.keysAnimation.instance.events.stopped.on(() => stopHandler(jibo_expression_client_1.AnimationState.STOPPED));
this.keysAnimation.instance.events.cancelled.on(() => stopHandler(jibo_expression_client_1.AnimationState.CANCELLED));
this.keysAnimation.instance.events.rejected.on(() => stopHandler(jibo_expression_client_1.AnimationState.REJECTED));
if (this.holdSafeDuration > 0) {
this.keysAnimation.instance.events.holdSafe.on(holdSafeHandler);
}
}
handlePlaybackCompletion(state) {
return __awaiter(this, void 0, void 0, function* () {
if (state === jibo_expression_client_1.AnimationState.REJECTED) {
log.warn(`Playback ${this.animation.name} was rejected! (See DOFArbiter debug for more details)`);
}
else if (this.options.forceReturnToIdle) {
log.debug(`Returning playback ${this.animation.name} to idle pose.`);
if (!Playback.DOFS_TO_CENTER) {
const dofs = this.jibo.expression.dofs;
Playback.DOFS_TO_CENTER = dofs.ALL.minus(dofs.BASE).minus(dofs.EYE_TRANSLATE);
}
yield this.jibo.expression.centerRobot({
requestor: this.options.ownerInformation,
dofs: Playback.DOFS_TO_CENTER,
centerGlobally: false
});
}
});
}
_cleanup() {
if (this.keysAnimation) {
if (this.hasScreenDOFs && !this.options.disableSetFaceAnim) {
this.jibo.face.eye.removeAnimation(this.keysAnimation);
}
else {
this.keysAnimation.destroy();
}
this.keysAnimation = null;
if (this.assetToken) {
this.assetToken.unload();
this.assetToken = null;
}
}
this.instance = null;
}
loadAnimation(andPlay = false) {
return __awaiter(this, void 0, void 0, function* () {
const id = this.filePath;
if (this.runtimeKeys) {
this.filePath = path.join(id, uuid.v4());
}
return new Promise((resolve, reject) => {
const load = this.jibo.loader.load({
id: id,
cache: this.cacheName,
options: this.config,
data: this.runtimeKeys ? this.animation.animData : null,
src: this.filePath,
upload: true,
root: this.animation.resourceRoot,
type: 'keys',
}, (error, keysData) => {
if (error) {
reject(error);
}
else {
if (!this.assetToken) {
return;
}
if (andPlay && this.options) {
resolve(keysData.getAndPlayAnim(Object.assign({ src: this.filePath }, this.config), this.options.ownerInformation));
}
else {
resolve(keysData.getAnim(Object.assign({ src: this.filePath }, this.config)));
}
}
});
this.assetToken = load.tokens[0];
});
});
}
}
exports.Playback = Playback;
},{"./AnimUtils":4,"./Classes":7,"./log":15,"events":undefined,"jibo-cai-utils":undefined,"jibo-expression-client":undefined,"path":undefined,"uuid":undefined}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.INFINITE_DURATION = 1e6;
class Range {
constructor(min, max) {
this.min = min;
this.max = max;
if (min > max) {
throw new Error(`Invalid bounds ${this.toString()}`);
}
}
toString() {
return `[${this.min}, ${this.max}]`;
}
limit(num) {
if (num < this.min) {
return this.min;
}
else if (num > this.max) {
return this.max;
}
else {
return num;
}
}
isUpperInfinite() {
return (this.max === exports.INFINITE_DURATION);
}
distanceFrom(num) {
if (num < this.min) {
return this.min - num;
}
else if (num > this.max) {
return num - this.max;
}
else {
return 0;
}
}
}
exports.Range = Range;
},{}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Classes_1 = require("./Classes");
let SemverUtils = require('semver-utils');
class Utils {
static parseString(input, defaultVal) {
if (!input || !(input.length)) {
return defaultVal;
}
return input;
}
static parseNumber(input, defaultVal) {
if (typeof input === 'number') {
return input;
}
if (!input || !(input.length)) {
return defaultVal;
}
try {
let num = parseFloat(input);
return num;
}
catch (e) {
return defaultVal;
}
}
static parseSemVer(input) {
let parse = SemverUtils.parse(input);
return {
semver: parse.semver,
version: parse.version,
major: parseInt(parse.major),
minor: parseInt(parse.minor),
patch: parseInt(parse.patch),
release: parse.release
};
}
static getAnimationsByQuery(animations, interimResults, query) {
animations.forEach(anim => {
if (Utils.audioMatch(anim, query.hasAudio) &&
Utils.catMatch(anim, query.includeCat, query.includeSomeCat, query.excludeCat) &&
Utils.metaMatch(anim, query.includeMeta, query.includeSomeMeta, query.excludeMeta)) {
Utils.addIfDurationMatch(anim, query.duration, query.durationError, interimResults);
}
});
}
static audioMatch(animation, shouldHaveAudio) {
return (shouldHaveAudio === Classes_1.HasAudio.DONT_CARE) ||
(shouldHaveAudio === Classes_1.HasAudio.YES && animation.meta.hasAudio) ||
(shouldHaveAudio === Classes_1.HasAudio.NO && !animation.meta.hasAudio);
}
static catMatch(animation, allOfCat, someOfCat, noneOfCat) {
const categories = animation.meta.categories;
const allOfMatch = (allOfCat.length > 0) ? allOfCat.every(cat => categories.indexOf(cat) !== -1) : true;
const someOfMatch = (someOfCat.length > 0) ? someOfCat.some(cat => categories.indexOf(cat) !== -1) : true;
const noneOfMatch = (noneOfCat.length > 0) ? noneOfCat.every(cat => categories.indexOf(cat) === -1) : true;
return (allOfMatch && someOfMatch && noneOfMatch);
}
static metaMatch(animation, allOfMeta, someOfMeta, noneOfMeta) {
const metas = animation.meta.metaTerms;
const allOfMatch = (allOfMeta.length > 0) ? allOfMeta.every(meta => metas.indexOf(meta) !== -1) : true;
const someOfMatch = (someOfMeta.length > 0) ? someOfMeta.some(meta => metas.indexOf(meta) !== -1) : true;
const noneOfMatch = (noneOfMeta.length > 0) ? noneOfMeta.every(meta => metas.indexOf(meta) === -1) : true;
return (allOfMatch && someOfMatch && noneOfMatch);
}
static addIfDurationMatch(animation, duration, durationError, res) {
if (duration === -1) {
res.matching.push(animation);
}
else {
let dist = Utils.distanceFromRange(duration, animation.meta.durationRange);
if (dist === 0) {
res.matching.push(animation);
}
else if (dist <= durationError) {
res.nonMatching.push(animation);
}
}
}
static limitToRange(num, range) {
if (num < range[0]) {
return range[0];
}
else if (num > range[1]) {
return range[1];
}
else {
return num;
}
}
static distanceFromRange(num, range) {
if (num < range[0]) {
return range[0] - num;
}
else if (num > range[1]) {
return num - range[1];
}
else {
return 0;
}
}
}
exports.Utils = Utils;
},{"./Classes":7,"semver-utils":undefined}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
},{}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
let generateId = require('jibo-keyframes').generateId;
class LayerTemplate {
static generateLayer(name, type) {
let layer = {};
layer.id = generateId();
layer.name = name;
layer.type = type;
layer.visible = true;
layer.locked = false;
layer.keyframes = [];
return layer;
}
}
exports.LayerTemplate = LayerTemplate;
},{"jibo-keyframes":undefined}],13:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./LayerMocks"));
const format_0_6_x = require("./0_6_X");
exports.format_0_6_x = format_0_6_x;
},{"./0_6_X":11,"./LayerMocks":12}],14:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fs = require("fs");
const AnimDBParser_1 = require("./AnimDBParser");
exports.AnimDBParser = AnimDBParser_1.AnimDBParser;
const AnimCollection_1 = require("./AnimCollection");
exports.AnimCollection = AnimCollection_1.AnimCollection;
const Animation_1 = require("./Animation");
exports.Animation = Animation_1.Animation;
const AnimDB_1 = require("./AnimDB");
exports.AnimDB = AnimDB_1.AnimDB;
const Playback_1 = require("./Playback");
exports.Playback = Playback_1.Playback;
__export(require("./animation_formats"));
__export(require("./Classes"));
function init(jibo, animDBPath, ...moreAnimDBPaths) {
return __awaiter(this, void 0, void 0, function* () {
if (!animDBPath) {
exports._animDB = new AnimDB_1.AnimDB(jibo);
}
else {
exports._animDB = yield AnimDBParser_1.AnimDBParser.readAnimDB(jibo, animDBPath, ...moreAnimDBPaths);
}
});
}
exports.init = init;
function isInitialized() {
return !!exports._animDB;
}
exports.isInitialized = isInitialized;
function resolveAnimDB(jibo, dir) {
let animDBPath;
let packjson;
if (!dir) {
const adaPath = jibo.utils.PathUtils.resolve('jibo-anim-db-animations');
dir = adaPath ? path.dirname(adaPath) : undefined;
}
try {
packjson = require(path.resolve(dir, 'package.json'));
}
catch (error) {
return undefined;
}
if (packjson && packjson.jibo) {
if (packjson.jibo.animdb && (path.extname(packjson.jibo.animdb).toLowerCase() === '.json')) {
animDBPath = path.resolve(dir, packjson.jibo.animdb);
}
else {
animDBPath = path.resolve(dir, 'animdb.json');
}
}
if (fs.existsSync(animDBPath)) {
return animDBPath;
}
return undefined;
}
exports.resolveAnimDB = resolveAnimDB;
function getAnimByName(animName) {
return exports._animDB.getAnimByName(animName);
}
exports.getAnimByName = getAnimByName;
function getAnimationNames() {
return exports._animDB.getAnimationNames();
}
exports.getAnimationNames = getAnimationNames;
function getAnimationCategories() {
return exports._animDB.getAnimationCategories();
}
exports.getAnimationCategories = getAnimationCategories;
function search(searchTerm) {
return exports._animDB.search(searchTerm);
}
exports.search = search;
function query(query) {
return exports._animDB.query(query);
}
exports.query = query;
function push(animCollection) {
exports._animDB.push(animCollection);
}
exports.push = push;
function pop() {
return exports._animDB.pop();
}
exports.pop = pop;
},{"./AnimCollection":1,"./AnimDB":2,"./AnimDBParser":3,"./Animation":5,"./Classes":7,"./Playback":8,"./animation_formats":13,"fs":undefined,"path":undefined}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jibo_log_1 = require("jibo-log");
exports.default = new jibo_log_1.Log('Jibo.AnimDB');
},{"jibo-log":undefined}],16:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./AnimDB"));
__export(require("./Range"));
__export(require("./AnimDBParser"));
__export(require("./AnimUtils"));
__export(require("./AnimCollection"));
__export(require("./Playback"));
__export(require("./Animation"));
__export(require("./Classes"));
__export(require("./AnimUtils"));
__export(require("./Utils"));
const api = require("./api");
exports.api = api;
const animation_formats = require("./animation_formats");
exports.animation_formats = animation_formats;
},{"./AnimCollection":1,"./AnimDB":2,"./AnimDBParser":3,"./AnimUtils":4,"./Animation":5,"./Classes":7,"./Playback":8,"./Range":9,"./Utils":10,"./animation_formats":13,"./api":14}],17:[function(require,module,exports){
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./main"));
},{"./main":16}]},{},[17])(17)
});
//# sourceMappingURL=jibo-anim-db.js.map