glTFAnimation.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /**
  2. * @author Tony Parisi / http://www.tonyparisi.com/
  3. */
  4. THREE.glTFAnimator = ( function () {
  5. var animators = [];
  6. return {
  7. add : function(animator)
  8. {
  9. animators.push(animator);
  10. },
  11. remove: function(animator)
  12. {
  13. var i = animators.indexOf(animator);
  14. if ( i !== -1 ) {
  15. animators.splice( i, 1 );
  16. }
  17. },
  18. update : function()
  19. {
  20. for (i = 0; i < animators.length; i++)
  21. {
  22. animators[i].update();
  23. }
  24. },
  25. };
  26. })();
  27. // Construction/initialization
  28. THREE.glTFAnimation = function(interps)
  29. {
  30. this.running = false;
  31. this.loop = false;
  32. this.duration = 0;
  33. this.startTime = 0;
  34. this.interps = [];
  35. if (interps)
  36. {
  37. this.createInterpolators(interps);
  38. }
  39. }
  40. THREE.glTFAnimation.prototype.createInterpolators = function(interps)
  41. {
  42. var i, len = interps.length;
  43. for (i = 0; i < len; i++)
  44. {
  45. var interp = new THREE.glTFInterpolator(interps[i]);
  46. this.interps.push(interp);
  47. this.duration = Math.max(this.duration, interp.duration);
  48. }
  49. }
  50. // Start/stop
  51. THREE.glTFAnimation.prototype.play = function()
  52. {
  53. if (this.running)
  54. return;
  55. this.startTime = Date.now();
  56. this.running = true;
  57. THREE.glTFAnimator.add(this);
  58. }
  59. THREE.glTFAnimation.prototype.stop = function()
  60. {
  61. this.running = false;
  62. THREE.glTFAnimator.remove(this);
  63. }
  64. // Update - drive key frame evaluation
  65. THREE.glTFAnimation.prototype.update = function()
  66. {
  67. if (!this.running)
  68. return;
  69. var now = Date.now();
  70. var deltat = (now - this.startTime) / 1000;
  71. var t = deltat % this.duration;
  72. var nCycles = Math.floor(deltat / this.duration);
  73. if (nCycles >= 1 && !this.loop)
  74. {
  75. this.running = false;
  76. var i, len = this.interps.length;
  77. for (i = 0; i < len; i++)
  78. {
  79. this.interps[i].interp(this.duration);
  80. }
  81. this.stop();
  82. return;
  83. }
  84. else
  85. {
  86. var i, len = this.interps.length;
  87. for (i = 0; i < len; i++)
  88. {
  89. this.interps[i].interp(t);
  90. }
  91. }
  92. }
  93. //Interpolator class
  94. //Construction/initialization
  95. THREE.glTFInterpolator = function(param)
  96. {
  97. this.keys = param.keys;
  98. this.values = param.values;
  99. this.count = param.count;
  100. this.type = param.type;
  101. this.path = param.path;
  102. this.isRot = false;
  103. var node = param.target;
  104. node.updateMatrix();
  105. node.matrixAutoUpdate = true;
  106. this.targetNode = node;
  107. switch (param.path) {
  108. case "translation" :
  109. this.target = node.position;
  110. this.originalValue = node.position.clone();
  111. break;
  112. case "rotation" :
  113. this.target = node.quaternion;
  114. this.originalValue = node.quaternion.clone();
  115. this.isRot = true;
  116. break;
  117. case "scale" :
  118. this.target = node.scale;
  119. this.originalValue = node.scale.clone();
  120. break;
  121. }
  122. this.duration = this.keys[this.count - 1];
  123. this.vec1 = new THREE.Vector3;
  124. this.vec2 = new THREE.Vector3;
  125. this.vec3 = new THREE.Vector3;
  126. this.quat1 = new THREE.Quaternion;
  127. this.quat2 = new THREE.Quaternion;
  128. this.quat3 = new THREE.Quaternion;
  129. }
  130. //Interpolation and tweening methods
  131. THREE.glTFInterpolator.prototype.interp = function(t)
  132. {
  133. var i, j;
  134. if (t == this.keys[0])
  135. {
  136. if (this.isRot) {
  137. this.quat3.set(this.values[0], this.values[1], this.values[2], this.values[3]);
  138. }
  139. else {
  140. this.vec3.set(this.values[0], this.values[1], this.values[2]);
  141. }
  142. }
  143. else if (t < this.keys[0])
  144. {
  145. if (this.isRot) {
  146. this.quat1.set(this.originalValue.x,
  147. this.originalValue.y,
  148. this.originalValue.z,
  149. this.originalValue.w);
  150. this.quat2.set(this.values[0],
  151. this.values[1],
  152. this.values[2],
  153. this.values[3]);
  154. THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, t / this.keys[0]);
  155. }
  156. else {
  157. this.vec3.set(this.originalValue.x,
  158. this.originalValue.y,
  159. this.originalValue.z);
  160. this.vec2.set(this.values[0],
  161. this.values[1],
  162. this.values[2]);
  163. this.vec3.lerp(this.vec2, t / this.keys[0]);
  164. }
  165. }
  166. else if (t >= this.keys[this.count - 1])
  167. {
  168. if (this.isRot) {
  169. this.quat3.set(this.values[(this.count - 1) * 4],
  170. this.values[(this.count - 1) * 4 + 1],
  171. this.values[(this.count - 1) * 4 + 2],
  172. this.values[(this.count - 1) * 4 + 3]);
  173. }
  174. else {
  175. this.vec3.set(this.values[(this.count - 1) * 3],
  176. this.values[(this.count - 1) * 3 + 1],
  177. this.values[(this.count - 1) * 3 + 2]);
  178. }
  179. }
  180. else
  181. {
  182. for (i = 0; i < this.count - 1; i++)
  183. {
  184. var key1 = this.keys[i];
  185. var key2 = this.keys[i + 1];
  186. if (t >= key1 && t <= key2)
  187. {
  188. if (this.isRot) {
  189. this.quat1.set(this.values[i * 4],
  190. this.values[i * 4 + 1],
  191. this.values[i * 4 + 2],
  192. this.values[i * 4 + 3]);
  193. this.quat2.set(this.values[(i + 1) * 4],
  194. this.values[(i + 1) * 4 + 1],
  195. this.values[(i + 1) * 4 + 2],
  196. this.values[(i + 1) * 4 + 3]);
  197. THREE.Quaternion.slerp(this.quat1, this.quat2, this.quat3, (t - key1) / (key2 - key1));
  198. }
  199. else {
  200. this.vec3.set(this.values[i * 3],
  201. this.values[i * 3 + 1],
  202. this.values[i * 3 + 2]);
  203. this.vec2.set(this.values[(i + 1) * 3],
  204. this.values[(i + 1) * 3 + 1],
  205. this.values[(i + 1) * 3 + 2]);
  206. this.vec3.lerp(this.vec2, (t - key1) / (key2 - key1));
  207. }
  208. }
  209. }
  210. }
  211. if (this.target)
  212. {
  213. this.copyValue(this.target);
  214. }
  215. }
  216. THREE.glTFInterpolator.prototype.copyValue = function(target) {
  217. if (this.isRot) {
  218. target.copy(this.quat3);
  219. }
  220. else {
  221. target.copy(this.vec3);
  222. }
  223. }