123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import { Mesh } from './Mesh.js';
- import { Matrix4 } from '../math/Matrix4.js';
- import { Vector3 } from '../math/Vector3.js';
- import { Vector4 } from '../math/Vector4.js';
- const _basePosition = /*@__PURE__*/ new Vector3();
- const _skinIndex = /*@__PURE__*/ new Vector4();
- const _skinWeight = /*@__PURE__*/ new Vector4();
- const _vector = /*@__PURE__*/ new Vector3();
- const _matrix = /*@__PURE__*/ new Matrix4();
- class SkinnedMesh extends Mesh {
- constructor( geometry, material ) {
- super( geometry, material );
- this.type = 'SkinnedMesh';
- this.bindMode = 'attached';
- this.bindMatrix = new Matrix4();
- this.bindMatrixInverse = new Matrix4();
- }
- copy( source ) {
- super.copy( source );
- this.bindMode = source.bindMode;
- this.bindMatrix.copy( source.bindMatrix );
- this.bindMatrixInverse.copy( source.bindMatrixInverse );
- this.skeleton = source.skeleton;
- return this;
- }
- bind( skeleton, bindMatrix ) {
- this.skeleton = skeleton;
- if ( bindMatrix === undefined ) {
- this.updateMatrixWorld( true );
- this.skeleton.calculateInverses();
- bindMatrix = this.matrixWorld;
- }
- this.bindMatrix.copy( bindMatrix );
- this.bindMatrixInverse.copy( bindMatrix ).invert();
- }
- pose() {
- this.skeleton.pose();
- }
- normalizeSkinWeights() {
- const vector = new Vector4();
- const skinWeight = this.geometry.attributes.skinWeight;
- for ( let i = 0, l = skinWeight.count; i < l; i ++ ) {
- vector.x = skinWeight.getX( i );
- vector.y = skinWeight.getY( i );
- vector.z = skinWeight.getZ( i );
- vector.w = skinWeight.getW( i );
- const scale = 1.0 / vector.manhattanLength();
- if ( scale !== Infinity ) {
- vector.multiplyScalar( scale );
- } else {
- vector.set( 1, 0, 0, 0 ); // do something reasonable
- }
- skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
- }
- }
- updateMatrixWorld( force ) {
- super.updateMatrixWorld( force );
- if ( this.bindMode === 'attached' ) {
- this.bindMatrixInverse.copy( this.matrixWorld ).invert();
- } else if ( this.bindMode === 'detached' ) {
- this.bindMatrixInverse.copy( this.bindMatrix ).invert();
- } else {
- console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
- }
- }
- boneTransform( index, target ) {
- const skeleton = this.skeleton;
- const geometry = this.geometry;
- _skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
- _skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
- _basePosition.copy( target ).applyMatrix4( this.bindMatrix );
- target.set( 0, 0, 0 );
- for ( let i = 0; i < 4; i ++ ) {
- const weight = _skinWeight.getComponent( i );
- if ( weight !== 0 ) {
- const boneIndex = _skinIndex.getComponent( i );
- _matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
- target.addScaledVector( _vector.copy( _basePosition ).applyMatrix4( _matrix ), weight );
- }
- }
- return target.applyMatrix4( this.bindMatrixInverse );
- }
- }
- SkinnedMesh.prototype.isSkinnedMesh = true;
- export { SkinnedMesh };
|