MorphAnimMesh.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. */
  4. THREE.MorphAnimMesh = function ( geometry, material ) {
  5. THREE.Mesh.call( this, geometry, material );
  6. this.type = 'MorphAnimMesh';
  7. // API
  8. this.duration = 1000; // milliseconds
  9. this.mirroredLoop = false;
  10. this.time = 0;
  11. // internals
  12. this.lastKeyframe = 0;
  13. this.currentKeyframe = 0;
  14. this.direction = 1;
  15. this.directionBackwards = false;
  16. this.setFrameRange( 0, this.geometry.morphTargets.length - 1 );
  17. };
  18. THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
  19. THREE.MorphAnimMesh.prototype.constructor = THREE.MorphAnimMesh;
  20. THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) {
  21. this.startKeyframe = start;
  22. this.endKeyframe = end;
  23. this.length = this.endKeyframe - this.startKeyframe + 1;
  24. };
  25. THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
  26. this.direction = 1;
  27. this.directionBackwards = false;
  28. };
  29. THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
  30. this.direction = - 1;
  31. this.directionBackwards = true;
  32. };
  33. THREE.MorphAnimMesh.prototype.parseAnimations = function () {
  34. var geometry = this.geometry;
  35. if ( ! geometry.animations ) geometry.animations = {};
  36. var firstAnimation, animations = geometry.animations;
  37. var pattern = /([a-z]+)_?(\d+)/;
  38. for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
  39. var morph = geometry.morphTargets[ i ];
  40. var parts = morph.name.match( pattern );
  41. if ( parts && parts.length > 1 ) {
  42. var label = parts[ 1 ];
  43. var num = parts[ 2 ];
  44. if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: - Infinity };
  45. var animation = animations[ label ];
  46. if ( i < animation.start ) animation.start = i;
  47. if ( i > animation.end ) animation.end = i;
  48. if ( ! firstAnimation ) firstAnimation = label;
  49. }
  50. }
  51. geometry.firstAnimation = firstAnimation;
  52. };
  53. THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) {
  54. if ( ! this.geometry.animations ) this.geometry.animations = {};
  55. this.geometry.animations[ label ] = { start: start, end: end };
  56. };
  57. THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
  58. var animation = this.geometry.animations[ label ];
  59. if ( animation ) {
  60. this.setFrameRange( animation.start, animation.end );
  61. this.duration = 1000 * ( ( animation.end - animation.start ) / fps );
  62. this.time = 0;
  63. } else {
  64. THREE.warning( 'THREE.MorphAnimMesh: animation[' + label + '] undefined in .playAnimation()' );
  65. }
  66. };
  67. THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
  68. var frameTime = this.duration / this.length;
  69. this.time += this.direction * delta;
  70. if ( this.mirroredLoop ) {
  71. if ( this.time > this.duration || this.time < 0 ) {
  72. this.direction *= - 1;
  73. if ( this.time > this.duration ) {
  74. this.time = this.duration;
  75. this.directionBackwards = true;
  76. }
  77. if ( this.time < 0 ) {
  78. this.time = 0;
  79. this.directionBackwards = false;
  80. }
  81. }
  82. } else {
  83. this.time = this.time % this.duration;
  84. if ( this.time < 0 ) this.time += this.duration;
  85. }
  86. var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 );
  87. if ( keyframe !== this.currentKeyframe ) {
  88. this.morphTargetInfluences[ this.lastKeyframe ] = 0;
  89. this.morphTargetInfluences[ this.currentKeyframe ] = 1;
  90. this.morphTargetInfluences[ keyframe ] = 0;
  91. this.lastKeyframe = this.currentKeyframe;
  92. this.currentKeyframe = keyframe;
  93. }
  94. var mix = ( this.time % frameTime ) / frameTime;
  95. if ( this.directionBackwards ) {
  96. mix = 1 - mix;
  97. }
  98. this.morphTargetInfluences[ this.currentKeyframe ] = mix;
  99. this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix;
  100. };
  101. THREE.MorphAnimMesh.prototype.interpolateTargets = function ( a, b, t ) {
  102. var influences = this.morphTargetInfluences;
  103. for ( var i = 0, l = influences.length; i < l; i ++ ) {
  104. influences[ i ] = 0;
  105. }
  106. if ( a > -1 ) influences[ a ] = 1 - t;
  107. if ( b > -1 ) influences[ b ] = t;
  108. };
  109. THREE.MorphAnimMesh.prototype.clone = function ( object ) {
  110. if ( object === undefined ) object = new THREE.MorphAnimMesh( this.geometry, this.material );
  111. object.duration = this.duration;
  112. object.mirroredLoop = this.mirroredLoop;
  113. object.time = this.time;
  114. object.lastKeyframe = this.lastKeyframe;
  115. object.currentKeyframe = this.currentKeyframe;
  116. object.direction = this.direction;
  117. object.directionBackwards = this.directionBackwards;
  118. THREE.Mesh.prototype.clone.call( this, object );
  119. return object;
  120. };
粤ICP备19079148号