BlendCharacter.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. * @author Michael Guerrero / http://realitymeltdown.com
  3. */
  4. THREE.BlendCharacter = function () {
  5. this.weightSchedule = [];
  6. this.warpSchedule = [];
  7. this.load = function ( url, onLoad ) {
  8. var scope = this;
  9. var loader = new THREE.ObjectLoader();
  10. loader.load( url, function( loadedObject ) {
  11. // The exporter does not currently allow exporting a skinned mesh by itself
  12. // so we must fish it out of the hierarchy it is embedded in (scene)
  13. loadedObject.traverse( function( object ) {
  14. if ( object instanceof THREE.SkinnedMesh ) {
  15. scope.skinnedMesh = object;
  16. }
  17. } );
  18. THREE.SkinnedMesh.call( scope, scope.skinnedMesh.geometry, scope.skinnedMesh.material );
  19. // If we didn't successfully find the mesh, bail out
  20. if ( scope.skinnedMesh == undefined ) {
  21. console.log( 'unable to find skinned mesh in ' + url );
  22. return;
  23. }
  24. scope.material.skinning = true;
  25. scope.mixer = new THREE.AnimationMixer( scope );
  26. // Create the animations
  27. for ( var i = 0; i < scope.geometry.animations.length; ++ i ) {
  28. scope.mixer.clipAction( scope.geometry.animations[ i ] );
  29. }
  30. // Loading is complete, fire the callback
  31. if ( onLoad !== undefined ) onLoad();
  32. } );
  33. };
  34. this.loadJSON = function ( url, onLoad ) {
  35. var scope = this;
  36. var loader = new THREE.JSONLoader();
  37. loader.load( url, function( geometry, materials ) {
  38. var originalMaterial = materials[ 0 ];
  39. originalMaterial.skinning = true;
  40. THREE.SkinnedMesh.call( scope, geometry, originalMaterial );
  41. var mixer = new THREE.AnimationMixer( scope );
  42. scope.mixer = mixer;
  43. // Create the animations
  44. for ( var i = 0; i < geometry.animations.length; ++ i ) {
  45. mixer.clipAction( geometry.animations[ i ] );
  46. }
  47. // Loading is complete, fire the callback
  48. if ( onLoad !== undefined ) onLoad();
  49. } );
  50. };
  51. this.update = function( dt ) {
  52. this.mixer.update( dt );
  53. };
  54. this.play = function( animName, weight ) {
  55. //console.log("play('%s', %f)", animName, weight);
  56. return this.mixer.clipAction( animName ).
  57. setEffectiveWeight( weight ).play();
  58. };
  59. this.crossfade = function( fromAnimName, toAnimName, duration ) {
  60. this.mixer.stopAllAction();
  61. var fromAction = this.play( fromAnimName, 1 );
  62. var toAction = this.play( toAnimName, 1 );
  63. fromAction.crossFadeTo( toAction, duration, false );
  64. };
  65. this.warp = function( fromAnimName, toAnimName, duration ) {
  66. this.mixer.stopAllAction();
  67. var fromAction = this.play( fromAnimName, 1 );
  68. var toAction = this.play( toAnimName, 1 );
  69. fromAction.crossFadeTo( toAction, duration, true );
  70. };
  71. this.applyWeight = function( animName, weight ) {
  72. this.mixer.clipAction( animName ).setEffectiveWeight( weight );
  73. };
  74. this.getWeight = function( animName ) {
  75. return this.mixer.clipAction( animName ).getEffectiveWeight();
  76. };
  77. this.pauseAll = function() {
  78. this.mixer.timeScale = 0;
  79. };
  80. this.unPauseAll = function() {
  81. this.mixer.timeScale = 1;
  82. };
  83. this.stopAll = function() {
  84. this.mixer.stopAllAction();
  85. };
  86. this.showModel = function( boolean ) {
  87. this.visible = boolean;
  88. };
  89. };
  90. THREE.BlendCharacter.prototype = Object.create( THREE.SkinnedMesh.prototype );
  91. THREE.BlendCharacter.prototype.constructor = THREE.BlendCharacter;
  92. THREE.BlendCharacter.prototype.getForward = function() {
  93. var forward = new THREE.Vector3();
  94. return function() {
  95. // pull the character's forward basis vector out of the matrix
  96. forward.set(
  97. - this.matrix.elements[ 8 ],
  98. - this.matrix.elements[ 9 ],
  99. - this.matrix.elements[ 10 ]
  100. );
  101. return forward;
  102. }
  103. };