First integration step: something appeared on the screen ;)

Otherwise things are very much work in progress, expect everything to be broken.
This commit is contained in:
alteredq
2011-02-16 17:58:19 +01:00
parent df513e044c
commit cf37a8cc43
20 changed files with 2456 additions and 793 deletions
+91
View File
@@ -0,0 +1,91 @@
/**
* @author mikael emtinger / http://gomo.se/
*/
THREE.Bone = function( belongsToSkin ) {
THREE.Object3D.call( this );
this.skin = belongsToSkin;
this.skinMatrix = new THREE.Matrix4();
this.hasNoneBoneChildren = false;
};
THREE.Bone.prototype = new THREE.Object3D();
THREE.Bone.prototype.constructor = THREE.Bone;
THREE.Bone.prototype.supr = THREE.Object3D.prototype;
/*
* Update
*/
THREE.Bone.prototype.update = function( parentSkinMatrix, forceUpdate, camera, renderer ) {
// update local
if( this.autoUpdateMatrix )
forceUpdate |= this.updateMatrix();
// update skin matrix
if( forceUpdate || this.matrixNeedsToUpdate ) {
if( parentSkinMatrix )
this.skinMatrix.multiply( parentSkinMatrix, this.localMatrix );
else
this.skinMatrix.copy( this.localMatrix );
this.matrixNeedsToUpdate = false;
forceUpdate = true;
}
// update children
if( this.hasNoneBoneChildren ) {
this.globalMatrix.multiply( this.skin.globalMatrix, this.skinMatrix );
for( var i = 0; i < this.children.length; i++ )
if( !( this.children[ i ] instanceof THREE.Bone ))
this.children[ i ].update( this.globalMatrix, true, camera, renderer );
else
this.children[ i ].update( this.skinMatrix, forceUpdate, camera, renderer );
} else {
for( var i = 0; i < this.children.length; i++ )
this.children[ i ].update( this.skinMatrix, forceUpdate, camera, renderer );
}
};
/*
* Add child
*/
THREE.Bone.prototype.addChild = function( child ) {
if( this.children.indexOf( child ) === -1 ) {
if( child.parent !== undefined )
child.parent.removeChild( child );
child.parent = this;
this.children.push( child );
if( !( child instanceof THREE.Bone ))
this.hasNoneBoneChildren = true;
}
};
/*
* Todo: Remove Children: see if any remaining are none-Bone
*/
+97
View File
@@ -0,0 +1,97 @@
/**
* @author mikael emtinger / http://gomo.se/
*/
THREE.LOD = function() {
THREE.Object3D.call( this );
this.LODs = [];
};
THREE.LOD.prototype = new THREE.Object3D();
THREE.LOD.prototype.constructor = THREE.LOD;
THREE.LOD.prototype.supr = THREE.Object3D.prototype;
/*
* Add
*/
THREE.LOD.prototype.add = function( object3D, visibleAtDistance ) {
if( visibleAtDistance === undefined ) visibleAtDistance = 0;
visibleAtDistance = Math.abs( visibleAtDistance );
for( var l = 0; l < this.LODs.length; l++ ) {
if( visibleAtDistance < this.LODs[ l ].visibleAtDistance )
break;
}
this.LODs.splice( l, 0, { visibleAtDistance: visibleAtDistance, object3D: object3D } );
this.addChild( object3D );
};
/*
* Update
*/
THREE.LOD.prototype.update = function( parentGlobalMatrix, forceUpdate, camera, renderer ) {
// 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 lods
if( this.LODs.length > 1 ) {
var distance = -camera.inverseMatrix.mulitplyVector3OnlyZ( this.position );
this.LODs[ 0 ].object3D.visible = true;
for( var l = 1; l < this.LODs.length; l++ ) {
if( distance >= this.LODs[ l ].visibleAtDistance ) {
this.LODs[ l - 1 ].object3D.visible = false;
this.LODs[ l ].object3D.visible = true;
}
else
break;
}
for( ; l < this.LODs.length; l++ )
this.LODs[ l ].object3D.visible = false;
}
// update children
for( var c = 0; c < this.children.length; c++ )
this.children[ c ].update( this.globalMatrix, forceUpdate, camera, renderer );
};
+83 -8
View File
@@ -1,23 +1,98 @@
/**
* @author mr.doob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author mikael emtinger / http://gomo.se/
*/
THREE.Mesh = function ( geometry, materials ) {
THREE.Mesh = function( geometry, materials ) {
THREE.Object3D.call( this );
this.geometry = geometry;
this.materials = materials instanceof Array ? materials : [ materials ];
this.geometry = geometry;
this.materials = materials && materials.length ? materials : [ materials ];
this.normalMatrix = THREE.Matrix4.makeInvert3x3( this.globalMatrix ).transpose();
this.flipSided = false;
this.doubleSided = false;
this.overdraw = false; // TODO: Move to material?
// calc bound radius
if( this.geometry ) {
if( !this.geometry.boundingSphere )
this.geometry.computeBoundingSphere();
this.boundRadius = geometry.boundingSphere.radius;
this.geometry.boundingSphere || this.geometry.computeBoundingSphere();
}
};
}
THREE.Mesh.prototype = new THREE.Object3D();
THREE.Mesh.prototype = new THREE.Object3D();
THREE.Mesh.prototype.constructor = THREE.Mesh;
THREE.Mesh.prototype.supr = THREE.Object3D.prototype;
/*
* Update
*/
THREE.Mesh.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++ )
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 );
}
}
+168 -38
View File
@@ -1,74 +1,204 @@
/**
* @author mr.doob / http://mrdoob.com/
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
THREE.Object3D = function () {
THREE.Object3D = function() {
this.id = THREE.Object3DCounter.value ++; // TODO: Probably not needed?
this.id = THREE.Object3DCounter.value ++;
this.visible = true;
this.autoUpdateMatrix = true;
this.matrixNeedsToUpdate = true;
this.parent = undefined;
this.children = [];
this.position = new THREE.Vector3();
this.rotation = new THREE.Vector3();
this.scale = new THREE.Vector3( 1, 1, 1 );
this.matrix = new THREE.Matrix4();
this.matrixWorld = new THREE.Matrix4();
this.rotationMatrix = new THREE.Matrix4();
this.tmpMatrix = new THREE.Matrix4();
this.screen = new THREE.Vector3();
this.autoUpdateMatrix = true;
this.visible = true;
this.children = [];
this.position = new THREE.Vector3();
this.rotation = new THREE.Vector3();
this.scale = new THREE.Vector3( 1.0, 1.0, 1.0 );
this.localMatrix = new THREE.Matrix4();
this.globalMatrix = new THREE.Matrix4();
this.quaternion = new THREE.Quaternion();
this.useQuaternion = false;
this.screenPosition = new THREE.Vector4(); // xyzr
this.boundRadius = 0.0;
this.boundRadiusScale = 1.0;
};
THREE.Object3D.prototype = {
addChild: function ( object ) {
/*
* Update
*/
var i = this.children.indexOf( object );
THREE.Object3D.prototype.update = function( parentGlobalMatrix, forceUpdate, camera, renderer ) {
if ( i === -1 ) {
// visible and auto update?
if( this.visible ) {
this.children.push( object );
// 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;
}
},
removeChild: function ( object ) {
// update children
for( var i = 0; i < this.children.length; i++ ) {
this.children[ i ].update( this.globalMatrix, forceUpdate, camera, renderer );
}
var i = this.children.indexOf( object );
}
if ( i !== -1 ) {
};
this.children.splice( i, 1 );
/*
* Update Matrix
*/
THREE.Object3D.prototype.updateMatrix = function() {
// update position
var isDirty = false;
if( this.position.isDirty ) {
this.localMatrix.setPosition( this.position );
this.position.isDirty = false;
isDirty = true;
}
// update quaternion
if( this.useQuaternion ) {
if( this.quaternion.isDirty ) {
this.localMatrix.setRotationFromQuaternion( this.quaternion );
this.quaternion.isDirty = false;
this.rotation .isDirty = false;
if( this.scale.isDirty || this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
this.localMatrix.scale( this.scale );
this.scale.isDirty = false;
this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
}
isDirty = true;
}
},
}
updateMatrix: function () {
// update rotation
var p = this.position, r = this.rotation, s = this.scale,
matrix = this.matrix, rotationMatrix = this.rotationMatrix,
tmpMatrix = this.tmpMatrix;
else if( this.rotation.isDirty ) {
this.localMatrix.setRotationFromEuler( this.rotation );
this.rotation.isDirty = false;
matrix.setTranslation( p.x, p.y, p.z );
if( this.scale.isDirty || this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
this.localMatrix.scale( this.scale );
this.scale.isDirty = false;
this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
rotationMatrix.setRotX( r.x );
}
if ( r.y != 0 ) rotationMatrix.multiplySelf( tmpMatrix.setRotY( r.y ) );
if ( r.z != 0 ) rotationMatrix.multiplySelf( tmpMatrix.setRotZ( r.z ) );
isDirty = true;
matrix.multiplySelf( rotationMatrix );
}
if ( s.x != 0 || s.y != 0 || s.z != 0 ) matrix.multiplySelf( tmpMatrix.setScale( s.x, s.y, s.z ) );
// update scale
if( this.scale.isDirty ) {
if( this.useQuaternion )
this.localMatrix.setRotationFromQuaternion( this.quaternion );
else
this.localMatrix.setRotationFromEuler( this.rotation );
this.localMatrix.scale( this.scale );
this.scale.isDirty = false;
this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ));
isDirty = true;
}
return isDirty;
};
/*
* AddChild
*/
THREE.Object3D.prototype.addChild = function( child ) {
if( this.children.indexOf( child ) === -1 ) {
if( child.parent !== undefined )
child.parent.removeChild( child );
child.parent = this;
this.children.push( child );
}
};
/*
* RemoveChild
*/
THREE.Object3D.prototype.removeChild = function() {
var childIndex = this.children.indexOf( child );
if( childIndex !== -1 ) {
this.children.splice( childIndex, 1 );
child.parent = undefined;
}
};
THREE.Object3DCounter = { value: 0 };
+193
View File
@@ -0,0 +1,193 @@
/**
* @author mikael emtinger / http://gomo.se/
*/
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.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 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 );
}
// 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;
}
}
}
};