BlendCharacter.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * @author Michael Guerrero / http://realitymeltdown.com
  3. */
  4. THREE.BlendCharacter = function () {
  5. this.animations = {};
  6. this.weightSchedule = [];
  7. this.warpSchedule = [];
  8. this.load = function ( url, onLoad ) {
  9. var scope = this;
  10. var loader = new THREE.JSONLoader();
  11. loader.load( url, function( geometry, materials ) {
  12. var originalMaterial = materials[ 0 ];
  13. originalMaterial.skinning = true;
  14. THREE.SkinnedMesh.call( scope, geometry, originalMaterial );
  15. scope.mixer = new THREE.AnimationMixer( scope );
  16. // Create the animations
  17. for ( var i = 0; i < geometry.animations.length; ++ i ) {
  18. var animName = geometry.animations[ i ].name;
  19. scope.animations[ animName ] = THREE.AnimationClip.FromJSONLoaderAnimation( geometry.animations[ i ], geometry.bones );
  20. }
  21. // Loading is complete, fire the callback
  22. if ( onLoad !== undefined ) onLoad();
  23. } );
  24. };
  25. this.update = function( dt ) {
  26. scope.mixer.update( dt );
  27. };
  28. this.play = function( animName, weight ) {
  29. this.removeAllActions();
  30. this.mixer.play( new THREE.AnimationAction( this.animations[ animName ], 0, 1, 1, true ) );
  31. };
  32. this.crossfade = function( fromAnimName, toAnimName, duration ) {
  33. var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ], 0, 1, 1, true );
  34. var toAction = new THREE.AnimationAction( this.animations[ toAnimName ], 0, 1, 1, true );
  35. this.mixer.play( fromAction );
  36. this.mixer.play( toAction );
  37. this.mixer.crossFade( fromAction, toAction, duration, false );
  38. };
  39. this.warp = function( fromAnimName, toAnimName, duration ) {
  40. var fromAction = new THREE.AnimationAction( this.animations[ fromAnimName ], 0, 1, 1, true );
  41. var toAction = new THREE.AnimationAction( this.animations[ toAnimName ], 0, 1, 1, true );
  42. this.mixer.play( fromAction );
  43. this.mixer.play( toAction );
  44. this.mixer.crossFade( fromAction, toAction, duration, true );
  45. };
  46. this.applyWeight = function( animName, weight ) {
  47. if( this.mixer[ animName ] ) {
  48. this.mixer[ animName ].weight = weight;
  49. }
  50. };
  51. this.pauseAll = function() {
  52. this.mixer.timeScale = 0;
  53. };
  54. this.unPauseAll = function() {
  55. this.mixer.timeScale = 1;
  56. };
  57. this.stopAll = function() {
  58. this.removeAllActions();
  59. };
  60. this.showModel = function( boolean ) {
  61. this.visible = boolean;
  62. }
  63. };
  64. THREE.BlendCharacter.prototype = Object.create( THREE.SkinnedMesh.prototype );
  65. THREE.BlendCharacter.prototype.constructor = THREE.BlendCharacter;
  66. THREE.BlendCharacter.prototype.getForward = function() {
  67. var forward = new THREE.Vector3();
  68. return function() {
  69. // pull the character's forward basis vector out of the matrix
  70. forward.set(
  71. - this.matrix.elements[ 8 ],
  72. - this.matrix.elements[ 9 ],
  73. - this.matrix.elements[ 10 ]
  74. );
  75. return forward;
  76. }
  77. };