Doodle3D-Slicer/three.js-master/examples/js/loaders/gltf/glTFAnimation.js
2015-06-12 15:58:26 +02:00

252 lines
5.2 KiB
JavaScript
Executable File

/**
* @author Tony Parisi / http://www.tonyparisi.com/
*/
THREE.glTFAnimator = ( function () {
var animators = [];
return {
add : function(animator)
{
animators.push(animator);
},
remove: function(animator)
{
var i = animators.indexOf(animator);
if ( i !== -1 ) {
animators.splice( i, 1 );
}
},
update : function()
{
for (i = 0; i < animators.length; i ++)
{
animators[i].update();
}
},
};
})();
// Construction/initialization
THREE.glTFAnimation = function(interps)
{
this.running = false;
this.loop = false;
this.duration = 0;
this.startTime = 0;
this.interps = [];
if (interps)
{
this.createInterpolators(interps);
}
}
THREE.glTFAnimation.prototype.createInterpolators = function(interps)
{
var i, len = interps.length;
for (i = 0; i < len; i ++)
{
var interp = new THREE.glTFInterpolator(interps[i]);
this.interps.push(interp);
this.duration = Math.max(this.duration, interp.duration);
}
}
// Start/stop
THREE.glTFAnimation.prototype.play = function()
{
if (this.running)
return;
this.startTime = Date.now();
this.running = true;
THREE.glTFAnimator.add(this);
}
THREE.glTFAnimation.prototype.stop = function()
{
this.running = false;
THREE.glTFAnimator.remove(this);
}
// Update - drive key frame evaluation
THREE.glTFAnimation.prototype.update = function()
{
if (!this.running)
return;
var now = Date.now();
var deltat = (now - this.startTime) / 1000;
var t = deltat % this.duration;
var nCycles = Math.floor(deltat / this.duration);
if (nCycles >= 1 && !this.loop)
{
this.running = false;
var i, len = this.interps.length;
for (i = 0; i < len; i ++)
{
this.interps[i].interp(this.duration);
}
this.stop();
return;
}
else
{
var i, len = this.interps.length;
for (i = 0; i < len; i ++)
{
this.interps[i].interp(t);
}
}
}
//Interpolator class
//Construction/initialization
THREE.glTFInterpolator = function(param)
{
this.keys = param.keys;
this.values = param.values;
this.count = param.count;
this.type = param.type;
this.path = param.path;
this.isRot = false;
var node = param.target;
node.updateMatrix();
node.matrixAutoUpdate = true;
this.targetNode = node;
switch (param.path) {
case "translation" :
this.target = node.position;
this.originalValue = node.position.clone();
break;
case "rotation" :
this.target = node.quaternion;
this.originalValue = node.quaternion.clone();
this.isRot = true;
break;
case "scale" :
this.target = node.scale;
this.originalValue = node.scale.clone();
break;
}
this.duration = this.keys[this.count - 1];
this.vec1 = new THREE.Vector3;
this.vec2 = new THREE.Vector3;
this.vec3 = new THREE.Vector3;
this.quat1 = new THREE.Quaternion;
this.quat2 = new THREE.Quaternion;
this.quat3 = new THREE.Quaternion;
}
//Interpolation and tweening methods
THREE.glTFInterpolator.prototype.interp = function(t)
{
var i, j;
if (t == this.keys[0])
{
if (this.isRot) {
this.quat3.set(this.values[0], this.values[1], this.values[2], this.values[3]);
}
else {
this.vec3.set(this.values[0], this.values[1], this.values[2]);
}
}
else if (t < this.keys[0])
{
if (this.isRot) {
this.quat1.set(this.originalValue.x,
this.originalValue.y,
this.originalValue.z,
this.originalValue.w);
this.quat2.set(this.values[0],
this.values[1],
this.values[2],
this.values[3]);
THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, t / this.keys[0]);
}
else {
this.vec3.set(this.originalValue.x,
this.originalValue.y,
this.originalValue.z);
this.vec2.set(this.values[0],
this.values[1],
this.values[2]);
this.vec3.lerp(this.vec2, t / this.keys[0]);
}
}
else if (t >= this.keys[this.count - 1])
{
if (this.isRot) {
this.quat3.set(this.values[(this.count - 1) * 4],
this.values[(this.count - 1) * 4 + 1],
this.values[(this.count - 1) * 4 + 2],
this.values[(this.count - 1) * 4 + 3]);
}
else {
this.vec3.set(this.values[(this.count - 1) * 3],
this.values[(this.count - 1) * 3 + 1],
this.values[(this.count - 1) * 3 + 2]);
}
}
else
{
for (i = 0; i < this.count - 1; i ++)
{
var key1 = this.keys[i];
var key2 = this.keys[i + 1];
if (t >= key1 && t <= key2)
{
if (this.isRot) {
this.quat1.set(this.values[i * 4],
this.values[i * 4 + 1],
this.values[i * 4 + 2],
this.values[i * 4 + 3]);
this.quat2.set(this.values[(i + 1) * 4],
this.values[(i + 1) * 4 + 1],
this.values[(i + 1) * 4 + 2],
this.values[(i + 1) * 4 + 3]);
THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, (t - key1) / (key2 - key1));
}
else {
this.vec3.set(this.values[i * 3],
this.values[i * 3 + 1],
this.values[i * 3 + 2]);
this.vec2.set(this.values[(i + 1) * 3],
this.values[(i + 1) * 3 + 1],
this.values[(i + 1) * 3 + 2]);
this.vec3.lerp(this.vec2, (t - key1) / (key2 - key1));
}
}
}
}
if (this.target)
{
this.copyValue(this.target);
}
}
THREE.glTFInterpolator.prototype.copyValue = function(target) {
if (this.isRot) {
target.copy(this.quat3);
}
else {
target.copy(this.vec3);
}
}