content/hifi-content/dave/walk-tools/walkTools/libraries/three.js/objects/SkinnedMesh.js
2022-02-13 22:49:05 +01:00

170 lines
3.2 KiB
JavaScript

/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
* @author ikerr / http://verold.com
*/
THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
THREE.Mesh.call( this, geometry, material );
this.type = 'SkinnedMesh';
this.bindMode = "attached";
this.bindMatrix = new THREE.Matrix4();
this.bindMatrixInverse = new THREE.Matrix4();
// init bones
// TODO: remove bone creation as there is no reason (other than
// convenience) for THREE.SkinnedMesh to do this.
var bones = [];
if ( this.geometry && this.geometry.bones !== undefined ) {
var bone, gbone, p, q, s;
for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
gbone = this.geometry.bones[ b ];
p = gbone.pos;
q = gbone.rotq;
s = gbone.scl;
bone = new THREE.Bone( this );
bones.push( bone );
bone.name = gbone.name;
bone.position.set( p[ 0 ], p[ 1 ], p[ 2 ] );
bone.quaternion.set( q[ 0 ], q[ 1 ], q[ 2 ], q[ 3 ] );
if ( s !== undefined ) {
bone.scale.set( s[ 0 ], s[ 1 ], s[ 2 ] );
} else {
bone.scale.set( 1, 1, 1 );
}
}
for ( var b = 0, bl = this.geometry.bones.length; b < bl; ++ b ) {
gbone = this.geometry.bones[ b ];
if ( gbone.parent !== - 1 ) {
bones[ gbone.parent ].add( bones[ b ] );
} else {
this.add( bones[ b ] );
}
}
}
this.normalizeSkinWeights();
this.updateMatrixWorld( true );
this.bind( new THREE.Skeleton( bones, undefined, useVertexTexture ) );
};
THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) {
this.skeleton = skeleton;
if ( bindMatrix === undefined ) {
this.updateMatrixWorld( true );
bindMatrix = this.matrixWorld;
}
this.bindMatrix.copy( bindMatrix );
this.bindMatrixInverse.getInverse( bindMatrix );
};
THREE.SkinnedMesh.prototype.pose = function () {
this.skeleton.pose();
};
THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () {
if ( this.geometry instanceof THREE.Geometry ) {
for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
var sw = this.geometry.skinWeights[ i ];
var scale = 1.0 / sw.lengthManhattan();
if ( scale !== Infinity ) {
sw.multiplyScalar( scale );
} else {
sw.set( 1 ); // this will be normalized by the shader anyway
}
}
} else {
// skinning weights assumed to be normalized for THREE.BufferGeometry
}
};
THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) {
THREE.Mesh.prototype.updateMatrixWorld.call( this, true );
if ( this.bindMode === "attached" ) {
this.bindMatrixInverse.getInverse( this.matrixWorld );
} else if ( this.bindMode === "detached" ) {
this.bindMatrixInverse.getInverse( this.bindMatrix );
} else {
THREE.warn( 'THREE.SkinnedMesh unreckognized bindMode: ' + this.bindMode );
}
};
THREE.SkinnedMesh.prototype.clone = function( object ) {
if ( object === undefined ) {
object = new THREE.SkinnedMesh( this.geometry, this.material, this.useVertexTexture );
}
THREE.Mesh.prototype.clone.call( this, object );
return object;
};