SkinnedMesh.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /**
  2. * @author mikael emtinger / http://gomo.se/
  3. * @author alteredq / http://alteredqualia.com/
  4. * @author ikerr / http://verold.com
  5. */
  6. THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
  7. THREE.Mesh.call( this, geometry, material );
  8. this.type = 'SkinnedMesh';
  9. this.bindMode = "attached";
  10. this.bindMatrix = new THREE.Matrix4();
  11. this.bindMatrixInverse = new THREE.Matrix4();
  12. // init bones
  13. // TODO: remove bone creation as there is no reason (other than
  14. // convenience) for THREE.SkinnedMesh to do this.
  15. var bones = [];
  16. if ( this.geometry && this.geometry.bones !== undefined ) {
  17. var bone, gbone;
  18. for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
  19. gbone = this.geometry.bones[ b ];
  20. bone = new THREE.Bone( this );
  21. bones.push( bone );
  22. bone.name = gbone.name;
  23. bone.position.fromArray( gbone.pos );
  24. bone.quaternion.fromArray( gbone.rotq );
  25. if ( gbone.scl !== undefined ) bone.scale.fromArray( gbone.scl );
  26. }
  27. for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
  28. gbone = this.geometry.bones[ b ];
  29. if ( gbone.parent !== - 1 && gbone.parent !== null &&
  30. bones[ gbone.parent ] !== undefined ) {
  31. bones[ gbone.parent ].add( bones[ b ] );
  32. } else {
  33. this.add( bones[ b ] );
  34. }
  35. }
  36. }
  37. this.normalizeSkinWeights();
  38. this.updateMatrixWorld( true );
  39. this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );
  40. };
  41. THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
  42. THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
  43. THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {
  44. this.skeleton = skeleton;
  45. if ( bindMatrix === undefined ) {
  46. this.updateMatrixWorld( true );
  47. this.skeleton.calculateInverses();
  48. bindMatrix = this.matrixWorld;
  49. }
  50. this.bindMatrix.copy( bindMatrix );
  51. this.bindMatrixInverse.getInverse( bindMatrix );
  52. };
  53. THREE.SkinnedMesh.prototype.pose = function () {
  54. this.skeleton.pose();
  55. };
  56. THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {
  57. if ( this.geometry instanceof THREE.Geometry ) {
  58. for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {
  59. var sw = this.geometry.skinWeights[ i ];
  60. var scale = 1.0 / sw.lengthManhattan();
  61. if ( scale !== Infinity ) {
  62. sw.multiplyScalar( scale );
  63. } else {
  64. sw.set( 1, 0, 0, 0 ); // do something reasonable
  65. }
  66. }
  67. } else if ( this.geometry instanceof THREE.BufferGeometry ) {
  68. var vec = new THREE.Vector4();
  69. var skinWeight = this.geometry.attributes.skinWeight;
  70. for ( var i = 0; i < skinWeight.count; i ++ ) {
  71. vec.x = skinWeight.getX( i );
  72. vec.y = skinWeight.getY( i );
  73. vec.z = skinWeight.getZ( i );
  74. vec.w = skinWeight.getW( i );
  75. var scale = 1.0 / vec.lengthManhattan();
  76. if ( scale !== Infinity ) {
  77. vec.multiplyScalar( scale );
  78. } else {
  79. vec.set( 1, 0, 0, 0 ); // do something reasonable
  80. }
  81. skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );
  82. }
  83. }
  84. };
  85. THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {
  86. THREE.Mesh.prototype.updateMatrixWorld.call( this, true );
  87. if ( this.bindMode === "attached" ) {
  88. this.bindMatrixInverse.getInverse( this.matrixWorld );
  89. } else if ( this.bindMode === "detached" ) {
  90. this.bindMatrixInverse.getInverse( this.bindMatrix );
  91. } else {
  92. console.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );
  93. }
  94. };
  95. THREE.SkinnedMesh.prototype.clone = function() {
  96. return new this.constructor( this.geometry, this.material, this.useVertexTexture ).copy( this );
  97. };
粤ICP备19079148号