AnimationAction.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. *
  3. * A clip that has been explicitly scheduled.
  4. *
  5. * @author Ben Houston / http://clara.io/
  6. * @author David Sarno / http://lighthaus.us/
  7. */
  8. THREE.AnimationAction = function ( clip, startTime, timeScale, weight, loop ) {
  9. if ( clip === undefined ) throw new Error( 'clip is null' );
  10. this.clip = clip;
  11. this.localRoot = null;
  12. this.startTime = startTime || 0;
  13. this.timeScale = timeScale || 1;
  14. this.weight = weight || 1;
  15. this.loop = loop || THREE.LoopRepeat;
  16. this.loopCount = 0;
  17. this.enabled = true; // allow for easy disabling of the action.
  18. this.actionTime = - this.startTime;
  19. this.clipTime = 0;
  20. this.propertyBindings = [];
  21. };
  22. /*
  23. THREE.LoopOnce = 2200;
  24. THREE.LoopRepeat = 2201;
  25. THREE.LoopPingPing = 2202;
  26. */
  27. THREE.AnimationAction.prototype = {
  28. constructor: THREE.AnimationAction,
  29. setLocalRoot: function( localRoot ) {
  30. this.localRoot = localRoot;
  31. return this;
  32. },
  33. updateTime: function( clipDeltaTime ) {
  34. var previousClipTime = this.clipTime;
  35. var previousLoopCount = this.loopCount;
  36. var previousActionTime = this.actionTime;
  37. var duration = this.clip.duration;
  38. this.actionTime = this.actionTime + clipDeltaTime;
  39. if ( this.loop === THREE.LoopOnce ) {
  40. this.loopCount = 0;
  41. this.clipTime = Math.min( Math.max( this.actionTime, 0 ), duration );
  42. // if time is changed since last time, see if we have hit a start/end limit
  43. if ( this.clipTime !== previousClipTime ) {
  44. if ( this.clipTime === duration ) {
  45. this.mixer.dispatchEvent( { type: 'finished', action: this, direction: 1 } );
  46. } else if ( this.clipTime === 0 ) {
  47. this.mixer.dispatchEvent( { type: 'finished', action: this, direction: -1 } );
  48. }
  49. }
  50. return this.clipTime;
  51. }
  52. this.loopCount = Math.floor( this.actionTime / duration );
  53. var newClipTime = this.actionTime - this.loopCount * duration;
  54. newClipTime = newClipTime % duration;
  55. // if we are ping pong looping, ensure that we go backwards when appropriate
  56. if ( this.loop == THREE.LoopPingPong ) {
  57. if ( Math.abs( this.loopCount % 2 ) === 1 ) {
  58. newClipTime = duration - newClipTime;
  59. }
  60. }
  61. this.clipTime = newClipTime;
  62. if ( this.loopCount !== previousLoopCount ) {
  63. this.mixer.dispatchEvent( { type: 'loop', action: this, loopDelta: ( this.loopCount - this.loopCount ) } );
  64. }
  65. return this.clipTime;
  66. },
  67. syncWith: function( action ) {
  68. this.actionTime = action.actionTime;
  69. this.timeScale = action.timeScale;
  70. return this;
  71. },
  72. warpToDuration: function( duration ) {
  73. this.timeScale = this.clip.duration / duration;
  74. return this;
  75. },
  76. init: function( time ) {
  77. this.clipTime = time - this.startTime;
  78. return this;
  79. },
  80. update: function( clipDeltaTime ) {
  81. this.updateTime( clipDeltaTime );
  82. var clipResults = this.clip.getAt( this.clipTime );
  83. return clipResults;
  84. },
  85. getTimeScaleAt: function( time ) {
  86. if ( this.timeScale.getAt ) {
  87. // pass in time, not clip time, allows for fadein/fadeout across multiple loops of the clip
  88. return this.timeScale.getAt( time );
  89. }
  90. return this.timeScale;
  91. },
  92. getWeightAt: function( time ) {
  93. if ( this.weight.getAt ) {
  94. // pass in time, not clip time, allows for fadein/fadeout across multiple loops of the clip
  95. return this.weight.getAt( time );
  96. }
  97. return this.weight;
  98. }
  99. };