MorphAnimMesh.js 3.5 KB

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