123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /**
- * @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);
- }
- }
|