| 312 | |
| 313 | // Interpolate between two arbitrary values/objects. |
| 314 | function process(from, to) { |
| 315 | |
| 316 | // Handle default cases. |
| 317 | if (to === undefined) { |
| 318 | to = from; |
| 319 | } |
| 320 | if (from === undefined) { |
| 321 | from = to; |
| 322 | } |
| 323 | if (to === from) { |
| 324 | return from; |
| 325 | } |
| 326 | |
| 327 | // Sanity type check. |
| 328 | if (typeof from != typeof to) { |
| 329 | console.log(object, key) |
| 330 | throw "Data type mismatch between from/to values in animator. "+ key +': '+ from + ' ('+ from.constructor +')' + ", " + to + "("+ to.constructor +")"; |
| 331 | } |
| 332 | |
| 333 | // Type-specific behavior. |
| 334 | var out; |
| 335 | switch (typeof to) { |
| 336 | default: |
| 337 | case 'string': |
| 338 | throw "Unimplemented value type in animator. ("+(typeof to)+")"; |
| 339 | |
| 340 | case 'function': |
| 341 | return function () { |
| 342 | return process(from.apply(this, arguments), to.apply(this, arguments)); |
| 343 | }; |
| 344 | |
| 345 | case 'boolean': |
| 346 | return (fraction > .5) ? to : from; |
| 347 | |
| 348 | case 'number': |
| 349 | return lerp(from, to); |
| 350 | |
| 351 | case 'object': |
| 352 | if (!from) { |
| 353 | return to; |
| 354 | } |
| 355 | if (!to) { |
| 356 | return from; |
| 357 | } |
| 358 | if (to.constructor == Array) { |
| 359 | out = []; |
| 360 | _.loop(from.length, function (i) { |
| 361 | out[i] = process(from[i], to[i]); |
| 362 | }) |
| 363 | return out; |
| 364 | } |
| 365 | if (to.constructor == THREE.Matrix4) { |
| 366 | out = new THREE.Matrix4() |
| 367 | for (var i = 0; i < 16; ++i) { |
| 368 | out.elements[i] = lerp(from.elements[i], to.elements[i]); |
| 369 | } |
| 370 | return out; |
| 371 | } |