| 757 | */ |
| 758 | |
| 759 | void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, |
| 760 | dxJoint **joint, int nj, dReal stepsize) |
| 761 | { |
| 762 | |
| 763 | int i,j; |
| 764 | IFTIMING(dTimerStart("preprocessing");) |
| 765 | |
| 766 | dReal stepsize1 = dRecip(stepsize); |
| 767 | |
| 768 | // number all bodies in the body list - set their tag values |
| 769 | for (i=0; i<nb; i++) body[i]->tag = i; |
| 770 | |
| 771 | // make a local copy of the joint array, because we might want to modify it. |
| 772 | // (the "dxJoint *const*" declaration says we're allowed to modify the joints |
| 773 | // but not the joint array, because the caller might need it unchanged). |
| 774 | //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints |
| 775 | //dxJoint **joint = (dxJoint**) alloca (nj * sizeof(dxJoint*));//slipch@ - no need to copy with sipmle island processing |
| 776 | //memcpy (joint,_joint,nj * sizeof(dxJoint*)); |
| 777 | |
| 778 | // for all bodies, compute the inertia tensor and its inverse in the global |
| 779 | // frame, and compute the rotational force and add it to the torque |
| 780 | // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body. |
| 781 | dRealAllocaArray (I,3*4*nb); // need to remember all I's for feedback purposes only |
| 782 | dRealAllocaArray (invI,3*4*nb); |
| 783 | for (i=0; i<nb; i++) { |
| 784 | |
| 785 | dMatrix3 tmp; |
| 786 | dxBody *b=body[i]; |
| 787 | #ifdef DEBUG_VALID |
| 788 | dIASSERT(dValid(b->tacc[0])&&dValid(b->tacc[1])&&dValid(b->tacc[2])); |
| 789 | #endif |
| 790 | // compute inertia tensor in global frame |
| 791 | dMULTIPLY2_333 (tmp,b->mass.I,body[i]->R); |
| 792 | dMULTIPLY0_333 (I+i*12,b->R,tmp); |
| 793 | // compute inverse inertia tensor in global frame |
| 794 | dMULTIPLY2_333 (tmp,b->invI,b->R); |
| 795 | dMULTIPLY0_333 (invI+i*12,b->R,tmp); |
| 796 | // compute rotational force |
| 797 | dMULTIPLY0_331 (tmp,I+i*12,b->avel); |
| 798 | |
| 799 | dCROSS (b->tacc,-=,b->avel,tmp); |
| 800 | #ifndef dNODEBUG |
| 801 | if(!(dValid(b->tacc[0])&&dValid(b->tacc[1])&&dValid(b->tacc[2]))) |
| 802 | { |
| 803 | //char s[64]; |
| 804 | //_snprintf (s,sizeof(s),"tmp %f,%f,%f \n avel %f,%f,%f",tmp[0],tmp[1],tmp[2],b->avel[0],b->avel[1],b->avel[2]); |
| 805 | //dUASSERT(0,"tmp %f,%f,%f \n avel %f,%f,%f",tmp[0],tmp[1],tmp[2],b->avel[0],b->avel[1],b->avel[2]); |
| 806 | |
| 807 | dDebug (d_ERR_UASSERT," (%s:%d \n tmp %f,%f,%f \n avel %f,%f,%f)", __FILE__,__LINE__,tmp[0],tmp[1],tmp[2],b->avel[0],b->avel[1],b->avel[2]); |
| 808 | } |
| 809 | |
| 810 | #endif |
| 811 | } |
| 812 | |
| 813 | // add the gravity force to all bodies |
| 814 | for (i=0; i<nb; i++) { |
| 815 | if ((body[i]->flags & dxBodyNoGravity)==0) { |
| 816 | body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; |
nothing calls this directly
no test coverage detected