| 314 | #endif |
| 315 | |
| 316 | static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, dxBody * const *body, |
| 317 | dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr fc, dRealMutablePtr b, |
| 318 | dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex, |
| 319 | dxQuickStepParameters *qs) |
| 320 | { |
| 321 | const int num_iterations = qs->num_iterations; |
| 322 | const dReal sor_w = qs->w; // SOR over-relaxation parameter |
| 323 | |
| 324 | int i,j; |
| 325 | |
| 326 | #ifdef WARM_STARTING |
| 327 | // for warm starting, this seems to be necessary to prevent |
| 328 | // jerkiness in motor-driven joints. i have no idea why this works. |
| 329 | for (i=0; i<m; i++) lambda[i] *= REAL(0.9); |
| 330 | #else |
| 331 | dSetZero (lambda,m); |
| 332 | #endif |
| 333 | |
| 334 | // the lambda computed at the previous iteration. |
| 335 | // this is used to measure error for when we are reordering the indexes. |
| 336 | dRealAllocaArray (last_lambda,m); |
| 337 | |
| 338 | // a copy of the 'hi' vector in case findex[] is being used |
| 339 | dRealAllocaArray (hicopy,m); |
| 340 | memcpy (hicopy,hi,m*sizeof(dReal)); |
| 341 | |
| 342 | // precompute iMJ = inv(M)*J' |
| 343 | dRealAllocaArray (iMJ,m*12); |
| 344 | compute_invM_JT (m,J,iMJ,jb,body,invI); |
| 345 | |
| 346 | // compute fc=(inv(M)*J')*lambda. we will incrementally maintain fc |
| 347 | // as we change lambda. |
| 348 | #ifdef WARM_STARTING |
| 349 | multiply_invM_JT (m,nb,iMJ,jb,lambda,fc); |
| 350 | #else |
| 351 | dSetZero (fc,nb*6); |
| 352 | #endif |
| 353 | |
| 354 | // precompute 1 / diagonals of A |
| 355 | dRealAllocaArray (Ad,m); |
| 356 | dRealPtr iMJ_ptr = iMJ; |
| 357 | dRealMutablePtr J_ptr = J; |
| 358 | for (i=0; i<m; i++) { |
| 359 | dReal sum = 0; |
| 360 | for (j=0; j<6; j++) sum += iMJ_ptr[j] * J_ptr[j]; |
| 361 | if (jb[i*2+1] >= 0) { |
| 362 | for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; |
| 363 | } |
| 364 | iMJ_ptr += 12; |
| 365 | J_ptr += 12; |
| 366 | Ad[i] = sor_w / (sum + cfm[i]); |
| 367 | } |
| 368 | |
| 369 | // scale J and b by Ad |
| 370 | J_ptr = J; |
| 371 | for (i=0; i<m; i++) { |
| 372 | for (j=0; j<12; j++) { |
| 373 | J_ptr[0] *= Ad[i]; |
no test coverage detected