Buckets:
| import { Mesh } from './Mesh.js'; | |
| import { Box3 } from '../math/Box3.js'; | |
| import { Matrix4 } from '../math/Matrix4.js'; | |
| import { Sphere } from '../math/Sphere.js'; | |
| import { Vector3 } from '../math/Vector3.js'; | |
| import { Vector4 } from '../math/Vector4.js'; | |
| import { Ray } from '../math/Ray.js'; | |
| import { AttachedBindMode, DetachedBindMode } from '../constants.js'; | |
| const _basePosition = /*@__PURE__*/ new Vector3(); | |
| const _skinIndex = /*@__PURE__*/ new Vector4(); | |
| const _skinWeight = /*@__PURE__*/ new Vector4(); | |
| const _vector3 = /*@__PURE__*/ new Vector3(); | |
| const _matrix4 = /*@__PURE__*/ new Matrix4(); | |
| const _vertex = /*@__PURE__*/ new Vector3(); | |
| const _sphere = /*@__PURE__*/ new Sphere(); | |
| const _inverseMatrix = /*@__PURE__*/ new Matrix4(); | |
| const _ray = /*@__PURE__*/ new Ray(); | |
| class SkinnedMesh extends Mesh { | |
| constructor( geometry, material ) { | |
| super( geometry, material ); | |
| this.isSkinnedMesh = true; | |
| this.type = 'SkinnedMesh'; | |
| this.bindMode = AttachedBindMode; | |
| this.bindMatrix = new Matrix4(); | |
| this.bindMatrixInverse = new Matrix4(); | |
| this.boundingBox = null; | |
| this.boundingSphere = null; | |
| } | |
| computeBoundingBox() { | |
| const geometry = this.geometry; | |
| if ( this.boundingBox === null ) { | |
| this.boundingBox = new Box3(); | |
| } | |
| this.boundingBox.makeEmpty(); | |
| const positionAttribute = geometry.getAttribute( 'position' ); | |
| for ( let i = 0; i < positionAttribute.count; i ++ ) { | |
| this.getVertexPosition( i, _vertex ); | |
| this.boundingBox.expandByPoint( _vertex ); | |
| } | |
| } | |
| computeBoundingSphere() { | |
| const geometry = this.geometry; | |
| if ( this.boundingSphere === null ) { | |
| this.boundingSphere = new Sphere(); | |
| } | |
| this.boundingSphere.makeEmpty(); | |
| const positionAttribute = geometry.getAttribute( 'position' ); | |
| for ( let i = 0; i < positionAttribute.count; i ++ ) { | |
| this.getVertexPosition( i, _vertex ); | |
| this.boundingSphere.expandByPoint( _vertex ); | |
| } | |
| } | |
| copy( source, recursive ) { | |
| super.copy( source, recursive ); | |
| this.bindMode = source.bindMode; | |
| this.bindMatrix.copy( source.bindMatrix ); | |
| this.bindMatrixInverse.copy( source.bindMatrixInverse ); | |
| this.skeleton = source.skeleton; | |
| if ( source.boundingBox !== null ) this.boundingBox = source.boundingBox.clone(); | |
| if ( source.boundingSphere !== null ) this.boundingSphere = source.boundingSphere.clone(); | |
| return this; | |
| } | |
| raycast( raycaster, intersects ) { | |
| const material = this.material; | |
| const matrixWorld = this.matrixWorld; | |
| if ( material === undefined ) return; | |
| // test with bounding sphere in world space | |
| if ( this.boundingSphere === null ) this.computeBoundingSphere(); | |
| _sphere.copy( this.boundingSphere ); | |
| _sphere.applyMatrix4( matrixWorld ); | |
| if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; | |
| // convert ray to local space of skinned mesh | |
| _inverseMatrix.copy( matrixWorld ).invert(); | |
| _ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix ); | |
| // test with bounding box in local space | |
| if ( this.boundingBox !== null ) { | |
| if ( _ray.intersectsBox( this.boundingBox ) === false ) return; | |
| } | |
| // test for intersections with geometry | |
| this._computeIntersections( raycaster, intersects, _ray ); | |
| } | |
| getVertexPosition( index, target ) { | |
| super.getVertexPosition( index, target ); | |
| this.applyBoneTransform( index, target ); | |
| return target; | |
| } | |
| 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.fromBufferAttribute( skinWeight, 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 === AttachedBindMode ) { | |
| this.bindMatrixInverse.copy( this.matrixWorld ).invert(); | |
| } else if ( this.bindMode === DetachedBindMode ) { | |
| this.bindMatrixInverse.copy( this.bindMatrix ).invert(); | |
| } else { | |
| console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode ); | |
| } | |
| } | |
| applyBoneTransform( index, vector ) { | |
| const skeleton = this.skeleton; | |
| const geometry = this.geometry; | |
| _skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index ); | |
| _skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index ); | |
| _basePosition.copy( vector ).applyMatrix4( this.bindMatrix ); | |
| vector.set( 0, 0, 0 ); | |
| for ( let i = 0; i < 4; i ++ ) { | |
| const weight = _skinWeight.getComponent( i ); | |
| if ( weight !== 0 ) { | |
| const boneIndex = _skinIndex.getComponent( i ); | |
| _matrix4.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] ); | |
| vector.addScaledVector( _vector3.copy( _basePosition ).applyMatrix4( _matrix4 ), weight ); | |
| } | |
| } | |
| return vector.applyMatrix4( this.bindMatrixInverse ); | |
| } | |
| boneTransform( index, vector ) { // @deprecated, r151 | |
| console.warn( 'THREE.SkinnedMesh: .boneTransform() was renamed to .applyBoneTransform() in r151.' ); | |
| return this.applyBoneTransform( index, vector ); | |
| } | |
| } | |
| export { SkinnedMesh }; | |
Xet Storage Details
- Size:
- 5.64 kB
- Xet hash:
- 45fe8f271174171f72f63c9a9bc543b067fd1bf25178ce2b26eab33469954fc3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.