| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /**
- * @author mikael emtinger / http://gomo.se/
- */
- // do not crash if somebody includes the file in oldie browser
- if ( !window.Float32Array ) {
- window.Float32Array = Array;
- }
- THREE.SkinnedMesh = function( geometry, materials ) {
-
- THREE.Mesh.call( this, geometry, materials );
-
-
- // init bones
- this.identityMatrix = new THREE.Matrix4();
- this.bones = [];
- this.boneMatrices = [];
-
- if( this.geometry.bones !== undefined ) {
-
- for( var b = 0; b < this.geometry.bones.length; b++ ) {
-
- var bone = this.addBone();
-
- bone.name = this.geometry.bones[ b ].name;
- bone.position.x = this.geometry.bones[ b ].pos [ 0 ];
- bone.position.y = this.geometry.bones[ b ].pos [ 1 ];
- bone.position.z = this.geometry.bones[ b ].pos [ 2 ];
- bone.quaternion.x = this.geometry.bones[ b ].rotq[ 0 ];
- bone.quaternion.y = this.geometry.bones[ b ].rotq[ 1 ];
- bone.quaternion.z = this.geometry.bones[ b ].rotq[ 2 ];
- bone.quaternion.w = this.geometry.bones[ b ].rotq[ 3 ];
- bone.scale.x = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 0 ] : 1;
- bone.scale.y = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 1 ] : 1;
- bone.scale.z = this.geometry.bones[ b ].scl !== undefined ? this.geometry.bones[ b ].scl[ 2 ] : 1;
- }
-
- for( var b = 0; b < this.bones.length; b++ ) {
-
- if( this.geometry.bones[ b ].parent === -1 )
- this.addChild( this.bones[ b ] );
- else
- this.bones[ this.geometry.bones[ b ].parent ].addChild( this.bones[ b ] );
- }
- //this.boneMatrices = new Float32Array( 16 * this.bones.length );
-
- this.pose();
- }
- };
- THREE.SkinnedMesh.prototype = new THREE.Mesh();
- THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh;
- /*
- * Update
- */
- THREE.SkinnedMesh.prototype.update = function( parentGlobalMatrix, forceUpdate, camera, renderer ) {
-
- // visible?
-
- if( this.visible ) {
- // update local
-
- if( this.autoUpdateMatrix )
- forceUpdate |= this.updateMatrix();
- // update global
- if( forceUpdate || this.matrixNeedsToUpdate ) {
-
- if( parentGlobalMatrix )
- this.globalMatrix.multiply( parentGlobalMatrix, this.localMatrix );
- else
- this.globalMatrix.copy( this.localMatrix );
-
- this.matrixNeedsToUpdate = false;
- forceUpdate = true;
-
-
- // update normal
- this.normalMatrix = THREE.Matrix4.makeInvert3x3( this.globalMatrix ).transpose();
- }
- // update children
-
- for( var i = 0; i < this.children.length; i++ )
- if( this.children[ i ] instanceof THREE.Bone )
- this.children[ i ].update( this.identityMatrix, false, camera, renderer );
- else
- this.children[ i ].update( this.globalMatrix, forceUpdate, camera, renderer );
-
- // check camera frustum and add to render list
-
- if( renderer && camera ) {
-
- if( camera.frustumContains( this ) )
- renderer.addToRenderList( this );
- else
- renderer.removeFromRenderList( this );
- }
- } else {
-
- renderer.removeFromRenderList( this );
- }
- };
- /*
- * Add
- */
- THREE.SkinnedMesh.prototype.addBone = function( bone ) {
-
- if( bone === undefined )
- bone = new THREE.Bone( this );
-
- this.bones.push( bone );
-
- return bone;
- };
- /*
- * Pose
- */
- THREE.SkinnedMesh.prototype.pose = function() {
- this.update( undefined, true );
- var bim, bone,
- boneInverses = [];
-
- for( var b = 0; b < this.bones.length; b++ ) {
-
- boneInverses.push( THREE.Matrix4.makeInvert( this.bones[ b ].skinMatrix, new THREE.Matrix4() ) );
- this.boneMatrices.push( this.bones[ b ].skinMatrix.flatten32 );
-
- /*
- bone = this.bones[ b ];
-
- boneInverses.push( THREE.Matrix4.makeInvert( bone.skinMatrix ) );
-
- bim = new Float32Array( 16 );
- bone.skinMatrix.flattenToArray( bim );
- this.boneMatrices.push( bim );
- //bone.skinMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
- */
- }
-
- // project vertices to local
- if( this.geometry.skinVerticesA === undefined ) {
-
- this.geometry.skinVerticesA = [];
- this.geometry.skinVerticesB = [];
- var orgVertex;
- var vertex;
-
- for( var i = 0; i < this.geometry.skinIndices.length; i++ ) {
-
- orgVertex = this.geometry.vertices[ i ].position;
-
- var indexA = this.geometry.skinIndices[ i ].x;
- var indexB = this.geometry.skinIndices[ i ].y;
-
- vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
- this.geometry.skinVerticesA.push( boneInverses[ indexA ].multiplyVector3( vertex ) );
-
- vertex = new THREE.Vector3( orgVertex.x, orgVertex.y, orgVertex.z );
- this.geometry.skinVerticesB.push( boneInverses[ indexB ].multiplyVector3( vertex ) );
-
- // todo: add more influences
-
- // normalize weights
-
- if( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y !== 1 ) {
-
- var len = ( 1.0 - ( this.geometry.skinWeights[ i ].x + this.geometry.skinWeights[ i ].y )) * 0.5;
- this.geometry.skinWeights[ i ].x += len;
- this.geometry.skinWeights[ i ].y += len;
- }
- }
- }
- };
|