MorphAnimMesh.js 3.6 KB

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