BlendCharacterGui.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /**
  2. * @author Michael Guerrero / http://realitymeltdown.com
  3. */
  4. function BlendCharacterGui( blendMesh ) {
  5. var controls = {
  6. gui: null,
  7. "Show Model": true,
  8. "Show Skeleton": false,
  9. "Time Scale": 1.0,
  10. "Step Size": 0.016,
  11. "Crossfade Time": 3.5,
  12. "idle": 0.33,
  13. "walk": 0.33,
  14. "run": 0.33
  15. };
  16. var blendMesh = blendMesh;
  17. this.showModel = function() {
  18. return controls[ 'Show Model' ];
  19. };
  20. this.showSkeleton = function() {
  21. return controls[ 'Show Skeleton' ];
  22. };
  23. this.getTimeScale = function() {
  24. return controls[ 'Time Scale' ];
  25. };
  26. this.update = function( time ) {
  27. var getWeight = function( actionName ) {
  28. for( var i = 0; i < blendMesh.mixer.actions.length; i ++ ) {
  29. var action = blendMesh.mixer.actions[i];
  30. if( action.clip.name === actionName ) {
  31. return action.getWeightAt( time );
  32. }
  33. }
  34. return 0;
  35. }
  36. controls[ 'idle' ] = getWeight( 'idle' );
  37. controls[ 'walk' ] = getWeight( 'walk' );
  38. controls[ 'run' ] = getWeight( 'run' );
  39. };
  40. var init = function() {
  41. controls.gui = new dat.GUI();
  42. var settings = controls.gui.addFolder( 'Settings' );
  43. var playback = controls.gui.addFolder( 'Playback' );
  44. var blending = controls.gui.addFolder( 'Blend Tuning' );
  45. settings.add( controls, "Show Model" ).onChange( controls.showModelChanged );
  46. settings.add( controls, "Show Skeleton" ).onChange( controls.showSkeletonChanged );
  47. settings.add( controls, "Time Scale", 0, 1, 0.01 );
  48. settings.add( controls, "Step Size", 0.01, 0.1, 0.01 );
  49. settings.add( controls, "Crossfade Time", 0.1, 6.0, 0.05 );
  50. // These controls execute functions
  51. playback.add( controls, "start" );
  52. playback.add( controls, "pause" );
  53. playback.add( controls, "step" );
  54. playback.add( controls, "idle to walk" );
  55. playback.add( controls, "walk to run" );
  56. playback.add( controls, "warp walk to run" );
  57. blending.add( controls, "idle", 0, 1, 0.01 ).listen().onChange( controls.weight );
  58. blending.add( controls, "walk", 0, 1, 0.01 ).listen().onChange( controls.weight );
  59. blending.add( controls, "run", 0, 1, 0.01 ).listen().onChange( controls.weight );
  60. settings.open();
  61. playback.open();
  62. blending.open();
  63. };
  64. var getAnimationData = function() {
  65. return {
  66. detail: {
  67. anims: [ "idle", "walk", "run" ],
  68. weights: [ controls[ 'idle' ],
  69. controls[ 'walk' ],
  70. controls[ 'run' ] ]
  71. }
  72. };
  73. };
  74. controls.start = function() {
  75. var startEvent = new CustomEvent( 'start-animation', getAnimationData() );
  76. window.dispatchEvent( startEvent );
  77. };
  78. controls.stop = function() {
  79. var stopEvent = new CustomEvent( 'stop-animation' );
  80. window.dispatchEvent( stopEvent );
  81. };
  82. controls.pause = function() {
  83. var pauseEvent = new CustomEvent( 'pause-animation' );
  84. window.dispatchEvent( pauseEvent );
  85. };
  86. controls.step = function() {
  87. var stepData = { detail: { stepSize: controls[ 'Step Size' ] } };
  88. window.dispatchEvent( new CustomEvent( 'step-animation', stepData ) );
  89. };
  90. controls.weight = function() {
  91. // renormalize
  92. var sum = controls[ 'idle' ] + controls[ 'walk' ] + controls[ 'run' ];
  93. controls[ 'idle' ] /= sum;
  94. controls[ 'walk' ] /= sum;
  95. controls[ 'run' ] /= sum;
  96. var weightEvent = new CustomEvent( 'weight-animation', getAnimationData() );
  97. window.dispatchEvent( weightEvent );
  98. };
  99. controls.crossfade = function( from, to ) {
  100. var fadeData = getAnimationData();
  101. fadeData.detail.from = from;
  102. fadeData.detail.to = to;
  103. fadeData.detail.time = controls[ "Crossfade Time" ];
  104. window.dispatchEvent( new CustomEvent( 'crossfade', fadeData ) );
  105. };
  106. controls.warp = function( from, to ) {
  107. var warpData = getAnimationData();
  108. warpData.detail.from = 'walk';
  109. warpData.detail.to = 'run';
  110. warpData.detail.time = controls[ "Crossfade Time" ];
  111. window.dispatchEvent( new CustomEvent( 'warp', warpData ) );
  112. };
  113. controls[ 'idle to walk' ] = function() {
  114. controls.crossfade( 'idle', 'walk' );
  115. };
  116. controls[ 'walk to run' ] = function() {
  117. controls.crossfade( 'walk', 'run' );
  118. };
  119. controls[ 'warp walk to run' ] = function() {
  120. controls.warp( 'walk', 'run' );
  121. };
  122. controls.showSkeletonChanged = function() {
  123. var data = {
  124. detail: {
  125. shouldShow: controls[ 'Show Skeleton' ]
  126. }
  127. };
  128. window.dispatchEvent( new CustomEvent( 'toggle-show-skeleton', data ) );
  129. };
  130. controls.showModelChanged = function() {
  131. var data = {
  132. detail: {
  133. shouldShow: controls[ 'Show Model' ]
  134. }
  135. };
  136. window.dispatchEvent( new CustomEvent( 'toggle-show-model', data ) );
  137. };
  138. init.call( this );
  139. }