@@ -140,6 +140,114 @@ static void polarDecomposition(const Eigen::Matrix3f &A, Eigen::Matrix3f &R, Eig
140140	R.col (2 ) = c2;
141141}
142142
143+ /* * Return the one norm of the matrix.
144+ */ 
145+ static  float  oneNorm (const  Eigen::Matrix3f &A) 
146+ {
147+ 	const  float  sum1 = fabs (A (0 ,0 )) + fabs (A (1 ,0 )) + fabs (A (2 ,0 ));
148+ 	const  float  sum2 = fabs (A (0 ,1 )) + fabs (A (1 ,1 )) + fabs (A (2 ,1 ));
149+ 	const  float  sum3 = fabs (A (0 ,2 )) + fabs (A (1 ,2 )) + fabs (A (2 ,2 ));
150+ 	float  maxSum = sum1;
151+ 	if  (sum2 > maxSum)
152+ 		maxSum = sum2;
153+ 	if  (sum3 > maxSum)
154+ 		maxSum = sum3;
155+ 	return  maxSum;
156+ }
157+ 
158+ /* * Return the inf norm of the matrix.
159+ */ 
160+ static  float  infNorm (const  Eigen::Matrix3f &A)
161+ {
162+ 	const  float  sum1 = fabs (A (0 , 0 )) + fabs (A (0 , 1 )) + fabs (A (0 , 2 ));
163+ 	const  float  sum2 = fabs (A (1 , 0 )) + fabs (A (1 , 1 )) + fabs (A (1 , 2 ));
164+ 	const  float  sum3 = fabs (A (2 , 0 )) + fabs (A (2 , 1 )) + fabs (A (2 , 2 ));
165+ 	float  maxSum = sum1;
166+ 	if  (sum2 > maxSum)
167+ 		maxSum = sum2;
168+ 	if  (sum3 > maxSum)
169+ 		maxSum = sum3;
170+ 	return  maxSum;
171+ }
172+ 
173+ /* * Perform a polar decomposition of matrix M and return the rotation matrix R. This method handles the degenerated cases.
174+ */ 
175+ static  void  polarDecomposition2 (const  Eigen::Matrix3f &M, const  float  tolerance, Eigen::Matrix3f &R)
176+ {
177+ 	Eigen::Matrix3f Mt = M.transpose ();
178+ 	float  Mone = oneNorm (M);
179+ 	float  Minf = infNorm (M);
180+ 	float  Eone;
181+ 	Eigen::Matrix3f MadjTt, Et;
182+ 	do 
183+ 	{
184+ 		MadjTt.row (0 ) = Mt.row (1 ).cross (Mt.row (2 ));
185+ 		MadjTt.row (1 ) = Mt.row (2 ).cross (Mt.row (0 ));
186+ 		MadjTt.row (2 ) = Mt.row (0 ).cross (Mt.row (1 ));
187+ 
188+ 		float  det = Mt (0 ,0 ) * MadjTt (0 ,0 ) + Mt (0 ,1 ) * MadjTt (0 ,1 ) + Mt (0 ,2 ) * MadjTt (0 ,2 );
189+ 
190+ 		if  (fabs (det) < 1.0e-12 )
191+ 		{
192+ 			Eigen::Vector3f len;
193+ 			unsigned  int  index = 0xffffffff ;
194+ 			for  (unsigned  int  i = 0 ; i < 3 ; i++)
195+ 			{
196+ 				len[i] = MadjTt.row (i).squaredNorm ();
197+ 				if  (len[i] > 1.0e-12 )
198+ 				{
199+ 					//  index of valid cross product
200+ 					//  => is also the index of the vector in Mt that must be exchanged
201+ 					index = i;
202+ 					break ;
203+ 				}
204+ 			}
205+ 			if  (index == 0xffffffff )
206+ 			{
207+ 				R.setIdentity ();
208+ 				return ;
209+ 			}
210+ 			else 
211+ 			{
212+ 				Mt.row (index) = Mt.row ((index + 1 ) % 3 ).cross (Mt.row ((index + 2 ) % 3 ));
213+ 				MadjTt.row ((index + 1 ) % 3 ) = Mt.row ((index + 2 ) % 3 ).cross (Mt.row (index));
214+ 				MadjTt.row ((index + 2 ) % 3 ) = Mt.row (index).cross (Mt.row ((index + 1 ) % 3 ));
215+ 				Eigen::Matrix3f M2 = Mt.transpose ();
216+ 				Mone = oneNorm (M2);
217+ 				Minf = infNorm (M2);
218+ 				det = Mt (0 ,0 ) * MadjTt (0 ,0 ) + Mt (0 ,1 ) * MadjTt (0 ,1 ) + Mt (0 ,2 ) * MadjTt (0 ,2 );
219+ 			}
220+ 		}
221+ 
222+ 		const  float  MadjTone = oneNorm (MadjTt);
223+ 		const  float  MadjTinf = infNorm (MadjTt);
224+ 
225+ 		const  float  gamma = sqrt (sqrt ((MadjTone*MadjTinf) / (Mone*Minf)) / fabs (det));
226+ 
227+ 		const  float  g1 = gamma*0 .5f ;
228+ 		const  float  g2 = 0 .5f  / (gamma*det);
229+ 
230+ 		for  (unsigned  char  i = 0 ; i < 3 ; i++)
231+ 		{
232+ 			for  (unsigned  char  j = 0 ; j < 3 ; j++)
233+ 			{
234+ 				Et (i,j) = Mt (i,j);
235+ 				Mt (i,j) = g1*Mt (i,j) + g2*MadjTt (i,j);
236+ 				Et (i,j) -= Mt (i,j);
237+ 			}
238+ 		}
239+ 
240+ 		Eone = oneNorm (Et);
241+ 
242+ 		Mone = oneNorm (Mt);
243+ 		Minf = infNorm (Mt);
244+ 	} while  (Eone > Mone * tolerance);
245+ 
246+ 	//  Q = Mt^T 
247+ 	R = Mt.transpose ();
248+ }
249+ 
250+ 
143251//  ----------------------------------------------------------------------------------------------
144252bool  PositionBasedDynamics::solveDistanceConstraint (
145253	const  Eigen::Vector3f &p0, float  invMass0, 
@@ -653,7 +761,8 @@ bool PositionBasedDynamics::computeShapeMatchingRestInfo(
653761	restCm /= wsum;
654762
655763	//  A
656- 	invRestMat.setZero ();
764+ 	Eigen::Matrix3f A;
765+ 	A.setZero ();
657766	for  (int  i = 0 ; i < numPoints; i++) {
658767		const  Eigen::Vector3f qi = x0[i] - restCm;
659768		float  wi = 1 .0f  / (invMasses[i] + eps);
@@ -663,21 +772,21 @@ bool PositionBasedDynamics::computeShapeMatchingRestInfo(
663772		float  xy = wi * qi[0 ] * qi[1 ];
664773		float  xz = wi * qi[0 ] * qi[2 ];
665774		float  yz = wi * qi[1 ] * qi[2 ];
666- 		invRestMat (0 , 0 ) += x2; invRestMat (0 , 1 ) += xy; invRestMat (0 , 2 ) += xz;
667- 		invRestMat (1 , 0 ) += xy; invRestMat (1 , 1 ) += y2; invRestMat (1 , 2 ) += yz;
668- 		invRestMat (2 , 0 ) += xz; invRestMat (2 , 1 ) += yz; invRestMat (2 , 2 ) += z2;
775+ 		A (0 , 0 ) += x2; A (0 , 1 ) += xy; A (0 , 2 ) += xz;
776+ 		A (1 , 0 ) += xy; A (1 , 1 ) += y2; A (1 , 2 ) += yz;
777+ 		A (2 , 0 ) += xz; A (2 , 1 ) += yz; A (2 , 2 ) += z2;
669778	}
670- 	float  det = invRestMat .determinant ();
779+ 	float  det = A .determinant ();
671780	if  (fabs (det) > 1.0e-9 )
672781	{
673- 		invRestMat = invRestMat .inverse ();
782+ 		invRestMat = A .inverse ();
674783		return  true ;
675784	}
676785	return  false ;
677786}
678787
679788//  ----------------------------------------------------------------------------------------------
680- bool  PositionBasedDynamics::shapeMatchingConstraint  (
789+ bool  PositionBasedDynamics::solveShapeMatchingConstraint  (
681790	const  Eigen::Vector3f x0[], const  Eigen::Vector3f x[], const  float  invMasses[], int  numPoints,
682791	Eigen::Vector3f &restCm, const  Eigen::Matrix3f &invRestMat,
683792	float  stiffness,
@@ -692,7 +801,8 @@ bool PositionBasedDynamics::shapeMatchingConstraint(
692801	//  center of mass
693802	Eigen::Vector3f cm (0 .0f , 0 .0f , 0 .0f );
694803	float  wsum = 0 .0f ;
695- 	for  (int  i = 0 ; i < numPoints; i++) {
804+ 	for  (int  i = 0 ; i < numPoints; i++) 
805+ 	{
696806		float  wi = 1 .0f  / (invMasses[i] + eps);
697807		cm += x[i] * wi;
698808		wsum += wi;
@@ -723,7 +833,8 @@ bool PositionBasedDynamics::shapeMatchingConstraint(
723833	if  (allowStretch)
724834		R = mat;
725835	else 
726- 		polarDecomposition (mat, R, U, D);
836+ 		// polarDecomposition(mat, R, U, D);
837+ 		polarDecomposition2 (mat, 1e-6f , R);
727838
728839	for  (int  i = 0 ; i < numPoints; i++) {
729840		Eigen::Vector3f goal = cm + R * (x0[i] - restCm);
0 commit comments