SkinnedMesh.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 ].add( bones[ b ] );
  31. } else {
  32. this.add( bones[ b ] );
  33. }
  34. }
  35. }
  36. this.normalizeSkinWeights();
  37. this.updateMatrixWorld( true );
  38. this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ), this.matrixWorld );
  39. };
  40. THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
  41. THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
  42. THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {
  43. this.skeleton = skeleton;
  44. if ( bindMatrix === undefined ) {
  45. this.updateMatrixWorld( true );
  46. this.skeleton.calculateInverses();
  47. bindMatrix = this.matrixWorld;
  48. }
  49. this.bindMatrix.copy( bindMatrix );
  50. this.bindMatrixInverse.getInverse( bindMatrix );
  51. };
  52. THREE.SkinnedMesh.prototype.pose = function () {
  53. this.skeleton.pose();
  54. };
  55. THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {
  56. if ( this.geometry instanceof THREE.Geometry ) {
  57. for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) {
  58. var sw = this.geometry.skinWeights[ i ];
  59. var scale = 1.0 / sw.lengthManhattan();
  60. if ( scale !== Infinity ) {
  61. sw.multiplyScalar( scale );
  62. } else {
  63. sw.set( 1, 0, 0, 0 ); // do something reasonable
  64. }
  65. }
  66. } else if ( this.geometry instanceof THREE.BufferGeometry ) {
  67. var vec = new THREE.Vector4();
  68. var skinWeight = this.geometry.attributes.skinWeight;
  69. for ( var i = 0; i < skinWeight.count; i ++ ) {
  70. vec.x = skinWeight.getX( i );
  71. vec.y = skinWeight.getY( i );
  72. vec.z = skinWeight.getZ( i );
  73. vec.w = skinWeight.getW( i );
  74. var scale = 1.0 / vec.lengthManhattan();
  75. if ( scale !== Infinity ) {
  76. vec.multiplyScalar( scale );
  77. } else {
  78. vec.set( 1, 0, 0, 0 ); // do something reasonable
  79. }
  80. skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w );
  81. }
  82. }
  83. };
  84. THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {
  85. THREE.Mesh.prototype.updateMatrixWorld.call( this, true );
  86. if ( this.bindMode === "attached" ) {
  87. this.bindMatrixInverse.getInverse( this.matrixWorld );
  88. } else if ( this.bindMode === "detached" ) {
  89. this.bindMatrixInverse.getInverse( this.bindMatrix );
  90. } else {
  91. console.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode );
  92. }
  93. };
  94. THREE.SkinnedMesh.prototype.clone = function() {
  95. return new this.constructor( this.geometry, this.material, this.useVertexTexture ).copy( this );
  96. };
粤ICP备19079148号