mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-27 13:56:03 +10:00
Just one hardcoded shader for the moment. Everything needs to get cleaned / bugfixed / optimized.
216 lines
4.9 KiB
JavaScript
216 lines
4.9 KiB
JavaScript
/**
|
|
* @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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|