@@ -140,6 +140,114 @@ static void polarDecomposition(const Eigen::Matrix3f &A, Eigen::Matrix3f &R, Eig
140
140
R.col (2 ) = c2;
141
141
}
142
142
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
+
143
251
// ----------------------------------------------------------------------------------------------
144
252
bool PositionBasedDynamics::solveDistanceConstraint (
145
253
const Eigen::Vector3f &p0, float invMass0,
@@ -653,7 +761,8 @@ bool PositionBasedDynamics::computeShapeMatchingRestInfo(
653
761
restCm /= wsum;
654
762
655
763
// A
656
- invRestMat.setZero ();
764
+ Eigen::Matrix3f A;
765
+ A.setZero ();
657
766
for (int i = 0 ; i < numPoints; i++) {
658
767
const Eigen::Vector3f qi = x0[i] - restCm;
659
768
float wi = 1 .0f / (invMasses[i] + eps);
@@ -663,21 +772,21 @@ bool PositionBasedDynamics::computeShapeMatchingRestInfo(
663
772
float xy = wi * qi[0 ] * qi[1 ];
664
773
float xz = wi * qi[0 ] * qi[2 ];
665
774
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;
669
778
}
670
- float det = invRestMat .determinant ();
779
+ float det = A .determinant ();
671
780
if (fabs (det) > 1.0e-9 )
672
781
{
673
- invRestMat = invRestMat .inverse ();
782
+ invRestMat = A .inverse ();
674
783
return true ;
675
784
}
676
785
return false ;
677
786
}
678
787
679
788
// ----------------------------------------------------------------------------------------------
680
- bool PositionBasedDynamics::shapeMatchingConstraint (
789
+ bool PositionBasedDynamics::solveShapeMatchingConstraint (
681
790
const Eigen::Vector3f x0[], const Eigen::Vector3f x[], const float invMasses[], int numPoints,
682
791
Eigen::Vector3f &restCm, const Eigen::Matrix3f &invRestMat,
683
792
float stiffness,
@@ -692,7 +801,8 @@ bool PositionBasedDynamics::shapeMatchingConstraint(
692
801
// center of mass
693
802
Eigen::Vector3f cm (0 .0f , 0 .0f , 0 .0f );
694
803
float wsum = 0 .0f ;
695
- for (int i = 0 ; i < numPoints; i++) {
804
+ for (int i = 0 ; i < numPoints; i++)
805
+ {
696
806
float wi = 1 .0f / (invMasses[i] + eps);
697
807
cm += x[i] * wi;
698
808
wsum += wi;
@@ -723,7 +833,8 @@ bool PositionBasedDynamics::shapeMatchingConstraint(
723
833
if (allowStretch)
724
834
R = mat;
725
835
else
726
- polarDecomposition (mat, R, U, D);
836
+ // polarDecomposition(mat, R, U, D);
837
+ polarDecomposition2 (mat, 1e-6f , R);
727
838
728
839
for (int i = 0 ; i < numPoints; i++) {
729
840
Eigen::Vector3f goal = cm + R * (x0[i] - restCm);
0 commit comments