SkinnedMesh.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**
  2. * @author mikael emtinger / http://gomo.se/
  3. */
  4. // do not crash if somebody includes the file in oldie browser
  5. if ( !window.Float32Array ) {
  6. window.Float32Array = Array;
  7. }
  8. THREE.SkinnedMesh = function( geometry, materials ) {
  9. THREE.Mesh.call( this, geometry, materials );
  10. // init bones
  11. this.identityMatrix = new THREE.Matrix4();
  12. this.bones = [];
  13. this.boneMatrices = [];
  14. if( this.geometry.bones !== undefined ) {
  15. for( var b = 0; b < this.geometry.bones.length; b++ ) {
  16. var bone = this.addBone();
  17. bone.name = this.geometry.bones[ b ].name;
  18. bone.position.x = this.geometry.bones[ b ].pos [ 0 ];
  19. bone.position.y = this.geometry.bones[ b ].pos [ 1 ];
  20. bone.position.z = this.geometry.bones[ b ].pos [ 2 ];
  21. bone.quaternion.x = this.geometry.bones[ b ].rotq[ 0 ];
  22. bone.quaternion.y = this.geometry.bones[ b ].rotq[ 1 ];
  23. bone.quaternion.z = this.geometry.bones[ b ].rotq[ 2 ];
  24. bone.quaternion.w = this.geometry.bones[ b ].rotq[ 3 ];
  25. bone.scale.x = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 0 ] : 1;
  26. bone.scale.y = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 1 ] : 1;
  27. bone.scale.z = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 2 ] : 1;
  28. }
  29. for( var b = 0; b < this.bones.length; b++ ) {
  30. if( this.geometry.bones[ b ].parent === -1 )
  31. this.addChild( this.bones[ b ] );
  32. else
  33. this.bones[ this.geometry.bones[ b ].parent ].addChild( this.bones[ b ] );
  34. }
  35. //this.boneMatrices = new Float32Array( 16 * this.bones.length );
  36. this.pose();
  37. }
  38. };
  39. THREE.SkinnedMesh.prototype = new THREE.Mesh();
  40. THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
  41. /*
  42. * Update
  43. */
  44. THREE.SkinnedMesh.prototype.update = function( parentGlobalMatrix, forceUpdate, camera, renderer ) {
  45. // visible?
  46. if( this.visible ) {
  47. // update local
  48. if( this.autoUpdateMatrix )
  49. forceUpdate |= this.updateMatrix();
  50. // update global
  51. if( forceUpdate || this.matrixNeedsToUpdate ) {
  52. if( parentGlobalMatrix )
  53. this.globalMatrix.multiply( parentGlobalMatrix, this.localMatrix );
  54. else
  55. this.globalMatrix.copy( this.localMatrix );
  56. this.matrixNeedsToUpdate = false;
  57. forceUpdate = true;
  58. // update normal
  59. this.normalMatrix = THREE.Matrix4.makeInvert3x3( this.globalMatrix ).transpose();
  60. }
  61. // update children
  62. for( var i = 0; i < this.children.length; i++ )
  63. if( this.children[ i ] instanceof THREE.Bone )
  64. this.children[ i ].update( this.identityMatrix, false, camera, renderer );
  65. else
  66. this.children[ i ].update( this.globalMatrix, forceUpdate, camera, renderer );
  67. // check camera frustum and add to render list
  68. if( renderer && camera ) {
  69. if( camera.frustumContains( this ) )
  70. renderer.addToRenderList( this );
  71. else
  72. renderer.removeFromRenderList( this );
  73. }
  74. } else {
  75. renderer.removeFromRenderList( this );
  76. }
  77. };
  78. /*
  79. * Add
  80. */
  81. THREE.SkinnedMesh.prototype.addBone = function( bone ) {
  82. if( bone === undefined )
  83. bone = new THREE.Bone( this );
  84. this.bones.push( bone );
  85. return bone;
  86. };
  87. /*
  88. * Pose
  89. */
  90. THREE.SkinnedMesh.prototype.pose = function() {
  91. this.update( undefined, true );
  92. var bim, bone,
  93. boneInverses = [];
  94. for( var b = 0; b < this.bones.length; b++ ) {
  95. boneInverses.push( THREE.Matrix4.makeInvert( this.bones[ b ].skinMatrix, new THREE.Matrix4() ) );
  96. this.boneMatrices.push( this.bones[ b ].skinMatrix.flatten32 );
  97. /*
  98. bone = this.bones[ b ];
  99. boneInverses.push( THREE.Matrix4.makeInvert( bone.skinMatrix ) );
  100. bim = new Float32Array( 16 );
  101. bone.skinMatrix.flattenToArray( bim );
  102. this.boneMatrices.push( bim );
  103. //bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
  104. */
  105. }
  106. // project vertices to local
  107. if( this.geometry.skinVerticesA === undefined ) {
  108. this.geometry.skinVerticesA = [];
  109. this.geometry.skinVerticesB = [];
  110. var orgVertex;
  111. var vertex;
  112. for( var i = 0; i < this.geometry.skinIndices.length; i++ ) {
  113. orgVertex = this.geometry.vertices[ i ].position;
  114. var indexA = this.geometry.skinIndices[ i ].x;
  115. var indexB = this.geometry.skinIndices[ i ].y;
  116. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  117. this.geometry.skinVerticesA.push( boneInverses[ indexA ].multiplyVector3( vertex ) );
  118. vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
  119. this.geometry.skinVerticesB.push( boneInverses[ indexB ].multiplyVector3( vertex ) );
  120. // todo: add more influences
  121. // normalize weights
  122. if( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y !== 1 ) {
  123. var len = ( 1.0 - ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y )) * 0.5;
  124. this.geometry.skinWeights[ i ].x += len;
  125. this.geometry.skinWeights[ i ].y += len;
  126. }
  127. }
  128. }
  129. };
粤ICP备19079148号