KeyFrameAnimation.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /**
  2. * @author mikael emtinger / http://gomo.se/
  3. * @author mrdoob / http://mrdoob.com/
  4. * @author alteredq / http://alteredqualia.com/
  5. * @author khang duong
  6. * @author erik kitson
  7. */
  8. THREE.KeyFrameAnimation = function ( root, data ) {
  9. this.root = root;
  10. this.data = THREE.AnimationHandler.get( data );
  11. this.hierarchy = THREE.AnimationHandler.parse( root );
  12. this.currentTime = 0;
  13. this.timeScale = 0.001;
  14. this.isPlaying = false;
  15. this.isPaused = true;
  16. this.loop = true;
  17. // initialize to first keyframes
  18. for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
  19. var keys = this.data.hierarchy[h].keys,
  20. sids = this.data.hierarchy[h].sids,
  21. obj = this.hierarchy[h];
  22. if ( keys.length && sids ) {
  23. for ( var s = 0; s < sids.length; s++ ) {
  24. var sid = sids[ s ],
  25. next = this.getNextKeyWith( sid, h, 0 );
  26. if ( next ) {
  27. next.apply( sid );
  28. }
  29. }
  30. obj.matrixAutoUpdate = false;
  31. this.data.hierarchy[h].node.updateMatrix();
  32. obj.matrixWorldNeedsUpdate = true;
  33. }
  34. }
  35. };
  36. // Play
  37. THREE.KeyFrameAnimation.prototype.play = function ( startTime ) {
  38. this.currentTime = startTime !== undefined ? startTime : 0;
  39. if ( this.isPlaying === false ) {
  40. this.isPlaying = true;
  41. // reset key cache
  42. var h, hl = this.hierarchy.length,
  43. object,
  44. node;
  45. for ( h = 0; h < hl; h++ ) {
  46. object = this.hierarchy[ h ];
  47. node = this.data.hierarchy[ h ];
  48. if ( node.animationCache === undefined ) {
  49. node.animationCache = {};
  50. node.animationCache.prevKey = null;
  51. node.animationCache.nextKey = null;
  52. node.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
  53. }
  54. var keys = this.data.hierarchy[h].keys;
  55. if (keys.length) {
  56. node.animationCache.prevKey = keys[ 0 ];
  57. node.animationCache.nextKey = keys[ 1 ];
  58. this.startTime = Math.min( keys[0].time, this.startTime );
  59. this.endTime = Math.max( keys[keys.length - 1].time, this.endTime );
  60. }
  61. }
  62. this.update( 0 );
  63. }
  64. this.isPaused = false;
  65. THREE.AnimationHandler.addToUpdate( this );
  66. };
  67. // Pause
  68. THREE.KeyFrameAnimation.prototype.pause = function() {
  69. if( this.isPaused ) {
  70. THREE.AnimationHandler.addToUpdate( this );
  71. } else {
  72. THREE.AnimationHandler.removeFromUpdate( this );
  73. }
  74. this.isPaused = !this.isPaused;
  75. };
  76. // Stop
  77. THREE.KeyFrameAnimation.prototype.stop = function() {
  78. this.isPlaying = false;
  79. this.isPaused = false;
  80. THREE.AnimationHandler.removeFromUpdate( this );
  81. // reset JIT matrix and remove cache
  82. for ( var h = 0; h < this.data.hierarchy.length; h++ ) {
  83. var obj = this.hierarchy[ h ];
  84. var node = this.data.hierarchy[ h ];
  85. if ( node.animationCache !== undefined ) {
  86. var original = node.animationCache.originalMatrix;
  87. if( obj instanceof THREE.Bone ) {
  88. original.copy( obj.skinMatrix );
  89. obj.skinMatrix = original;
  90. } else {
  91. original.copy( obj.matrix );
  92. obj.matrix = original;
  93. }
  94. delete node.animationCache;
  95. }
  96. }
  97. };
  98. // Update
  99. THREE.KeyFrameAnimation.prototype.update = function ( delta ) {
  100. if ( this.isPlaying === false ) return;
  101. this.currentTime += delta * this.timeScale;
  102. //
  103. var duration = this.data.length;
  104. var currentTime = this.currentTime;
  105. if ( this.loop === true ) {
  106. currentTime %= duration;
  107. }
  108. currentTime = Math.min( currentTime, duration );
  109. for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
  110. var object = this.hierarchy[ h ];
  111. var node = this.data.hierarchy[ h ];
  112. var keys = node.keys,
  113. animationCache = node.animationCache;
  114. if ( keys.length ) {
  115. var prevKey = animationCache.prevKey;
  116. var nextKey = animationCache.nextKey;
  117. if ( nextKey.time <= currentTime ) {
  118. while ( nextKey.time < currentTime && nextKey.index > prevKey.index ) {
  119. prevKey = nextKey;
  120. nextKey = keys[ prevKey.index + 1 ];
  121. }
  122. animationCache.prevKey = prevKey;
  123. animationCache.nextKey = nextKey;
  124. }
  125. if ( nextKey.time >= currentTime ) {
  126. prevKey.interpolate( nextKey, currentTime );
  127. } else {
  128. prevKey.interpolate( nextKey, nextKey.time );
  129. }
  130. this.data.hierarchy[ h ].node.updateMatrix();
  131. object.matrixWorldNeedsUpdate = true;
  132. }
  133. }
  134. };
  135. // Get next key with
  136. THREE.KeyFrameAnimation.prototype.getNextKeyWith = function( sid, h, key ) {
  137. var keys = this.data.hierarchy[ h ].keys;
  138. key = key % keys.length;
  139. for ( ; key < keys.length; key++ ) {
  140. if ( keys[ key ].hasTarget( sid ) ) {
  141. return keys[ key ];
  142. }
  143. }
  144. return keys[ 0 ];
  145. };
  146. // Get previous key with
  147. THREE.KeyFrameAnimation.prototype.getPrevKeyWith = function( sid, h, key ) {
  148. var keys = this.data.hierarchy[ h ].keys;
  149. key = key >= 0 ? key : key + keys.length;
  150. for ( ; key >= 0; key-- ) {
  151. if ( keys[ key ].hasTarget( sid ) ) {
  152. return keys[ key ];
  153. }
  154. }
  155. return keys[ keys.length - 1 ];
  156. };
粤ICP备19079148号