SkinnedMesh.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { Mesh } from './Mesh.js';
  2. import { Matrix4 } from '../math/Matrix4.js';
  3. import { Vector3 } from '../math/Vector3.js';
  4. import { Vector4 } from '../math/Vector4.js';
  5. function SkinnedMesh( geometry, material ) {
  6. if ( geometry && geometry.isGeometry ) {
  7. console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
  8. }
  9. Mesh.call( this, geometry, material );
  10. this.type = 'SkinnedMesh';
  11. this.bindMode = 'attached';
  12. this.bindMatrix = new Matrix4();
  13. this.bindMatrixInverse = new Matrix4();
  14. }
  15. SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
  16. constructor: SkinnedMesh,
  17. isSkinnedMesh: true,
  18. copy: function ( source ) {
  19. Mesh.prototype.copy.call( this, source );
  20. this.bindMode = source.bindMode;
  21. this.bindMatrix.copy( source.bindMatrix );
  22. this.bindMatrixInverse.copy( source.bindMatrixInverse );
  23. this.skeleton = source.skeleton;
  24. return this;
  25. },
  26. bind: function ( skeleton, bindMatrix ) {
  27. this.skeleton = skeleton;
  28. if ( bindMatrix === undefined ) {
  29. this.updateMatrixWorld( true );
  30. this.skeleton.calculateInverses();
  31. bindMatrix = this.matrixWorld;
  32. }
  33. this.bindMatrix.copy( bindMatrix );
  34. this.bindMatrixInverse.getInverse( bindMatrix );
  35. },
  36. pose: function () {
  37. this.skeleton.pose();
  38. },
  39. normalizeSkinWeights: function () {
  40. const vector = new Vector4();
  41. const skinWeight = this.geometry.attributes.skinWeight;
  42. for ( let i = 0, l = skinWeight.count; i < l; i ++ ) {
  43. vector.x = skinWeight.getX( i );
  44. vector.y = skinWeight.getY( i );
  45. vector.z = skinWeight.getZ( i );
  46. vector.w = skinWeight.getW( i );
  47. const scale = 1.0 / vector.manhattanLength();
  48. if ( scale !== Infinity ) {
  49. vector.multiplyScalar( scale );
  50. } else {
  51. vector.set( 1, 0, 0, 0 ); // do something reasonable
  52. }
  53. skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
  54. }
  55. },
  56. updateMatrixWorld: function ( force ) {
  57. Mesh.prototype.updateMatrixWorld.call( this, force );
  58. if ( this.bindMode === 'attached' ) {
  59. this.bindMatrixInverse.getInverse( this.matrixWorld );
  60. } else if ( this.bindMode === 'detached' ) {
  61. this.bindMatrixInverse.getInverse( this.bindMatrix );
  62. } else {
  63. console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
  64. }
  65. },
  66. boneTransform: ( function () {
  67. const basePosition = new Vector3();
  68. const skinIndex = new Vector4();
  69. const skinWeight = new Vector4();
  70. const vector = new Vector3();
  71. const matrix = new Matrix4();
  72. return function ( index, target ) {
  73. const skeleton = this.skeleton;
  74. const geometry = this.geometry;
  75. skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
  76. skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
  77. basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
  78. target.set( 0, 0, 0 );
  79. for ( let i = 0; i < 4; i ++ ) {
  80. const weight = skinWeight.getComponent( i );
  81. if ( weight !== 0 ) {
  82. const boneIndex = skinIndex.getComponent( i );
  83. matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
  84. target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight );
  85. }
  86. }
  87. return target.applyMatrix4( this.bindMatrixInverse );
  88. };
  89. }() )
  90. } );
  91. export { SkinnedMesh };
粤ICP备19079148号