提交 15f46931 编写于 作者: A alteredq

Fixed performance regress with skinning.

See #2336
上级 715507a9
...@@ -10841,38 +10841,39 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) { ...@@ -10841,38 +10841,39 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
} }
} }
// make a snapshot of the bones' rest position // make a snapshot of the bones' rest position
if (this.boneInverses == undefined) if ( this.boneInverses == undefined ) {
{
this.boneInverses = []; this.boneInverses = [];
for ( var b = 0; b < this.bones.length; b ++ ) for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
{
var inverse = new THREE.Matrix4(); var inverse = new THREE.Matrix4();
inverse.getInverse( this.bones[ b ].skinMatrix ); inverse.getInverse( this.bones[ b ].skinMatrix );
this.boneInverses.push( inverse ); this.boneInverses.push( inverse );
} }
} }
// flatten bone matrices to array // flatten bone matrices to array
for ( var b = 0; b < this.bones.length; b ++ ) for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
{
var offset = new THREE.Matrix4();
// compute the offset between the current and the original transform; // compute the offset between the current and the original transform;
//TODO: we could get rid of this multiplication step if the skinMatrix //TODO: we could get rid of this multiplication step if the skinMatrix
// was already representing the offset; however, this requires some // was already representing the offset; however, this requires some
// major changes to the animation system // major changes to the animation system
offset.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
offset.flattenToArrayOffset( this.boneMatrices, b * 16 ); THREE.SkinnedMesh.offsetMatrix.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
} }
if ( this.useVertexTexture ) { if ( this.useVertexTexture ) {
...@@ -10890,27 +10891,31 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) { ...@@ -10890,27 +10891,31 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
THREE.SkinnedMesh.prototype.pose = function() { THREE.SkinnedMesh.prototype.pose = function() {
this.updateMatrixWorld( true ); this.updateMatrixWorld( true );
for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) { for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
// normalize weights // normalize weights
var sw = this.geometry.skinWeights[ i ]; var sw = this.geometry.skinWeights[ i ];
var scale = 1.0 / sw.lengthManhattan(); var scale = 1.0 / sw.lengthManhattan();
if ( scale != Infinity ) { if ( scale !== Infinity ) {
sw.multiplyScalar( scale ); sw.multiplyScalar( scale );
} else { } else {
sw.set( 1 ); // this will be normalized by the shader anyway sw.set( 1 ); // this will be normalized by the shader anyway
} }
} }
}; };
THREE.SkinnedMesh.offsetMatrix = new THREE.Matrix4();
/** /**
* @author alteredq / http://alteredqualia.com/ * @author alteredq / http://alteredqualia.com/
*/ */
......
...@@ -234,10 +234,11 @@ THREE.Bone.prototype.update=function(a,b){this.matrixAutoUpdate&&(b=b|this.updat ...@@ -234,10 +234,11 @@ THREE.Bone.prototype.update=function(a,b){this.matrixAutoUpdate&&(b=b|this.updat
THREE.SkinnedMesh=function(a,b,c){THREE.Mesh.call(this,a,b);this.useVertexTexture=c!==void 0?c:true;this.identityMatrix=new THREE.Matrix4;this.bones=[];this.boneMatrices=[];var d,f,e;if(this.geometry.bones!==void 0){for(a=0;a<this.geometry.bones.length;a++){c=this.geometry.bones[a];d=c.pos;f=c.rotq;e=c.scl;b=this.addBone();b.name=c.name;b.position.set(d[0],d[1],d[2]);b.quaternion.set(f[0],f[1],f[2],f[3]);b.useQuaternion=true;e!==void 0?b.scale.set(e[0],e[1],e[2]):b.scale.set(1,1,1)}for(a=0;a<this.bones.length;a++){c= THREE.SkinnedMesh=function(a,b,c){THREE.Mesh.call(this,a,b);this.useVertexTexture=c!==void 0?c:true;this.identityMatrix=new THREE.Matrix4;this.bones=[];this.boneMatrices=[];var d,f,e;if(this.geometry.bones!==void 0){for(a=0;a<this.geometry.bones.length;a++){c=this.geometry.bones[a];d=c.pos;f=c.rotq;e=c.scl;b=this.addBone();b.name=c.name;b.position.set(d[0],d[1],d[2]);b.quaternion.set(f[0],f[1],f[2],f[3]);b.useQuaternion=true;e!==void 0?b.scale.set(e[0],e[1],e[2]):b.scale.set(1,1,1)}for(a=0;a<this.bones.length;a++){c=
this.geometry.bones[a];b=this.bones[a];c.parent===-1?this.add(b):this.bones[c.parent].add(b)}a=this.bones.length;if(this.useVertexTexture){this.boneTextureHeight=this.boneTextureWidth=a=a>256?64:a>64?32:a>16?16:8;this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4);this.boneTexture=new THREE.DataTexture(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,THREE.RGBAFormat,THREE.FloatType);this.boneTexture.minFilter=THREE.NearestFilter;this.boneTexture.magFilter= this.geometry.bones[a];b=this.bones[a];c.parent===-1?this.add(b):this.bones[c.parent].add(b)}a=this.bones.length;if(this.useVertexTexture){this.boneTextureHeight=this.boneTextureWidth=a=a>256?64:a>64?32:a>16?16:8;this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4);this.boneTexture=new THREE.DataTexture(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,THREE.RGBAFormat,THREE.FloatType);this.boneTexture.minFilter=THREE.NearestFilter;this.boneTexture.magFilter=
THREE.NearestFilter;this.boneTexture.generateMipmaps=false;this.boneTexture.flipY=false}else this.boneMatrices=new Float32Array(16*a);this.pose()}};THREE.SkinnedMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.SkinnedMesh.prototype.addBone=function(a){a===void 0&&(a=new THREE.Bone(this));this.bones.push(a);return a}; THREE.NearestFilter;this.boneTexture.generateMipmaps=false;this.boneTexture.flipY=false}else this.boneMatrices=new Float32Array(16*a);this.pose()}};THREE.SkinnedMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.SkinnedMesh.prototype.addBone=function(a){a===void 0&&(a=new THREE.Bone(this));this.bones.push(a);return a};
THREE.SkinnedMesh.prototype.updateMatrixWorld=function(a){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||a){this.parent?this.matrixWorld.multiply(this.parent.matrixWorld,this.matrix):this.matrixWorld.copy(this.matrix);this.matrixWorldNeedsUpdate=false}for(var a=0,b=this.children.length;a<b;a++){var c=this.children[a];c instanceof THREE.Bone?c.update(this.identityMatrix,false):c.updateMatrixWorld(true)}if(this.boneInverses==void 0){this.boneInverses=[];for(a=0;a<this.bones.length;a++){b= THREE.SkinnedMesh.prototype.updateMatrixWorld=function(a){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||a){this.parent?this.matrixWorld.multiply(this.parent.matrixWorld,this.matrix):this.matrixWorld.copy(this.matrix);this.matrixWorldNeedsUpdate=false}for(var a=0,b=this.children.length;a<b;a++){var c=this.children[a];c instanceof THREE.Bone?c.update(this.identityMatrix,false):c.updateMatrixWorld(true)}if(this.boneInverses==void 0){this.boneInverses=[];a=0;for(b=this.bones.length;a<
new THREE.Matrix4;b.getInverse(this.bones[a].skinMatrix);this.boneInverses.push(b)}}for(a=0;a<this.bones.length;a++){b=new THREE.Matrix4;b.multiply(this.bones[a].skinMatrix,this.boneInverses[a]);b.flattenToArrayOffset(this.boneMatrices,a*16)}if(this.useVertexTexture)this.boneTexture.needsUpdate=true}; b;a++){c=new THREE.Matrix4;c.getInverse(this.bones[a].skinMatrix);this.boneInverses.push(c)}}a=0;for(b=this.bones.length;a<b;a++){THREE.SkinnedMesh.offsetMatrix.multiply(this.bones[a].skinMatrix,this.boneInverses[a]);THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset(this.boneMatrices,a*16)}if(this.useVertexTexture)this.boneTexture.needsUpdate=true};
THREE.SkinnedMesh.prototype.pose=function(){this.updateMatrixWorld(true);for(var a=0;a<this.geometry.skinIndices.length;a++){var b=this.geometry.skinWeights[a],c=1/b.lengthManhattan();c!=Infinity?b.multiplyScalar(c):b.set(1)}};THREE.MorphAnimMesh=function(a,b){THREE.Mesh.call(this,a,b);this.duration=1E3;this.mirroredLoop=false;this.currentKeyframe=this.lastKeyframe=this.time=0;this.direction=1;this.directionBackwards=false;this.setFrameRange(0,this.geometry.morphTargets.length-1)}; THREE.SkinnedMesh.prototype.pose=function(){this.updateMatrixWorld(true);for(var a=0;a<this.geometry.skinIndices.length;a++){var b=this.geometry.skinWeights[a],c=1/b.lengthManhattan();c!==Infinity?b.multiplyScalar(c):b.set(1)}};THREE.SkinnedMesh.offsetMatrix=new THREE.Matrix4;
THREE.MorphAnimMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphAnimMesh.prototype.setFrameRange=function(a,b){this.startKeyframe=a;this.endKeyframe=b;this.length=this.endKeyframe-this.startKeyframe+1};THREE.MorphAnimMesh.prototype.setDirectionForward=function(){this.direction=1;this.directionBackwards=false};THREE.MorphAnimMesh.prototype.setDirectionBackward=function(){this.direction=-1;this.directionBackwards=true}; THREE.MorphAnimMesh=function(a,b){THREE.Mesh.call(this,a,b);this.duration=1E3;this.mirroredLoop=false;this.currentKeyframe=this.lastKeyframe=this.time=0;this.direction=1;this.directionBackwards=false;this.setFrameRange(0,this.geometry.morphTargets.length-1)};THREE.MorphAnimMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphAnimMesh.prototype.setFrameRange=function(a,b){this.startKeyframe=a;this.endKeyframe=b;this.length=this.endKeyframe-this.startKeyframe+1};
THREE.MorphAnimMesh.prototype.setDirectionForward=function(){this.direction=1;this.directionBackwards=false};THREE.MorphAnimMesh.prototype.setDirectionBackward=function(){this.direction=-1;this.directionBackwards=true};
THREE.MorphAnimMesh.prototype.parseAnimations=function(){var a=this.geometry;if(!a.animations)a.animations={};for(var b,c=a.animations,d=/([a-z]+)(\d+)/,f=0,e=a.morphTargets.length;f<e;f++){var g=a.morphTargets[f].name.match(d);if(g&&g.length>1){g=g[1];c[g]||(c[g]={start:Infinity,end:-Infinity});var h=c[g];if(f<h.start)h.start=f;if(f>h.end)h.end=f;b||(b=g)}}a.firstAnimation=b}; THREE.MorphAnimMesh.prototype.parseAnimations=function(){var a=this.geometry;if(!a.animations)a.animations={};for(var b,c=a.animations,d=/([a-z]+)(\d+)/,f=0,e=a.morphTargets.length;f<e;f++){var g=a.morphTargets[f].name.match(d);if(g&&g.length>1){g=g[1];c[g]||(c[g]={start:Infinity,end:-Infinity});var h=c[g];if(f<h.start)h.start=f;if(f>h.end)h.end=f;b||(b=g)}}a.firstAnimation=b};
THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){if(!this.geometry.animations)this.geometry.animations={};this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];if(c){this.setFrameRange(c.start,c.end);this.duration=1E3*((c.end-c.start)/b);this.time=0}else console.warn("animation["+a+"] undefined")}; THREE.MorphAnimMesh.prototype.setAnimationLabel=function(a,b,c){if(!this.geometry.animations)this.geometry.animations={};this.geometry.animations[a]={start:b,end:c}};THREE.MorphAnimMesh.prototype.playAnimation=function(a,b){var c=this.geometry.animations[a];if(c){this.setFrameRange(c.start,c.end);this.duration=1E3*((c.end-c.start)/b);this.time=0}else console.warn("animation["+a+"] undefined")};
THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time=this.time+this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||this.time<0){this.direction=this.direction*-1;if(this.time>this.duration){this.time=this.duration;this.directionBackwards=true}if(this.time<0){this.time=0;this.directionBackwards=false}}}else{this.time=this.time%this.duration;if(this.time<0)this.time=this.time+this.duration}a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/ THREE.MorphAnimMesh.prototype.updateAnimation=function(a){var b=this.duration/this.length;this.time=this.time+this.direction*a;if(this.mirroredLoop){if(this.time>this.duration||this.time<0){this.direction=this.direction*-1;if(this.time>this.duration){this.time=this.duration;this.directionBackwards=true}if(this.time<0){this.time=0;this.directionBackwards=false}}}else{this.time=this.time%this.duration;if(this.time<0)this.time=this.time+this.duration}a=this.startKeyframe+THREE.Math.clamp(Math.floor(this.time/
......
...@@ -169,38 +169,39 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) { ...@@ -169,38 +169,39 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
} }
} }
// make a snapshot of the bones' rest position // make a snapshot of the bones' rest position
if (this.boneInverses == undefined) if ( this.boneInverses == undefined ) {
{
this.boneInverses = []; this.boneInverses = [];
for ( var b = 0; b < this.bones.length; b ++ ) for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
{
var inverse = new THREE.Matrix4(); var inverse = new THREE.Matrix4();
inverse.getInverse( this.bones[ b ].skinMatrix ); inverse.getInverse( this.bones[ b ].skinMatrix );
this.boneInverses.push( inverse ); this.boneInverses.push( inverse );
} }
} }
// flatten bone matrices to array // flatten bone matrices to array
for ( var b = 0; b < this.bones.length; b ++ ) for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
{
var offset = new THREE.Matrix4();
// compute the offset between the current and the original transform; // compute the offset between the current and the original transform;
//TODO: we could get rid of this multiplication step if the skinMatrix //TODO: we could get rid of this multiplication step if the skinMatrix
// was already representing the offset; however, this requires some // was already representing the offset; however, this requires some
// major changes to the animation system // major changes to the animation system
offset.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
offset.flattenToArrayOffset( this.boneMatrices, b * 16 ); THREE.SkinnedMesh.offsetMatrix.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
} }
if ( this.useVertexTexture ) { if ( this.useVertexTexture ) {
...@@ -218,24 +219,28 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) { ...@@ -218,24 +219,28 @@ THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
THREE.SkinnedMesh.prototype.pose = function() { THREE.SkinnedMesh.prototype.pose = function() {
this.updateMatrixWorld( true ); this.updateMatrixWorld( true );
for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) { for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
// normalize weights // normalize weights
var sw = this.geometry.skinWeights[ i ]; var sw = this.geometry.skinWeights[ i ];
var scale = 1.0 / sw.lengthManhattan(); var scale = 1.0 / sw.lengthManhattan();
if ( scale != Infinity ) { if ( scale !== Infinity ) {
sw.multiplyScalar( scale ); sw.multiplyScalar( scale );
} else { } else {
sw.set( 1 ); // this will be normalized by the shader anyway sw.set( 1 ); // this will be normalized by the shader anyway
} }
} }
}; };
THREE.SkinnedMesh.offsetMatrix = new THREE.Matrix4();
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册