bones-browser.html 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Three.js Bones Browser</title>
  6. <style>
  7. @font-face {
  8. font-family: 'inconsolata';
  9. src: url('../files/inconsolata.woff') format('woff');
  10. font-weight: normal;
  11. font-style: normal;
  12. }
  13. body {
  14. margin:0;
  15. font-family: 'inconsolata';
  16. font-size: 15px;
  17. line-height: 18px;
  18. overflow: hidden;
  19. }
  20. canvas { width: 100%; height: 100% }
  21. #newWindow {
  22. display: block;
  23. position: absolute;
  24. bottom: 0.3em;
  25. left: 0.5em;
  26. color: #fff;
  27. }
  28. </style>
  29. </head>
  30. <body>
  31. <a id='newWindow' href='./bones-browser.html' target='_blank'>Open in New Window</a>
  32. <script src="../../build/three.min.js"></script>
  33. <script src='../../examples/js/libs/dat.gui.min.js'></script>
  34. <script src="../../examples/js/controls/OrbitControls.js"></script>
  35. <script>
  36. var gui, scene, camera, renderer, orbit, ambientLight, lights, mesh, bones, skeletonHelper;
  37. var state = {
  38. animateBones : false
  39. };
  40. function initScene () {
  41. gui = new dat.GUI();
  42. scene = new THREE.Scene();
  43. camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 200 );
  44. camera.position.z = 30;
  45. camera.position.y = 30;
  46. renderer = new THREE.WebGLRenderer( { antialias: true } );
  47. renderer.setPixelRatio( window.devicePixelRatio );
  48. renderer.setSize( window.innerWidth, window.innerHeight );
  49. document.body.appendChild( renderer.domElement );
  50. orbit = new THREE.OrbitControls( camera, renderer.domElement );
  51. orbit.enableZoom = false;
  52. ambientLight = new THREE.AmbientLight( 0x000000 );
  53. scene.add( ambientLight );
  54. lights = [];
  55. lights[ 0 ] = new THREE.PointLight( 0xffffff, 1, 0 );
  56. lights[ 1 ] = new THREE.PointLight( 0xffffff, 1, 0 );
  57. lights[ 2 ] = new THREE.PointLight( 0xffffff, 1, 0 );
  58. lights[ 0 ].position.set( 0, 200, 0 );
  59. lights[ 1 ].position.set( 100, 200, 100 );
  60. lights[ 2 ].position.set( -100, -200, -100 );
  61. scene.add( lights[ 0 ] );
  62. scene.add( lights[ 1 ] );
  63. scene.add( lights[ 2 ] );
  64. window.addEventListener( 'resize', function () {
  65. camera.aspect = window.innerWidth / window.innerHeight;
  66. camera.updateProjectionMatrix();
  67. renderer.setSize( window.innerWidth, window.innerHeight );
  68. }, false );
  69. initBones();
  70. setupDatGui();
  71. }
  72. function createGeometry ( sizing ) {
  73. var geometry = new THREE.CylinderGeometry(
  74. 5, // radiusTop
  75. 5, // radiusBottom
  76. sizing.height, // height
  77. 8, // radiusSegments
  78. sizing.segmentCount * 3, // heightSegments
  79. true // openEnded
  80. );
  81. for ( var i = 0; i < geometry.vertices.length; i ++ ) {
  82. var vertex = geometry.vertices[ i ];
  83. var y = ( vertex.y + sizing.halfHeight );
  84. var skinIndex = Math.floor( y / sizing.segmentHeight );
  85. var skinWeight = ( y % sizing.segmentHeight ) / sizing.segmentHeight;
  86. geometry.skinIndices.push( new THREE.Vector4( skinIndex, skinIndex + 1, 0, 0 ) );
  87. geometry.skinWeights.push( new THREE.Vector4( 1 - skinWeight, skinWeight, 0, 0 ) );
  88. }
  89. return geometry;
  90. };
  91. function createBones ( sizing ) {
  92. bones = [];
  93. var prevBone = new THREE.Bone();
  94. bones.push( prevBone );
  95. prevBone.position.y = -sizing.halfHeight;
  96. for ( var i = 0; i < sizing.segmentCount; i ++ ) {
  97. var bone = new THREE.Bone();
  98. bone.position.y = sizing.segmentHeight;
  99. bones.push( bone );
  100. prevBone.add( bone );
  101. prevBone = bone;
  102. }
  103. return bones;
  104. };
  105. function createMesh ( geometry, bones ) {
  106. var material = new THREE.MeshPhongMaterial( {
  107. skinning : true,
  108. color: 0x156289,
  109. emissive: 0x072534,
  110. side: THREE.DoubleSide,
  111. shading: THREE.FlatShading
  112. } );
  113. var mesh = new THREE.SkinnedMesh( geometry, material );
  114. var skeleton = new THREE.Skeleton( bones );
  115. mesh.add( bones[ 0 ] );
  116. mesh.bind( skeleton );
  117. skeletonHelper = new THREE.SkeletonHelper( mesh );
  118. skeletonHelper.material.linewidth = 2;
  119. scene.add( skeletonHelper );
  120. return mesh;
  121. };
  122. function setupDatGui () {
  123. var folder = gui.addFolder( "General Options" );
  124. folder.add( state, "animateBones" );
  125. folder.__controllers[ 0 ].name( "Animate Bones" );
  126. folder.add( mesh, "pose" );
  127. folder.__controllers[ 1 ].name( ".pose()" );
  128. var bones = mesh.skeleton.bones;
  129. for ( var i = 0; i < bones.length; i ++ ) {
  130. var bone = bones[ i ];
  131. folder = gui.addFolder( "Bone " + i );
  132. folder.add( bone.position, 'x', -10 + bone.position.x, 10 + bone.position.x );
  133. folder.add( bone.position, 'y', -10 + bone.position.y, 10 + bone.position.y );
  134. folder.add( bone.position, 'z', -10 + bone.position.z, 10 + bone.position.z );
  135. folder.add( bone.rotation, 'x', -Math.PI * 0.5, Math.PI * 0.5 );
  136. folder.add( bone.rotation, 'y', -Math.PI * 0.5, Math.PI * 0.5 );
  137. folder.add( bone.rotation, 'z', -Math.PI * 0.5, Math.PI * 0.5 );
  138. folder.add( bone.scale, 'x', 0, 2 );
  139. folder.add( bone.scale, 'y', 0, 2 );
  140. folder.add( bone.scale, 'z', 0, 2 );
  141. folder.__controllers[ 0 ].name( "position.x" );
  142. folder.__controllers[ 1 ].name( "position.y" );
  143. folder.__controllers[ 2 ].name( "position.z" );
  144. folder.__controllers[ 3 ].name( "rotation.x" );
  145. folder.__controllers[ 4 ].name( "rotation.y" );
  146. folder.__controllers[ 5 ].name( "rotation.z" );
  147. folder.__controllers[ 6 ].name( "scale.x" );
  148. folder.__controllers[ 7 ].name( "scale.y" );
  149. folder.__controllers[ 8 ].name( "scale.z" );
  150. }
  151. }
  152. function initBones () {
  153. var segmentHeight = 8;
  154. var segmentCount = 4;
  155. var height = segmentHeight * segmentCount;
  156. var halfHeight = height * 0.5;
  157. var sizing = {
  158. segmentHeight : segmentHeight,
  159. segmentCount : segmentCount,
  160. height : height,
  161. halfHeight : halfHeight
  162. };
  163. var geometry = createGeometry( sizing );
  164. var bones = createBones( sizing );
  165. mesh = createMesh( geometry, bones );
  166. mesh.scale.multiplyScalar( 1 );
  167. scene.add( mesh );
  168. };
  169. function render () {
  170. requestAnimationFrame( render );
  171. var time = Date.now() * 0.001;
  172. var bone = mesh;
  173. //Wiggle the bones
  174. if ( state.animateBones ) {
  175. for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
  176. mesh.skeleton.bones[ i ].rotation.z = Math.sin( time ) * 2 / mesh.skeleton.bones.length;
  177. }
  178. }
  179. skeletonHelper.update();
  180. renderer.render( scene, camera );
  181. };
  182. initScene();
  183. render();
  184. </script>
  185. </body>
  186. </html>