xzw 1 месяц назад
Родитель
Сommit
aa7d20e6b1
3 измененных файлов с 35 добавлено и 7 удалено
  1. 8 5
      libs/three.js/build/three.module.js
  2. 26 1
      src/custom/three.shim.js
  3. 1 1
      src/custom/viewer/ViewerNew.js

+ 8 - 5
libs/three.js/build/three.module.js

@@ -24444,7 +24444,7 @@ function WebGLRenderer( parameters ) {
 
 					if ( object.skeleton.frame !== info.render.frame ) {
 
-						object.skeleton.update();
+						object.skeleton.update(object);//xzw add object for avoidBigNumber
 						object.skeleton.frame = info.render.frame;
 
 					}
@@ -26337,7 +26337,9 @@ SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
 
 		if ( this.bindMode === 'attached' ) {
 
-			this.bindMatrixInverse.copy( this.matrixWorld ).invert();
+			//this.bindMatrixInverse.copy( this.matrixWorld ).invert();
+            this.bindMatrixInverse.copy( this.matrix ).invert();//xzw改 for avoidBigNumber
+
 
 		} else if ( this.bindMode === 'detached' ) {
 
@@ -26521,7 +26523,7 @@ Object.assign( Skeleton.prototype, {
 
 	},
 
-	update: function () {
+	update: function (skinMesh) {//xzw add skinMesh
 
 		const bones = this.bones;
 		const boneInverses = this.boneInverses;
@@ -26529,12 +26531,13 @@ Object.assign( Skeleton.prototype, {
 		const boneTexture = this.boneTexture;
 
 		// flatten bone matrices to array
+        let matrixWorldInverse = skinMesh.matrixWorld.clone().invert() //add
 
 		for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
 			// compute the offset between the current and the original transform
-
-			const matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;
+			//const matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;
+			const matrix = bones[ i ] ? bones[ i ].matrixWorld.clone().premultiply(matrixWorldInverse) : _identityMatrix; //xzw 改 for avoidBigNumber
 
 			_offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
 			_offsetMatrix.toArray( boneMatrices, i * 16 );

+ 26 - 1
src/custom/three.shim.js

@@ -657,6 +657,8 @@ THREE.SkinnedMesh.prototype.applyBoneTransform = function(index, vector) {
     _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index);
 
     _basePosition.copy(vector).applyMatrix4(this.bindMatrix);
+    
+    let matrixWorldInverse = this.matrixWorld.clone().invert() //xzw add avoidBigNumber 
 
     vector.set(0, 0, 0);
 
@@ -669,7 +671,7 @@ THREE.SkinnedMesh.prototype.applyBoneTransform = function(index, vector) {
             const boneIndex = _skinIndex.getComponent(i);
 
             _matrix4.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]);
-
+            _matrix4.premultiply(matrixWorldInverse) //xzw add avoidBigNumber
             vector.addScaledVector(_vector3.copy(_basePosition).applyMatrix4(_matrix4), weight);
 
         }
@@ -680,6 +682,29 @@ THREE.SkinnedMesh.prototype.applyBoneTransform = function(index, vector) {
 
 }
 
+
+/* 
+
+    动画模型在移动到百万米远处扭曲了。观察如下:
+    
+    有两处关键,在外和传入shader的,是一样的算法。
+    
+    
+    传入shader的有mesh的bindMatrixInverse和骨骼上的 boneTexture(也就是keleton.boneMatrices) 
+  
+    transformed = ( bindMatrixInverse * skinned ).xyz;//这里没有经过最外层的位移
+    其中skinned是经过boneTexture的位移  
+ 
+    而boneMatrices即bone.matrixWorld * boneInverse。 
+    boneInverse初始化后就不变了,前者因为随着模型位移而变得很大,所以我将其乘以mesh的逆矩阵
+    bindMatrixInverse是 matrixWorld.invert(), 我改为matrix.invert, 两者中和了,都去掉了大数字。
+     
+    所修改处都有avoidBigNumber标识
+
+
+ */
+
+
 THREE.SkinnedMesh.prototype._computeIntersections = function(raycaster, intersects, rayLocalSpace) {
 
     let intersection;

+ 1 - 1
src/custom/viewer/ViewerNew.js

@@ -6168,7 +6168,7 @@ export class Viewer extends ViewerBase{
     }
     
      
-    gltfAddAnimation(model){
+    gltfAddAnimation(model){ 
         
         if(model.gltf?.animations.length){
             let skeleton = new THREE.SkeletonHelper( model );