00001
00002
00003 #define MODULE_IK 1
00004
00005 #include "animate.h"
00006
00007
00008 void AssignIKchain(node *Np, long frame){
00009 return;
00010 }
00011
00012 void RemoveIKchain(node *Np, long frame){
00013 return;
00014 }
00015
00016 void RemoveAllIKchains(node *Np, long frame){
00017 return;
00018 }
00019
00020
00021 #if 0
00022 static void IterateTowardsGoal(HWND hWnd,int xi, int yi){
00023 double *J,*Jt,*dTheta,*I,*dI,*Ji;
00024 double x[3],dx[3];
00025 long Nv1,Nv2,n=0;
00026 if(Lv < 0)return;
00027 if(debug != NULL)fprintf(debug,"Test No. %ld\n",++version);
00028 Nv1=Nv-1;
00029 Nv1=Lv;
00030 Nv2=Nv1-Sv;
00031 SaveLast();
00032
00033 x[0]=TVlist[Nv1].p[0]+(double)xi;
00034 x[1]=TVlist[Nv1].p[1]+(double)yi;
00035 x[2]=TVlist[Nv1].p[2]+(double)0.0;
00036 VECSUB(x,TVlist[Nv1].p,dx)
00037 if(debug != NULL)fprintf(debug,"Initial |dx| = %lf\n",Length(dx,3));
00038 if((dTheta=(double *)malloc((3*Nv2)*sizeof(double))) == NULL)return;
00039 if((J=(double *)malloc(3*(3*Nv2)*sizeof(double))) == NULL)return;
00040 if((Jt=(double *)malloc((3*Nv2)*3*sizeof(double))) == NULL)return;
00041 if((Ji=(double *)malloc((3*Nv2)*3*sizeof(double))) == NULL)return;
00042 if((dI=(double *)malloc(3*3*sizeof(double))) == NULL)return;
00043 if((I=(double *)malloc(3*3*sizeof(double))) == NULL)return;
00044
00045 while(1){
00046 VECSUB(x,TVlist[Nv1].p,dx)
00047 if(++n > 50){
00048 if(debug != NULL)fprintf(debug,"*********** Out of iteration ******\n");
00049
00050 RevertToLast();
00051 MessageBeep(MB_OK);
00052 break;
00053 }
00054 CalculateJacobian(J,Nv2,Sv);
00055 CalculateTranspose(J,Jt,3,3*Nv2);
00056 MultiplyMatrix(J,3,3*Nv2,Jt,3*Nv2,3,I);
00057 if(InvertMatrix(I,3,dI)){
00058
00059 MultiplyMatrix(Jt,3*Nv2,3,dI,3,3,Ji);
00060
00061
00062
00063 if(debug != NULL)fprintf(debug,"Iteration %ld ",n);
00064 if(!StepOK(J,Ji,dx,3,3*Nv2,1.e-2,1.e-6)){
00065 MessageBox(NULL,"Dx too small",NULL,MB_OK);
00066 break;
00067 }
00068 else{
00069
00070 MultiplyMatrix(Ji,3*Nv2,3,dx,3,1,dTheta);
00071
00072 UpdateTheLinkage(Nv1,Nv,Sv,dTheta);
00073 if(Dist(TVlist[Nv1].p,x,3) < 3.0){
00074 if(debug != NULL)
00075 fprintf(debug,"converged in %ld iterations with |dx| = %lf\n",
00076 n,Length(dx,3));
00077 break;
00078 }
00079 else{
00080 if(debug != NULL)fprintf(debug,"linkage not yet at end point\n");
00081 }
00082 }
00083 }
00084 else{
00085 MessageBox(NULL,"Singular matrix",NULL,MB_OK);
00086 }
00087 }
00088
00089 free(dTheta);
00090 free(Ji);
00091 free(I);
00092 free(dI);
00093 free(Jt);
00094 free(J);
00095 InvalidateRect(hWnd,NULL,FALSE);
00096 return;
00097 }
00098
00099 static void CalculateJacobian(double *J,
00100 long n,
00101 long ns
00102 ){
00103 long k,l;
00104 vector ax,ay,az,dp,Jx,Jy,Jz;
00105 for(l=0,k=0;k<n;k++){
00106 VECCOPY(TVlist[k+ns].ax,ax)
00107 VECCOPY(TVlist[k+ns].ay,ay)
00108 VECCOPY(TVlist[k+ns].az,az)
00109 VECSUB(TVlist[n+ns].p,TVlist[k+ns].p,dp)
00110 CROSS(ax,dp,Jx)
00111 CROSS(ay,dp,Jy)
00112 CROSS(az,dp,Jz)
00113 J[l] = Jx[0];
00114 J[l+n*3] = Jx[1];
00115 J[l+n*3*2] = Jx[2];
00116 l++;
00117 J[l] = Jy[0];
00118 J[l+n*3] = Jy[1];
00119 J[l+n*3*2] = Jy[2];
00120 l++;
00121 J[l] = Jz[0];
00122 J[l+n*3] = Jz[1];
00123 J[l+n*3*2] = Jz[2];
00124 l++;
00125 }
00126 #if 0
00127 l=3*2;
00128 for(k=l;k<l+3;k++){
00129 J[k]=0.0;
00130 J[k+n*3]=0.0;
00131 J[k+n*3*2]=0.0;
00132 }
00133 #endif
00134 #if 0
00135 for(l=0,k=0;k<n;k++){
00136 J[l] *= (1.0+2.0*(double)(k));
00137 J[l+n*3] *= (1.0+2.0*(double)(k));
00138 J[l+n*3*2] *= (1.0+2.0*(double)(k));
00139 l++;
00140 J[l] *= (1.0+2.0*(double)(k));
00141 J[l+n*3] *= (1.0+2.0*(double)(k));
00142 J[l+n*3*2] *= (1.0+2.0*(double)(k));
00143 l++;
00144 J[l] *= (1.0+2.0*(double)(k));
00145 J[l+n*3] *= (1.0+2.0*(double)(k));
00146 J[l+n*3*2] *= (1.0+2.0*(double)(k));
00147 l++;
00148 }
00149 #endif
00150 return;
00151 }
00152
00153 static void UpdateTheLinkage(long Nv1, long Nv, long Ns, double *dTheta){
00154 long i,j,l;
00155 double thetaX,thetaY,thetaZ;
00156 vector ax,ay,az,baseZero={0.0,0.0,0.0};
00157 for(i=Ns,l=0;i<Nv1;i++,l+=3){
00158
00159
00160 thetaX = *(dTheta+l);
00161 thetaY = *(dTheta+l+1);
00162 thetaZ = *(dTheta+l+2);
00163 VECCOPY(TVlist[i].ax,ax)
00164 VECCOPY(TVlist[i].ay,ay)
00165 VECCOPY(TVlist[i].az,az)
00166
00167
00168 for(j=i+1;j<Nv;j++){
00169 RotateVectorRound(TVlist[j].p,TVlist[i].p,ax,thetaX);
00170 RotateVectorRound(TVlist[j].p,TVlist[i].p,ay,thetaY);
00171 RotateVectorRound(TVlist[j].p,TVlist[i].p,az,thetaZ);
00172 RotateVectorRound(TVlist[j].ax,baseZero,ax,thetaX);
00173 RotateVectorRound(TVlist[j].ax,baseZero,ay,thetaY);
00174 RotateVectorRound(TVlist[j].ax,baseZero,az,thetaZ);
00175 RotateVectorRound(TVlist[j].ay,baseZero,ax,thetaX);
00176 RotateVectorRound(TVlist[j].ay,baseZero,ay,thetaY);
00177 RotateVectorRound(TVlist[j].ay,baseZero,az,thetaZ);
00178 RotateVectorRound(TVlist[j].az,baseZero,ax,thetaX);
00179 RotateVectorRound(TVlist[j].az,baseZero,ay,thetaY);
00180 RotateVectorRound(TVlist[j].az,baseZero,az,thetaZ);
00181 TVlist[j].x=(int)TVlist[j].p[0];
00182 TVlist[j].y=(int)TVlist[j].p[1];
00183 TVlist[j].z=(int)TVlist[j].p[2];
00184 }
00185 }
00186 return;
00187 }
00188
00189 static BOOL StepOK(double *J, double *Ji, double *dx,
00190 long n, long m,
00191 double e, double dmin){
00192
00193 BOOL result=TRUE;
00194 long i;
00195 double *I,*N,norm=0.0;
00196 if((I=(double *)malloc(n*n*sizeof(double))) == NULL)return FALSE;
00197 if((N=(double *)malloc(n*sizeof(double))) == NULL)return FALSE;
00198 MultiplyMatrix(J,n,m,Ji,m,n,I);
00199 if(debug != NULL){
00200 fprintf(debug,"\nInverse matrix\n");
00201 for(i=0;i<n;i++){
00202 long j;
00203 for(j=0;j<3;j++){
00204 fprintf(debug,"%lf ",I[i*n+j]);
00205 }
00206 fprintf(debug,"\n");
00207 }
00208 }
00209 for(i=0;i<n;i++){
00210 I[i*n+i] -= 1.0;
00211 }
00212 while(1){
00213 MultiplyMatrix(I,n,n,dx,n,1,N);
00214 norm=0.0;
00215 for(i=0;i<n;i++){
00216 norm += N[i] * N[i];
00217 }
00218 if(debug != NULL)fprintf(debug,"Norm = %lf\n",norm);
00219 if(norm < e)break;
00220 for(i=0;i<n;i++)dx[i] *= 0.5;
00221 if(Length(dx,n) < dmin){
00222 result=FALSE;
00223 break;
00224 }
00225 }
00226 free(N);
00227 free(I);
00228 return result;
00229 }
00230
00231 static void SaveLast(void){
00232 long i;
00233 for(i=0;i<Nv;i++){
00234 TVlist[i].lx=TVlist[i].x;
00235 TVlist[i].ly=TVlist[i].y;
00236 TVlist[i].lz=TVlist[i].z;
00237 VECCOPY(TVlist[i].p,TVlist[i].lp)
00238 VECCOPY(TVlist[i].ax,TVlist[i].lax)
00239 VECCOPY(TVlist[i].ay,TVlist[i].lay)
00240 VECCOPY(TVlist[i].az,TVlist[i].laz)
00241 }
00242 return;
00243 }
00244
00245 static void RevertToLast(void){
00246 long i;
00247 for(i=0;i<Nv;i++){
00248 TVlist[i].x=TVlist[i].lx;
00249 TVlist[i].y=TVlist[i].ly;
00250 TVlist[i].z=TVlist[i].lz;
00251 VECCOPY(TVlist[i].lp,TVlist[i].p)
00252 VECCOPY(TVlist[i].lax,TVlist[i].ax)
00253 VECCOPY(TVlist[i].lay,TVlist[i].ay)
00254 VECCOPY(TVlist[i].laz,TVlist[i].az)
00255 }
00256 return;
00257 }
00258
00259 static void SetupStart(void){
00260 int i;
00261 vector x0={1.0,0.0,0.0},y0={0.0,1.0,0.0},z0={0.0,0.0,1.0};
00262 if(Nv < 2)return;
00263 for(i=0;i<Nv;i++){
00264 TVlist[i].p[0]=(double)TVlist[i].x;
00265 TVlist[i].p[1]=(double)TVlist[i].y;
00266 TVlist[i].p[2]=0.0;
00267 VECCOPY(x0,TVlist[i].ax)
00268 VECCOPY(y0,TVlist[i].ay)
00269 VECCOPY(z0,TVlist[i].az)
00270 }
00271 }
00272
00273 static void RotateVectorRound(vector v,
00274 vector BaseOfRotation,
00275 vector AxisOfRotation,
00276 double theta){
00277
00278 double t[4][4];
00279 vector lv,lvv;
00280 VECSUB(v,BaseOfRotation,lv)
00281 rotate_round_vector(theta,AxisOfRotation,t);
00282 mv4by1(t,lv,lvv);
00283 VECSUM(lvv,BaseOfRotation,v)
00284 return;
00285 }
00286
00287 static void rotz(double tr[4][4], double ang){
00288 short i,j;
00289 for(i=0;i<4;i++)
00290 for(j=0;j<4;j++){
00291 tr[i][j]=0.0;
00292 if(i == j)tr[i][j]=1.0;
00293 }
00294 tr[0][0]= cos(ang);
00295 tr[0][1]=-sin(ang);
00296 tr[1][0]= sin(ang);
00297 tr[1][1]= cos(ang);
00298 return;
00299 }
00300
00301 static void roty(double tr[4][4], double ang){
00302 short i,j;
00303 for(i=0;i<4;i++)
00304 for(j=0;j<4;j++){
00305 tr[i][j]=0.0;
00306 if(i == j)tr[i][j]=1.0;
00307 }
00308 tr[0][0]= cos(ang);
00309 tr[0][2]=-sin(ang);
00310 tr[2][0]= sin(ang);
00311 tr[2][2]= cos(ang);
00312 return;
00313 }
00314
00315 static void rotx(double tr[4][4], double ang){
00316 long i,j;
00317 for(i=0;i<4;i++)
00318 for(j=0;j<4;j++){
00319 tr[i][j]=0.0;
00320 if(i == j)tr[i][j]=1.0;
00321 }
00322 tr[1][1]= cos(ang);
00323 tr[1][2]=-sin(ang);
00324 tr[2][1]= sin(ang);
00325 tr[2][2]= cos(ang);
00326 return;
00327 }
00328
00329 static void mv4by1(double t4[4][4], vector v1, vector v2){
00330 double xx,yy,zz;
00331 xx=t4[0][0]*v1[0]+t4[0][1]*v1[1]+t4[0][2]*v1[2]+t4[0][3];
00332 yy=t4[1][0]*v1[0]+t4[1][1]*v1[1]+t4[1][2]*v1[2]+t4[1][3];
00333 zz=t4[2][0]*v1[0]+t4[2][1]*v1[1]+t4[2][2]*v1[2]+t4[2][3];
00334 v2[0]=xx; v2[1]=yy; v2[2]=zz;
00335 return;
00336 }
00337
00338 static void m4by4(double t1[4][4], double t2[4][4], double tr[4][4]){
00339 short n=4,i,j,k;
00340 for(i=0;i<4;i++)
00341 for(j=0;j<4;j++){
00342 tr[i][j]=0.0;
00343 for(k=0;k<4;k++)tr[i][j]=tr[i][j]+t1[i][k]*t2[k][j];
00344 }
00345 return;
00346 }
00347
00348 static void rotate_round_vector(double angle, vector v, double t[4][4]){
00349 double dx,dy,dz,phi,theta,dxy;
00350 double t1[4][4],t2[4][4],t3[4][4];
00351 dx=v[0]; dy=v[1]; dz=v[2];
00352 dxy=dx*dx+dy*dy;
00353 if(dxy < 0.00001){
00354 if(dz > 0.0)rotz(t, angle);
00355 else rotz(t,-angle);
00356 return;
00357 }
00358 dxy=sqrt(dxy);
00359 if (dx == 0.0 && dy > 0.0)phi = PI2;
00360 else if(dx == 0.0 && dy < 0.0)phi = -PI2;
00361 else phi = atan2(dy,dx);
00362 theta = atan2(dz,dxy);
00363 rotz(t3, -phi);
00364 roty(t2, -theta);
00365 m4by4(t2,t3,t1);
00366 rotx(t2, angle);
00367 m4by4(t2,t1,t3);
00368 roty(t2,theta);
00369 m4by4(t2,t3,t1);
00370 rotz(t2,phi);
00371 m4by4(t2,t1,t);
00372 }
00373
00374 static double Length(double *dx, long n){
00375 long i;
00376 double l=0.0;
00377 for(i=0;i<n;i++)l += dx[i]*dx[i];
00378 return sqrt(l);
00379 }
00380
00381 static double Dist(double *x, double *y, long n){
00382 long i;
00383 double d=0.0;
00384 for(i=0;i<n;i++)d += (x[i]-y[i])*(x[i]-y[i]);
00385 return sqrt(d);
00386 }
00387
00388 static void CalculateTranspose(double *M, double *Mt, long n, long m){
00389 long i,j;
00390 for(i=0;i<n;i++){
00391 for(j=0;j<m;j++){
00392 *(Mt+j*n+i) = *(M+i*m+j);
00393 }
00394 }
00395 return;
00396 }
00397
00398 static void MultiplyMatrix(double *M1, long n1, long m1,
00399 double *M2, long n2, long m2,
00400 double *I){
00401 long i,j,k,c;
00402 double s;
00403 if(m1 != n2){MessageBox(NULL,"Bad Multiply",NULL,MB_OK); return;}
00404 c=n2;
00405 for(i=0;i<n1;i++){
00406 for(j=0;j<m2;j++){
00407 for(s=0.0,k=0;k<c;k++){
00408 s += (*(M1+i*m1+k)) * (*(M2+k*m2+j));
00409
00410 }
00411 *(I+i*m2+j) = s;
00412 }
00413 }
00414 return;
00415 }
00416
00417 static BOOL InvertMatrix(double *A, long n, double *B){
00418 int i,j,k,imax,kp1;
00419 double del,amax,atmp,btmp,div,amult,eps=1.e-6;
00420 for(i=0;i<n;i++)for(j=0;j<n;j++){
00421 if(i == j)B[i*n+j]=1.0;
00422 else B[i*n+j]=0.0;
00423 }
00424 del=1.0;
00425 for(k=0;k<n;k++){
00426 if(k < n-1){
00427 imax=k;
00428 amax=fabs(A[k*n+k]);
00429 kp1=k+1;
00430 for(i=kp1;i<n;i++){
00431 if(amax-fabs(A[i*n+k]) < 0.0){
00432 imax=i;
00433 amax=fabs(A[i*n+k]);
00434 }
00435 }
00436 if(imax != k){
00437 for(j=0;j<n;j++){
00438 atmp=A[imax*n+j];
00439 A[imax*n+j]=A[k*n+j];
00440 A[k*n+j]=atmp;
00441 btmp=B[imax*n+j];
00442 B[imax*n+j]=B[k*n+j];
00443 B[k*n+j]=btmp;
00444 }
00445 del = -del;
00446 }
00447 }
00448 if(fabs(A[k*n+k]) < eps)return FALSE;
00449 del=A[k*n+k]*del;
00450 div=1.0/A[k*n+k];
00451 for(j=0;j<n;j++){
00452 A[k*n+j]=A[k*n+j]*div;
00453 B[k*n+j]=B[k*n+j]*div;
00454 }
00455 for(i=0;i<n;i++){
00456 amult=A[i*n+k];
00457 if(i != k){
00458 for(j=0;j<n;j++){
00459 A[i*n+j]=A[i*n+j]-amult*A[k*n+j];
00460 B[i*n+j]=B[i*n+j]-amult*B[k*n+j];
00461 }
00462 }
00463 }
00464 }
00465 return TRUE;
00466 }
00467
00468 #endif