SkinnedMesh.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. var b, bone, gbone, p, q, s;
  15. if ( this.geometry.bones !== undefined ) {
  16. for ( b = 0; b < this.geometry.bones.length; b++ ) {
  17. gbone = this.geometry.bones[ b ];
  18. p = gbone.pos;
  19. q = gbone.rotq;
  20. s = gbone.scl;
  21. bone = this.addBone();
  22. bone.name = gbone.name;
  23. bone.position.set( p[0], p[1], p[2] );
  24. bone.quaternion.set( q[0], q[1], q[2], q[3] );
  25. bone.useQuaternion = true;
  26. if ( s !== undefined ) {
  27. bone.scale.set( s[0], s[1], s[2] );
  28. } else {
  29. bone.scale.set( 1, 1, 1 );
  30. }
  31. }
  32. for ( b = 0; b < this.bones.length; b++ ) {
  33. gbone = this.geometry.bones[ b ];
  34. bone = this.bones[ b ];
  35. if ( gbone.parent === -1 ) {
  36. this.addChild( bone );
  37. } else {
  38. this.bones[ gbone.parent ].addChild( bone );
  39. }
  40. }
  41. this.boneMatrices = new Float32Array( 16 * this.bones.length );
  42. this.pose();
  43. }
  44. };
  45. THREE.SkinnedMesh.prototype = new THREE.Mesh();
  46. THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
  47. /*
  48. * Update
  49. */
  50. THREE.SkinnedMesh.prototype.update = function ( parentMatrixWorld, forceUpdate, camera ) {
  51. // visible?
  52. if ( this.visible ) {
  53. // update local
  54. if ( this.matrixAutoUpdate ) {
  55. forceUpdate |= this.updateMatrix();
  56. }
  57. // update global
  58. if ( forceUpdate || this.matrixWorldNeedsUpdate ) {
  59. if ( parentMatrixWorld ) {
  60. this.matrixWorld.multiply( parentMatrixWorld, this.matrix );
  61. } else {
  62. this.matrixWorld.copy( this.matrix );
  63. }
  64. this.matrixWorldNeedsUpdate = false;
  65. forceUpdate = true;
  66. }
  67. // update children
  68. var child, i, l = this.children.length;
  69. for ( i = 0; i < l; i++ ) {
  70. child = this.children[ i ];
  71. if ( child instanceof THREE.Bone ) {
  72. child.update( this.identityMatrix, false, camera );
  73. } else {
  74. child.update( this.matrixWorld, forceUpdate, camera );
  75. }
  76. }
  77. // flatten to array
  78. var b, bl = this.bones.length;
  79. ba = this.bones;
  80. bm = this.boneMatrices;
  81. for ( b = 0; b < bl; b++ ) {
  82. ba[ b ].skinMatrix.flattenToArrayOffset( bm, b * 16 );
  83. }
  84. }
  85. };
  86. /*
  87. * Add
  88. */
  89. THREE.SkinnedMesh.prototype.addBone = function( bone ) {
  90. if ( bone === undefined ) {
  91. bone = new THREE.Bone( this );
  92. }
  93. this.bones.push( bone );
  94. return bone;
  95. };
  96. /*
  97. * Pose
  98. */
  99. THREE.SkinnedMesh.prototype.pose = function() {
  100. this.update( undefined, true );
  101. var bim, bone, boneInverses = [];
  102. for ( var b = 0; b < this.bones.length; b++ ) {
  103. bone = this.bones[ b ];
  104. boneInverses.push( THREE.Matrix4.makeInvert( bone.skinMatrix ) );
  105. bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
  106. }
  107. // project vertices to local
  108. if ( this.geometry.skinVerticesA === undefined ) {
  109. this.geometry.skinVerticesA = [];
  110. this.geometry.skinVerticesB = [];
  111. var orgVertex, 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号