CAMERA.C

Go to the documentation of this file.
00001 /* file CAMERA.C  */
00002 
00003 // This file contains the code to render the camera perspective
00004 // view into the camera perspective window. It includes the
00005 // code to render the animation preview.
00006 
00007 #define MODULE ANI_PRSP 1
00008 
00009 #include "animate.h"
00010 
00011 #define GROUND_GRID_SIZE 10
00012 
00013 static void DrawStagePerspective(HDC, HWND, int , point ,BOOL);
00014 static void DrawQuickWire(HDC hdcView,
00015                           object *Op, double mr, double t1[4][4],
00016                           short pwincx, short pwincy);
00017 static void DrawNurbsPersp(HDC hdcView,
00018                           object *Op, double mr, double t1[4][4],
00019                           short pwincx, short pwincy);
00020 static BOOL CalculateEffectedVertices(double mr,
00021                                       double tall[4][4],
00022                                       double tc[4][4], double tp[4][4],
00023                                       BOOL  ground,
00024                                       point p, point gpos, point cpos,
00025                                       object *op, Svertex *Vp);
00026 static void ClipToPlane(double *x1, double *y1, double *z1,
00027                         double x2, double y2, double z2, long Cp);
00028 static BOOL ClipToWindow(long *x1, long *y1,
00029                          long *x2, long *y2,
00030                          long xmin, long ymin,
00031                          long xmax, long ymax);
00032 
00033 static double trr[4][4];
00034 static double scalex,scaley,dt;
00035 static double CameraAlpha,CameraTheta,CameraHeight;
00036 static short ep1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
00037 static short ep2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
00038 
00039 static void DrawStagePerspective(HDC hdcView, HWND hWnd,
00040                                  int DisplayType, point cP,
00041                                  BOOL check_abort){
00042  double  x1,y1,z1,x2,y2,z2,alpha,theta,phi,sx,sy,sz,ima,y_offset
00043          ,t1[4][4],t2[4][4],t3[4][4],t4[4][4],mr,rxyz[3];
00044  short   flag,im,pwinl,pwinr,pwint,pwinb,pwincx,pwincy;
00045  int     ix1,iy1,ix2,iy2;
00046  long    lx1,ly1,lx2,ly2;
00047  long    i,j,k,Nv,Nl,Nm,xyz[3],id[2],*sid,*sidl,qstep;
00048  node    *Np;
00049  object  *Op;
00050  Svertex *Vp;
00051  point   *Vm;
00052  point   Offset,TrackedOffset,grP;
00053  skel    *sp,*spl;
00054  RECT    rc;
00055  HPEN hGpen;
00056  BOOL gg=FALSE;
00057  mr=1.0;
00058  GetClientRect(hWnd,&rc);
00059  pwinl=pwint=0; pwinr=rc.right; pwinb=rc.bottom;
00060  pwincx=rc.right/2; pwincy=rc.bottom/2;
00061  if(hdcView == NULL)goto XXIT;
00062 // if(bAbortedDrawing){
00063 //   DisplayType=0;
00064 //   KillTimer(ghwnd_main,1);
00065 //   SetTimer(ghwnd_main,1,30,NULL);
00066 // }
00067  //TRYAGAIN:
00068  if((Np=FirstNp) != NULL)while(Np != NULL){ /* ground and lights */
00069    if(Np->type == GROUND && ((Op=Np->fobj) != NULL))while(Op != NULL){
00070      if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
00071        y_offset = (double)(scaley*(dt*tan(-CameraAlpha)));
00072        ix1 = (int)( 1000.0*cos(-CameraTheta)
00073                              - y_offset*sin(-CameraTheta) + pwincx);
00074        iy1 = (int)( 1000.0*sin( CameraTheta)
00075                              - y_offset*cos( CameraTheta) + pwincy);
00076        ix2 = (int)(-1000.0*cos(-CameraTheta)
00077                              - y_offset*sin(-CameraTheta) + pwincx);
00078        iy2 = (int)(-1000.0*sin( CameraTheta)
00079                              - y_offset*cos( CameraTheta) + pwincy);
00080        hGpen=SelectObject(hdcView,GetStockObject(BLACK_PEN));
00081        MoveToEx(hdcView,ix1,iy1,NULL);
00082        LineTo(hdcView,ix2,iy2);
00083        GetTransform(0,CurrentFrame,1.0,
00084                     Np,Op,Offset,TrackedOffset,&phi,&theta,&alpha,
00085                     &sx,&sy,&sz,&im,&ima);
00086        gg=TRUE;
00087        VECCOPY(Offset,grP)
00088        if(!Preferences.ground){ /* ground grid as well as horizon */
00089          long xx,yy,dx,dy,dxx,dyy,grid_size,Cp=UNIT;
00090          theta *= PIo180;
00091          phi   *= PIo180;
00092          alpha *= PIo180;
00093          scal(t3,sx,sy,sz);
00094          if(im > 0){
00095            if     (im == 1)rotz(t1,ima*PIo180);
00096            else if(im == 2)rotx(t1,ima*PIo180);
00097            else if(im == 3)roty(t1,ima*PIo180);
00098            roty(t4,theta);
00099            m4by4(t4,t1,t2);
00100          }
00101          else roty(t2,theta);
00102          m4by4(t2,t3,t1);
00103          rotx(t2,alpha);
00104          m4by4(t2,t1,t3);
00105          rotz(t1,phi);
00106          m4by4(t1,t3,t2);
00107          tram(t1,(double)Offset[0],(double)Offset[1],(double)Offset[2]);
00108          m4by4(t1,t2,t3);
00109          m4by4(trr,t3,t1);
00110          grid_size=UNIT*4;
00111          for(i=0;i<2;i++){
00112            yy = (grid_size/2)*GROUND_GRID_SIZE; xx = -yy;
00113            if(i == 0){
00114              dx=0; dy = -grid_size*GROUND_GRID_SIZE;
00115              dxx=grid_size;    dyy=0;
00116            }
00117            else{
00118              dx=grid_size*GROUND_GRID_SIZE; dy = 0;
00119              dxx=0; dyy = -grid_size;
00120            }
00121            for(j=0;j<GROUND_GRID_SIZE+1;j++){
00122              flag=0;
00123              m4by1(t1,(double)xx,(double)yy,0.0,&x1,&y1,&z1);
00124              m4by1(t1,(double)(xx+dx),(double)(yy+dy),0.0,&x2,&y2,&z2);
00125              if(y1 > Cp || y2 > Cp){
00126                if(y1 < Cp)ClipToPlane(&x1,&y1,&z1,x2,y2,z2,Cp);
00127                lx1=(long)((double)pwincx+scalex*x1/y1);
00128                ly1=(long)((double)pwincy-scaley*z1/y1);
00129                if(y2 < Cp)ClipToPlane(&x2,&y2,&z2,x1,y1,z1,Cp);
00130                lx2=(long)((double)pwincx+scalex*x2/y2);
00131                ly2=(long)((double)pwincy-scaley*z2/y2);
00132                if(ClipToWindow(&lx1,&ly1,&lx2,&ly2,
00133                                pwinl,pwint,pwinr,pwinb)){
00134                  MoveToEx(hdcView,lx1,ly1,NULL);
00135                  LineTo(hdcView,lx2,ly2);
00136                }
00137              }
00138              xx=xx+dxx; yy=yy+dyy;
00139            }
00140          }
00141        }
00142        SelectObject(hdcView,hGpen);
00143        break;
00144      }
00145      Op=Op->next;
00146    }
00147    else if(Np->type == LIGHT && ((Op=Np->fobj) != NULL))while(Op != NULL){
00148      if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
00149        GetTransform(0,CurrentFrame,1.0,
00150                     Np,Op,Offset,TrackedOffset,&phi,&theta,&alpha,
00151                     &sx,&sy,&sz,&im,&ima);
00152        tram(t1,(double)Offset[0],(double)Offset[1],(double)Offset[2]);
00153        m4by4(trr,t1,t2);
00154        m4by1(t2,0.0,0.0,0.0,&x1,&y1,&z1);
00155        if(y1 > dt){
00156          ix1=(int)(pwincx+scalex*x1*dt/(y1));
00157          iy1=(int)(pwincy-scaley*z1*dt/(y1));
00158          if(ix1 < 0 || ix1 >= pwinr || iy1 < 0 || iy1 >= pwinb)break;
00159          hGpen=SelectObject(hdcView,GetStockObject(BLACK_PEN));
00160          MoveToEx(hdcView,ix1-2,iy1,NULL); LineTo(hdcView,ix1+3,iy1);
00161          MoveToEx(hdcView,ix1,iy1-2,NULL); LineTo(hdcView,ix1,iy1+3);
00162          SelectObject(hdcView,hGpen);
00163        }
00164        break;
00165      }
00166      Op=Op->next;
00167    }
00168    Np=Np->next;
00169  }
00170 
00171  if((Np=FirstNp) != NULL)while(Np != NULL){
00172    if(   (Np->type == NORMAL || Np->type == ANIMOBJ || Np->type == PARTICLE)
00173       && ((Op=Np->fobj) != NULL))while(Op != NULL){
00174      if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
00175        GetTransform(0,CurrentFrame,1.0,
00176                     Np,Op,Offset,TrackedOffset,&phi,&theta,&alpha,
00177                     &sx,&sy,&sz,&im,&ima);
00178        theta *= PIo180;
00179        phi   *= PIo180;
00180        alpha *= PIo180;
00181        scal(t3,sx,sy,sz);
00182        if(im > 0){
00183          if     (im == 1)rotz(t1,ima*PIo180);
00184          else if(im == 2)rotx(t1,ima*PIo180);
00185          else if(im == 3)roty(t1,ima*PIo180);
00186          roty(t4,theta);
00187          m4by4(t4,t1,t2);
00188        }
00189        else roty(t2,theta);
00190        m4by4(t2,t3,t1);
00191        rotx(t2,alpha);
00192        m4by4(t2,t1,t3);
00193        rotz(t1,phi);
00194        m4by4(t1,t3,t2);
00195        tram(t1,(double)Offset[0],(double)Offset[1],(double)Offset[2]);
00196        m4by4(t1,t2,t3);  /* does't take object origin into account */
00197        m4by4(trr,t3,t1);
00198        if(DisplayType == 0 || Op->quick_only == 1 || Op->type == PARTICLE){
00199         if(Op->morph != NO && Op->last != NULL){
00200           mr=(double)(Op->lastframe - Op->firstframe+1);
00201           mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00202         }
00203         if(Op->w_frame.p != NULL){
00204           DrawQuickWire(hdcView,Op,mr,t1,pwincx,pwincy);
00205           goto CONTINUE;
00206         }
00207         for(i=0;i<12;i++){
00208          flag=0;
00209         if(Op->morph != NO && Op->last != NULL){
00210            m4by1(t1,(double)(Op->outline[ep1[i]][0] -
00211                        Op->last->outline[ep1[i]][0])*mr +
00212                        (double)Op->last->outline[ep1[i]][0],
00213                     (double)(Op->outline[ep1[i]][1] -
00214                        Op->last->outline[ep1[i]][1])*mr +
00215                        (double)Op->last->outline[ep1[i]][1],
00216                     (double)(Op->outline[ep1[i]][2] -
00217                        Op->last->outline[ep1[i]][2])*mr +
00218                        (double)Op->last->outline[ep1[i]][2],
00219                     &x1,&y1,&z1);
00220            m4by1(t1,(double)(Op->outline[ep2[i]][0] -
00221                        Op->last->outline[ep2[i]][0])*mr +
00222                        (double)Op->last->outline[ep2[i]][0],
00223                     (double)(Op->outline[ep2[i]][1] -
00224                        Op->last->outline[ep2[i]][1])*mr +
00225                        (double)Op->last->outline[ep2[i]][1],
00226                     (double)(Op->outline[ep2[i]][2] -
00227                        Op->last->outline[ep2[i]][2])*mr +
00228                        (double)Op->last->outline[ep2[i]][2],
00229                     &x2,&y2,&z2);
00230          }
00231          else{
00232            m4by1(t1 ,(double)Op->outline[ep1[i]][0]
00233                     ,(double)Op->outline[ep1[i]][1]
00234                     ,(double)Op->outline[ep1[i]][2]
00235                     ,&x1,&y1,&z1);
00236            m4by1(t1 ,(double)Op->outline[ep2[i]][0]
00237                     ,(double)Op->outline[ep2[i]][1]
00238                     ,(double)Op->outline[ep2[i]][2]
00239                     ,&x2,&y2,&z2);
00240          }
00241          if(y1 > dt){ /* point infront of viewing plane */
00242            ix1=(int)(pwincx+scalex*x1*dt/(y1));
00243            iy1=(int)(pwincy-scaley*z1*dt/(y1));
00244            if(ix1 < -16000 || ix1 > 16000)flag=1;
00245            if(iy1 < -16000 || iy1 > 16000)flag=1;
00246          }
00247          else  flag=1;
00248          if(y2 > dt){
00249            ix2=(int)(pwincx+scalex*x2*dt/(y2));
00250            iy2=(int)(pwincy-scaley*z2*dt/(y2));
00251            if(ix2 < -16000 || ix2 > 16000)flag=1;
00252            if(iy2 < -16000 || iy2 > 16000)flag=1;
00253          }
00254          else flag=1;
00255          if(flag == 0){
00256            MoveToEx(hdcView,ix1,iy1,NULL);
00257            LineTo(hdcView,ix2,iy2);
00258          }
00259         }
00260         CONTINUE:;
00261        }
00262        else{ /* draw the object */
00263         if(Op->morph != NO && Op->last != NULL && Op->last->in_ram){
00264           mr=(double)(Op->lastframe - Op->firstframe+1);
00265           if(Op->lastframe == Nframes)mr += 1.0;
00266           mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00267           Nm=Op->last->npoints;
00268         }
00269         else Nm=0;
00270         if(Op->in_ram && Op->points != NULL){
00271          Nv=Op->npoints;
00272          if(Nv > 0){
00273           Vp=(Svertex *)X__Malloc(Nv*sizeof(Svertex));
00274           if(Vp != NULL){
00275            if(Nv != Nm){
00276              if(!CalculateEffectedVertices(-1.0,t1,trr,t3,
00277                                             gg,Offset,grP,cP,Op,Vp))
00278              for(i=0;i<Nv;i++){
00279                m4by1(t1,(double)(Op->points[i][0] - Op->origin[0]),
00280                         (double)(Op->points[i][1] - Op->origin[1]),
00281                         (double)(Op->points[i][2] - Op->origin[2]),
00282                         &x1,&y1,&z1);
00283                Vp[i][0]=(float)x1; Vp[i][1]=(float)y1; Vp[i][2]=(float)z1;
00284              }
00285            }
00286            else{
00287              long l,m;
00288              if(!CalculateEffectedVertices(mr,t1,trr,t3,
00289                                            gg,Offset,grP,cP,Op,Vp))
00290              for(i=0;i<Nv;i++){
00291                for(j=0;j<3;j++){
00292                  l = Op->points[i][j] - Op->origin[j];
00293                  m = Op->last->points[i][j] - Op->last->origin[j];
00294                  rxyz[j] = (double)(l-m)*mr + (double)m;
00295                }
00296                m4by1(t1,rxyz[0],rxyz[1],rxyz[2]
00297                        ,&x1,&y1,&z1);
00298                Vp[i][0]=(float)x1; Vp[i][1]=(float)y1; Vp[i][2]=(float)z1;
00299              }
00300            }
00301            Nl = Op->nedges;
00302            if(global_quickdraw){
00303              if(Nl < 100)qstep=1;
00304              else if(Nl <   1000)qstep=2;
00305              else if(Nl <   2500)qstep=3;
00306              else if(Nl <   5000)qstep=4;
00307              else if(Nl <  10000)qstep=6;
00308              else if(Nl <  20000)qstep=8;
00309              else if(Nl <  50000)qstep=12;
00310              else if(Nl < 100000)qstep=25;
00311              else qstep=40;
00312            }
00313            else qstep=1;
00314            if(Nl > 0){
00315 #ifdef _LINE_DRAW
00316 LPPOINT lppt;
00317 LPBYTE  lpbTypes;
00318 int     cCount;
00319 long    pcount;
00320  if((lppt=(LPPOINT)LocalAlloc(LMEM_FIXED,2*Nl*sizeof(POINT))) == NULL)goto XXIT;
00321  if((lpbTypes=(LPBYTE)LocalAlloc(LMEM_FIXED,2*Nl*sizeof(BYTE))) == NULL){
00322   LocalFree((HLOCAL)lppt);
00323   goto XXIT;
00324  }
00325  cCount=0; pcount=0;
00326 #endif
00327              for(i=0;i<Nl;i += qstep){
00328                id[0] = Op->edges[i][0];
00329                id[1] = Op->edges[i][1];
00330                flag=0;
00331                x1=Vp[id[0]][0];  x2=Vp[id[1]][0];
00332                y1=Vp[id[0]][1];  y2=Vp[id[1]][1];
00333                z1=Vp[id[0]][2];  z2=Vp[id[1]][2];
00334                if(y1 > dt){ /* point infront of viewing plane */
00335                  ix1=(int)(pwincx+scalex*x1*dt/(y1));
00336                  iy1=(int)(pwincy-scaley*z1*dt/(y1));
00337                  if(ix1 < -16000 || ix1 > 16000)flag=1;
00338                  if(iy1 < -16000 || iy1 > 16000)flag=1;
00339                }
00340                else  flag=1;
00341                if(y2 > dt){
00342                  ix2=(int)(pwincx+scalex*x2*dt/(y2));
00343                  iy2=(int)(pwincy-scaley*z2*dt/(y2));
00344                  if(ix2 < -16000 || ix2 > 16000)flag=1;
00345                  if(iy2 < -16000 || iy2 > 16000)flag=1;
00346                }
00347                else flag=1;
00348                if(flag == 0){
00349                  if( !Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2 ){
00350 #ifdef _LINE_DRAW
00351     lppt[cCount].x=ix1; lppt[cCount].y=iy1;
00352     lpbTypes[cCount]=PT_MOVETO; cCount++;
00353     lppt[cCount].x=ix2; lppt[cCount].y=iy2;
00354     lpbTypes[cCount]=PT_LINETO; cCount++;
00355 #else
00356                    MoveToEx(hdcView,ix1,iy1,NULL);
00357                    LineTo(hdcView,ix2,iy2);
00358                    if(bAbortedDrawing){
00359                      X__Free(Vp);
00360                      bAbortedDrawing=FALSE;
00361                      goto XXIT;
00362                    }
00363 #if 0
00364                    if(check_abort && HIWORD(GetQueueStatus(QS_KEY|QS_MOUSEBUTTON))){
00365                      X__Free(Vp);
00366                      bAbortedDrawing=TRUE;
00367                      DisplayType=0;
00368                      SetTimer(ghwnd_main,1,50,NULL);
00369                      goto XXIT;
00370                      //goto TRYAGAIN;
00371                    }
00372 #endif
00373 #endif
00374                  }
00375                }
00376              }
00377 #ifdef _LINE_DRAW
00378  if(PolyDraw(hdcView,lppt,lpbTypes,cCount) == FALSE){
00379    char message[128];
00380    sprintf(message,"ERROR: pcount=%ld ccount=%ld",pcount,cCount);
00381    MessageBox (NULL,message, NULL,
00382    MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
00383  }
00384  LocalFree((HLOCAL)lppt);
00385  LocalFree((HLOCAL)lpbTypes);
00386 #endif
00387            }
00388            X__Free(Vp);
00389           }
00390           else{
00391            //  Don't do this because of multithreading
00392            //  SendPrgmQuery(IDQ_NOMEM3,0);
00393           }
00394          }
00395         }
00396         else{
00397           //  Don't do this because of multithreading
00398           //  SendPrgmQuery(IDQ_NOFINDMODEL,0);
00399         }
00400         // Draw Any NURBS
00401         DrawNurbsPersp(hdcView,Op,mr,t1,pwincx,pwincy);
00402        }
00403      }
00404      Op=Op->next;
00405    }
00406    else if(Np->type == ROBOT && ((Op=Np->fobj) != NULL))while(Op != NULL){
00407      if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
00408        if(Op->nskeleton == 0 || (sp=Op->skeleton) == NULL)break;
00409        GetTransform(0,CurrentFrame,1.0,
00410                     Np,Op,Offset,TrackedOffset,&phi,&theta,&alpha,
00411                     &sx,&sy,&sz,&im,&ima);
00412        RobotTransform(Offset,phi,theta,alpha,sx,sy,sz,im,ima,t1);
00413        m4by4(trr,t1,t3);
00414        mr=(double)(Op->lastframe - Op->firstframe+1);
00415        mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00416        InterpolateRobot(mr,Op,Op->last);
00417        if(Op->last != NULL)spl=Op->last->skeleton;
00418        else                spl=NULL;
00419        if(DisplayType == 0){
00420          for(k=0;k<Op->nskeleton;k++){
00421            flag=0;
00422            m4by4(t3,(Op->skeleton+k)->T,t4);
00423            for(i=0;i<12;i++){
00424              m4by1(t4 ,(double)(Op->skeleton+k)->bx[ep1[i]][0]
00425                       ,(double)(Op->skeleton+k)->bx[ep1[i]][1]
00426                       ,(double)(Op->skeleton+k)->bx[ep1[i]][2]
00427                       ,&x1,&y1,&z1);
00428              m4by1(t4 ,(double)(Op->skeleton+k)->bx[ep2[i]][0]
00429                       ,(double)(Op->skeleton+k)->bx[ep2[i]][1]
00430                       ,(double)(Op->skeleton+k)->bx[ep2[i]][2]
00431                       ,&x2,&y2,&z2);
00432              if(y1 > dt){ /* point infront of viewing plane */
00433                ix1=(int)(pwincx+scalex*x1*dt/(y1));
00434                iy1=(int)(pwincy-scaley*z1*dt/(y1));
00435                if(ix1 < -16000 || ix1 > 16000)flag=1;
00436                if(iy1 < -16000 || iy1 > 16000)flag=1;
00437              }
00438              else  flag=1;
00439              if(y2 > dt){
00440                ix2=(int)(pwincx+scalex*x2*dt/(y2));
00441                iy2=(int)(pwincy-scaley*z2*dt/(y2));
00442                if(ix2 < -16000 || ix2 > 16000)flag=1;
00443                if(iy2 < -16000 || iy2 > 16000)flag=1;
00444              }
00445              else flag=1;
00446              if(flag == 0){
00447                MoveToEx(hdcView,ix1,iy1,NULL);
00448                LineTo(hdcView,ix2,iy2);
00449              }
00450            }
00451          }
00452 #if 0
00453          for(k=0;k<Op->nskeleton;k++){
00454            x1=(double)sp[k].pp[0];
00455            y1=(double)sp[k].pp[1];
00456            z1=(double)sp[k].pp[2];
00457            m4by1(t3,x1,y1,z1,&x2,&y2,&z2);
00458            sp[k].wk[0]=(long)x2;
00459            sp[k].wk[1]=(long)y2;
00460            sp[k].wk[2]=(long)z2;
00461          }
00462          for(k=1;k<Op->nskeleton;k++){
00463            flag=0;
00464            x1=(double)sp[k].wk[0];
00465            y1=(double)sp[k].wk[1];
00466            z1=(double)sp[k].wk[2];
00467            if((j=sp[k].id) < Op->nskeleton){
00468              x2=(double)sp[j].wk[0];
00469              y2=(double)sp[j].wk[1];
00470              z2=(double)sp[j].wk[2];
00471            }
00472            else{ x2=x1; y2=y1; z2=z1;}
00473            if(y1 > dt){ /* point infront of viewing plane */
00474              ix1=(int)(pwincx+scalex*x1*dt/(y1));
00475              iy1=(int)(pwincy-scaley*z1*dt/(y1));
00476              if(ix1 < -16000 || ix1 > 16000)flag=1;
00477              if(iy1 < -16000 || iy1 > 16000)flag=1;
00478            }
00479            else  flag=1;
00480            if(y2 > dt){
00481              ix2=(int)(pwincx+scalex*x2*dt/(y2));
00482              iy2=(int)(pwincy-scaley*z2*dt/(y2));
00483              if(ix2 < -16000 || ix2 > 16000)flag=1;
00484              if(iy2 < -16000 || iy2 > 16000)flag=1;
00485            }
00486            else flag=1;
00487            if(flag == 0){
00488              MoveToEx(hdcView,ix1,iy1,NULL);
00489              LineTo(hdcView,ix2,iy2);
00490            }
00491          }
00492 #endif
00493        }
00494        else{ /* full robot */
00495          Vm=NULL;  Vp=NULL; sid=Op->skid;
00496          if(Op->morph != NO && Op->last != NULL && (sidl=Op->last->skid) != NULL){
00497            if(Op->last->in_ram){
00498              Nm=Op->last->npoints;
00499              if(Nm > 0){
00500                if((Vm=(point *)X__Malloc(Nm*sizeof(point))) != NULL){
00501                  for(i=0;i<Nm;i++){
00502                    CopyPoint(Op->last->points[i],xyz);
00503                    Vm[i][0] = xyz[0] - Op->last->origin[0];
00504                    Vm[i][1] = xyz[1] - Op->last->origin[1];
00505                    Vm[i][2] = xyz[2] - Op->last->origin[2];
00506                  }
00507                }
00508                else{
00509                  SendPrgmQuery(IDQ_NOMEM3,0);
00510                  Nm=0;
00511                }
00512              }
00513            }
00514          }
00515          else Nm=0;
00516          if(Op->in_ram){
00517            Nv=Op->npoints;
00518            if(Nv > 0){
00519              if((Vp=(Svertex *)X__Malloc(Nv*sizeof(Svertex))) != NULL){
00520                for(i=0;i<Nv;i++){
00521                  CopyPoint(Op->points[i],xyz);
00522                  m4by4(t3,sp[sid[i]].T,t4);
00523                  x1 = (double)(xyz[0]-Op->origin[0]);
00524                  y1 = (double)(xyz[1]-Op->origin[1]);
00525                  z1 = (double)(xyz[2]-Op->origin[2]);
00526                  if(Nv == Nm && Vm != NULL){ /* if object is morphing */
00527                    x1 = (x1 - (double)Vm[i][0])*mr + (double)Vm[i][0];
00528                    y1 = (y1 - (double)Vm[i][1])*mr + (double)Vm[i][1];
00529                    z1 = (z1 - (double)Vm[i][2])*mr + (double)Vm[i][2];
00530                  }
00531                  m4by1(t4,x1,y1,z1,&x2,&y2,&z2);
00532                  Vp[i][0]=(float)x2; Vp[i][1]=(float)y2; Vp[i][2]=(float)z2;
00533                }
00534              }
00535              else{
00536                SendPrgmQuery(IDQ_NOMEM3,0);
00537                Nv=0;
00538              }
00539            }
00540          }
00541          else Nv=0;
00542          Nl = Op->nedges;
00543          if(global_quickdraw){
00544            if(Nl < 100)qstep=1;
00545            else if(Nl <   1000)qstep=2;
00546            else if(Nl <   2500)qstep=3;
00547            else if(Nl <   5000)qstep=4;
00548            else if(Nl <  10000)qstep=6;
00549            else if(Nl <  20000)qstep=8;
00550            else if(Nl <  50000)qstep=12;
00551            else if(Nl < 100000)qstep=25;
00552            else qstep=40;
00553          }
00554          else qstep=1;
00555          if(Nl > 0 && Nv > 0 && Vp != NULL && sid != NULL)
00556          for(i=0;i<Nl;i+=qstep){
00557            id[0] = Op->edges[i][0];
00558            id[1] = Op->edges[i][1];
00559            flag=0;
00560            x1=Vp[id[0]][0];  x2=Vp[id[1]][0];
00561            y1=Vp[id[0]][1];  y2=Vp[id[1]][1];
00562            z1=Vp[id[0]][2];  z2=Vp[id[1]][2];
00563            if(y1 > dt){ /* point infront of viewing plane */
00564              ix1=(int)(pwincx+scalex*x1*dt/(y1));
00565              iy1=(int)(pwincy-scaley*z1*dt/(y1));
00566              if(ix1 < -16000 || ix1 > 16000)flag=1;
00567              if(iy1 < -16000 || iy1 > 16000)flag=1;
00568            }
00569            else  flag=1;
00570            if(y2 > dt){
00571              ix2=(int)(pwincx+scalex*x2*dt/(y2));
00572              iy2=(int)(pwincy-scaley*z2*dt/(y2));
00573              if(ix2 < -16000 || ix2 > 16000)flag=1;
00574              if(iy2 < -16000 || iy2 > 16000)flag=1;
00575            }
00576            else flag=1;
00577            if(flag == 0){
00578              MoveToEx(hdcView,ix1,iy1,NULL);
00579              LineTo(hdcView,ix2,iy2);
00580            }
00581            if(bAbortedDrawing){
00582              if(Vp != NULL){ X__Free(Vp); Vp=NULL;}
00583              if(Vm != NULL){ X__Free(Vm); Vm=NULL;}
00584              bAbortedDrawing=FALSE;
00585              goto XXIT;
00586            }
00587          }
00588          if(Vp != NULL){ X__Free(Vp); Vp=NULL;}
00589          if(Vm != NULL){ X__Free(Vm); Vm=NULL;}
00590        }
00591        break;
00592      }
00593      Op=Op->next;
00594    }
00595    Np=Np->next;
00596  }
00597  XXIT:
00598  return;
00599 }
00600 
00601 static void DrawQuickWire(HDC hdcView,
00602                           object *Op, double mr, double t1[4][4],
00603                           short pwincx, short pwincy){
00604  long i,j,flag,morphflag=0;
00605  double x1,y1,z1,x2,y2,z2;
00606  int ix1,iy1,ix2,iy2;
00607  point pl,pc;
00608  if(Op->w_frame.e != NULL && Op->w_frame.Np > 0){
00609    if(Op->morph != NO && Op->last != NULL && Op->last->w_frame.p != NULL &&
00610       Op->last->w_frame.e != NULL  && Op->last->w_frame.Np == Op->w_frame.Np)
00611       morphflag=1;
00612    for(i=0;i<Op->w_frame.Ne;i++){
00613      flag=0;
00614      if(morphflag){
00615        pl[0]=Op->last->w_frame.p[Op->last->w_frame.e[i][0]][0];
00616        pl[1]=Op->last->w_frame.p[Op->last->w_frame.e[i][0]][1];
00617        pl[2]=Op->last->w_frame.p[Op->last->w_frame.e[i][0]][2];
00618        SubPoints(pl,Op->last->origin,pl);
00619        AddPoints(pl,Op->origin,pl);
00620        pc[0]=Op->w_frame.p[Op->w_frame.e[i][0]][0];
00621        pc[1]=Op->w_frame.p[Op->w_frame.e[i][0]][1];
00622        pc[2]=Op->w_frame.p[Op->w_frame.e[i][0]][2];
00623        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00624                 (double)(pc[1]-pl[1])*mr+(double)pl[1],
00625                 (double)(pc[2]-pl[2])*mr+(double)pl[2],
00626           &x1,&y1,&z1);
00627        pl[0]=Op->last->w_frame.p[Op->last->w_frame.e[i][1]][0];
00628        pl[1]=Op->last->w_frame.p[Op->last->w_frame.e[i][1]][1];
00629        pl[2]=Op->last->w_frame.p[Op->last->w_frame.e[i][1]][2];
00630        pc[0]=Op->w_frame.p[Op->w_frame.e[i][1]][0];
00631        pc[1]=Op->w_frame.p[Op->w_frame.e[i][1]][1];
00632        pc[2]=Op->w_frame.p[Op->w_frame.e[i][1]][2];
00633        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00634                 (double)(pc[1]-pl[1])*mr+(double)pl[1],
00635                 (double)(pc[2]-pl[2])*mr+(double)pl[2],
00636           &x2,&y2,&z2);
00637      }
00638      else{
00639        m4by1(t1 ,(double)Op->w_frame.p[Op->w_frame.e[i][0]][0]
00640                 ,(double)Op->w_frame.p[Op->w_frame.e[i][0]][1]
00641                 ,(double)Op->w_frame.p[Op->w_frame.e[i][0]][2]
00642                 ,&x1,&y1,&z1);
00643        m4by1(t1 ,(double)Op->w_frame.p[Op->w_frame.e[i][1]][0]
00644                 ,(double)Op->w_frame.p[Op->w_frame.e[i][1]][1]
00645                 ,(double)Op->w_frame.p[Op->w_frame.e[i][1]][2]
00646                 ,&x2,&y2,&z2);
00647      }
00648      if(y1 > dt){ /* point infront of viewing plane */
00649        ix1=(int)(pwincx+scalex*x1*dt/(y1));
00650        iy1=(int)(pwincy-scaley*z1*dt/(y1));
00651        if(ix1 < -16000 || ix1 > 16000)flag=1;
00652        if(iy1 < -16000 || iy1 > 16000)flag=1;
00653      }
00654      else  flag=1;
00655      if(y2 > dt){
00656        ix2=(int)(pwincx+scalex*x2*dt/(y2));
00657        iy2=(int)(pwincy-scaley*z2*dt/(y2));
00658        if(ix2 < -16000 || ix2 > 16000)flag=1;
00659        if(iy2 < -16000 || iy2 > 16000)flag=1;
00660      }
00661      else flag=1;
00662      if(flag == 0){
00663         MoveToEx(hdcView,ix1,iy1,NULL);
00664         LineTo(hdcView,ix2,iy2);
00665      }
00666    }
00667  }
00668 }
00669 
00670 static void DrawNurbsPersp(HDC hdcView,
00671                           object *Op, double mr, double t1[4][4],
00672                           short pwincx, short pwincy){
00673  vector4 *p;
00674  nurbs *n;
00675  long k,ii,jj,flag,morphflag=0;
00676  double w,x1,y1,z1,x2,y2,z2;
00677  int ix1,iy1,ix2,iy2;
00678  point pl,pc;
00679  if(Op->nNurbs == 0 || Op->Nurbs == NULL)return;
00680  for(k=0;k<Op->nNurbs;k++){
00681    n=(Op->Nurbs+k);
00682    if(n->properties.hidden)continue;
00683    if(Op->morph != NO && Op->last != NULL && Op->last->Nurbs != NULL &&
00684       Op->nNurbs == Op->last->nNurbs)morphflag=1;
00685    // first pass
00686    for(ii=0;ii<n->numV;ii++)
00687    for(jj=0;jj<n->numU-1;jj++){
00688      flag=0;
00689      if(morphflag){
00690        p = &((Op->last->Nurbs+k)->points[ii][jj]);
00691        w=1.0/p->w; pl[0]=((p->x)*w); pl[1]=((p->y)*w); pl[2]=((p->z)*w);
00692        SubPoints(pl,Op->last->origin,pl);
00693        AddPoints(pl,Op->origin,pl);
00694        p = &(n->points[ii][jj]);
00695        w=1.0/p->w; pc[0]=((p->x)*w); pc[1]=((p->y)*w); pc[2]=((p->z)*w);
00696        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00697                 (double)(pc[0]-pl[1])*mr+(double)pl[1],
00698                 (double)(pc[0]-pl[1])*mr+(double)pl[2],
00699           &x1,&y1,&z1);
00700        p = &((Op->last->Nurbs+k)->points[ii][jj+1]);
00701        w=1.0/p->w; pl[0]=((p->x)*w); pl[1]=((p->y)*w); pl[2]=((p->z)*w);
00702        p = &(n->points[ii][jj+1]);
00703        w=1.0/p->w; pc[0]=((p->x)*w); pc[1]=((p->y)*w); pc[2]=((p->z)*w);
00704        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00705                 (double)(pc[0]-pl[1])*mr+(double)pl[1],
00706                 (double)(pc[0]-pl[1])*mr+(double)pl[2],
00707           &x2,&y2,&z2);
00708      }
00709      else{
00710        p = &(n->points[ii][jj]);
00711        w=1.0/p->w; x1=((p->x)*w); y1=((p->y)*w); z1=((p->z)*w);
00712        p = &(n->points[ii][jj+1]);
00713        w=1.0/p->w; x2=((p->x)*w); y2=((p->y)*w); z2=((p->z)*w);
00714        m4by1(t1 ,x1,y1,z1
00715                 ,&x1,&y1,&z1);
00716        m4by1(t1 ,x2,y2,z2
00717                 ,&x2,&y2,&z2);
00718      }
00719      if(y1 > dt){ /* point infront of viewing plane */
00720        ix1=(int)(pwincx+scalex*x1*dt/(y1));
00721        iy1=(int)(pwincy-scaley*z1*dt/(y1));
00722        if(ix1 < -16000 || ix1 > 16000)flag=1;
00723        if(iy1 < -16000 || iy1 > 16000)flag=1;
00724      }
00725      else  flag=1;
00726      if(y2 > dt){
00727        ix2=(int)(pwincx+scalex*x2*dt/(y2));
00728        iy2=(int)(pwincy-scaley*z2*dt/(y2));
00729        if(ix2 < -16000 || ix2 > 16000)flag=1;
00730        if(iy2 < -16000 || iy2 > 16000)flag=1;
00731      }
00732      else flag=1;
00733      if(flag == 0){
00734         MoveToEx(hdcView,ix1,iy1,NULL);
00735         LineTo(hdcView,ix2,iy2);
00736      }
00737    }
00738    // second pass
00739    for(jj=0;jj<n->numU;jj++)
00740    for(ii=0;ii<n->numV-1;ii++){
00741      flag=0;
00742      if(morphflag){
00743        p = &((Op->last->Nurbs+k)->points[ii][jj]);
00744        w=1.0/p->w; pl[0]=((p->x)*w); pl[1]=((p->y)*w); pl[2]=((p->z)*w);
00745        SubPoints(pl,Op->last->origin,pl);
00746        AddPoints(pl,Op->origin,pl);
00747        p = &(n->points[ii][jj]);
00748        w=1.0/p->w; pc[0]=((p->x)*w); pc[1]=((p->y)*w); pc[2]=((p->z)*w);
00749        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00750                 (double)(pc[0]-pl[1])*mr+(double)pl[1],
00751                 (double)(pc[0]-pl[1])*mr+(double)pl[2],
00752           &x1,&y1,&z1);
00753        p = &((Op->last->Nurbs+k)->points[ii+1][jj]);
00754        w=1.0/p->w; pl[0]=((p->x)*w); pl[1]=((p->y)*w); pl[2]=((p->z)*w);
00755        p = &(n->points[ii+1][jj]);
00756        w=1.0/p->w; pc[0]=((p->x)*w); pc[1]=((p->y)*w); pc[2]=((p->z)*w);
00757        m4by1(t1,(double)(pc[0]-pl[0])*mr+(double)pl[0],
00758                 (double)(pc[0]-pl[1])*mr+(double)pl[1],
00759                 (double)(pc[0]-pl[1])*mr+(double)pl[2],
00760           &x2,&y2,&z2);
00761      }
00762      else{
00763        p = &(n->points[ii][jj]);
00764        w=1.0/p->w; x1=((p->x)*w); y1=((p->y)*w); z1=((p->z)*w);
00765        p = &(n->points[ii+1][jj]);
00766        w=1.0/p->w; x2=((p->x)*w); y2=((p->y)*w); z2=((p->z)*w);
00767        m4by1(t1 ,x1,y1,z1
00768                 ,&x1,&y1,&z1);
00769        m4by1(t1 ,x2,y2,z2
00770                 ,&x2,&y2,&z2);
00771      }
00772      if(y1 > dt){ /* point infront of viewing plane */
00773        ix1=(int)(pwincx+scalex*x1*dt/(y1));
00774        iy1=(int)(pwincy-scaley*z1*dt/(y1));
00775        if(ix1 < -16000 || ix1 > 16000)flag=1;
00776        if(iy1 < -16000 || iy1 > 16000)flag=1;
00777      }
00778      else  flag=1;
00779      if(y2 > dt){
00780        ix2=(int)(pwincx+scalex*x2*dt/(y2));
00781        iy2=(int)(pwincy-scaley*z2*dt/(y2));
00782        if(ix2 < -16000 || ix2 > 16000)flag=1;
00783        if(iy2 < -16000 || iy2 > 16000)flag=1;
00784      }
00785      else flag=1;
00786      if(flag == 0){
00787         MoveToEx(hdcView,ix1,iy1,NULL);
00788         LineTo(hdcView,ix2,iy2);
00789      }
00790    }
00791    // end of passes
00792  }
00793 }
00794 
00795 void PerspectiveView0(int smab, int DisplayType){
00796  RECT rc;
00797  if(ghwndOpenGLview != NULL){
00798    UpdateGLview(FALSE);
00799    return;
00800  }
00801  if(ghdc_view_Bitmap == NULL || ghwnd_view == NULL)return;
00802  UpdateFrameBox();
00803  GetClientRect(ghwnd_view,&rc);
00804  PatBlt(ghdc_view_Bitmap,0,0,rc.right,rc.bottom,PATCOPY);
00805  DrawPerspectiveView(smab,DisplayType,
00806                      ghdc_view_Bitmap,ghwnd_view,ghWireframePen);
00807  InvalidateRect(ghwnd_view,NULL,FALSE);
00808 }
00809 
00810 static BOOL bRendering=FALSE;
00811 
00812 static void PerspectiveView1(void *xxx){
00813 //static DWORD WINAPI PerspectiveView1(LPVOID xxx){
00814  int smab=0,DisplayType;
00815  RECT rc;
00816  bRendering=TRUE;
00817  DisplayType=(int)xxx;
00818  GetClientRect(ghwnd_view,&rc);
00819  PatBlt(ghdc_view_Bitmap,0,0,rc.right,rc.bottom,PATCOPY);
00820  DrawPerspectiveView(smab,DisplayType,
00821                      ghdc_view_Bitmap,ghwnd_view,ghWireframePen);
00822  InvalidateRect(ghwnd_view,NULL,FALSE);
00823  bRendering=FALSE;
00824  _endthread();
00825 // ExitThread(0);
00826  return;
00827 }
00828 
00829 void PerspectiveView(int smab, int DisplayType){
00830  void (*fp)(void *);
00831 // DWORD WINAPI (*fp)(LPVOID);
00832 // DWORD threadID;
00833  if(ghwndOpenGLview != NULL){
00834    UpdateGLview(FALSE);
00835    return;
00836  }
00837  if(ghdc_view_Bitmap == NULL || ghwnd_view == NULL)return;
00838  if(DisplayType == 0){
00839    if(bRendering){
00840      bAbortedDrawing=TRUE;
00841      Sleep(10);
00842      if(bAbortedDrawing)return;
00843    }
00844    PerspectiveView0(smab,DisplayType);
00845    return;
00846  }
00847  UpdateFrameBox();
00848  if(bRendering){
00849    bAbortedDrawing=TRUE;
00850    Sleep(10);
00851    if(bAbortedDrawing)return;
00852  }
00853  fp=PerspectiveView1;
00854 #if  __WATCOMC__ && __WATCOMC__ < 1100
00855   _beginthread(fp,0,65536,(void *)DisplayType);
00856 #else
00857   _beginthread(fp,0,(void *)DisplayType);
00858 #endif
00859 // CreateThread(NULL,0,fp,(LPVOID)DisplayType,0,&threadID);
00860 }
00861 
00862 void DrawPerspectiveView(int smab, int DisplayType,
00863                          HDC hDC, HWND hWnd, HPEN hPen){
00864  node *selected_camera;
00865  RECT rc;
00866  double xc,yc,zc,alpha,theta,phi,t1[4][4],t2[4][4],t3[4][4],sx,sy,sz,ima;
00867  short im;
00868  point camera,TrackedOffset;
00869  double lenz=50.0;
00870  dt=1.0;
00871  GetClientRect(hWnd,&rc);
00872  scalex=scaley=(rc.right)/2/21.22*lenz;
00873  selected_camera=GetSelectedCamera(CurrentFrame,SelectedCamera);
00874  if(selected_camera == NULL)selected_camera=FirstNp;
00875  if(selected_camera->type != CAMERA)return;
00876  GetTransform(0,CurrentFrame,1.0,
00877               selected_camera,selected_camera->fobj,camera,TrackedOffset,
00878               &phi,&theta,&alpha,&sx,&sy,&sz,&im,&ima);
00879  /* IM is ignored no internal for camera */
00880  scalex *= sx;
00881  scaley *= sy;
00882  xc=(double)camera[0];
00883  yc=(double)camera[1];
00884  zc=(double)camera[2];
00885  theta *= PIo180;
00886  phi   *= PIo180;
00887  alpha *= PIo180;
00888  CameraAlpha=alpha;
00889  CameraTheta=theta;
00890  CameraHeight=zc;
00891  tram(t1,-xc,-yc,-zc);
00892  rotz(t2,-phi);
00893  m4by4(t2,t1,t3);
00894  rotx(t1,-alpha);
00895  m4by4(t1,t3,t2);
00896  roty(t3,-theta);   /* camera banking */
00897  m4by4(t3,t2,trr);
00898  SelectObject(hDC,hPen);
00899  DrawStagePerspective(hDC,hWnd,DisplayType,camera,TRUE);
00900  return;
00901 }
00902 
00903 // preview code
00904 
00905 static void    DrawPreviewFrame(HWND hwnd, HDC hdc, HBITMAP hbm);
00906 static PSTR    lpszAnimatorPreviewClass="OFX:PreviewClass";
00907 static HBITMAP *PreviewBitmaps=NULL;
00908 static int     nPreviewFrames=0,iPlayFrame,StartPreviewFrame,EndPreviewFrame;
00909 static HWND    hwndPreview=NULL;
00910 static UINT    PreviewTimer=0;
00911 static int     preview_quickdraw=0;
00912 static int     preview_speed=30;
00913 static RECT    mRect;
00914 static HBITMAP PreviewButtonBitmaps[6]={NULL,NULL,NULL,NULL,NULL,NULL};
00915 static int     PreviewButtonIDs[6]={
00916                 IDBM_PREV_FIRST,IDBM_PREV_PREV,IDBM_PREV_PLAY,
00917                 IDBM_PREV_NEXT,IDBM_PREV_LAST,IDBM_PREV_PAUSE};
00918 
00919 #define IDM_PREVIEW_FREE 0x10
00920 
00921 static void DrawPreviewFrame(HWND hwnd, HDC hdc, HBITMAP hbm){
00922  node *selected_camera;
00923  RECT rc;
00924  double xc,yc,zc,alpha,theta,phi,t1[4][4],t2[4][4],t3[4][4],sx,sy,sz,ima;
00925  short im;
00926  point camera,TrackedOffset;
00927  double lenz=50.0;
00928  if(hdc == NULL || hbm == NULL)return;
00929  dt=1.0;
00930  GetClientRect(hwnd,&rc);
00931  PatBlt(hdc,0,0,rc.right,rc.bottom,PATCOPY);
00932  scalex=scaley=(rc.right)/2/21.22*lenz;
00933  selected_camera=GetSelectedCamera(CurrentFrame,SelectedCamera);
00934  if(selected_camera == NULL)selected_camera=FirstNp;
00935  if(selected_camera->type != CAMERA)return;
00936  GetTransform(0,CurrentFrame,1.0,
00937               selected_camera,selected_camera->fobj,camera,TrackedOffset,
00938               &phi,&theta,&alpha,&sx,&sy,&sz,&im,&ima);
00939 /* IM is ignored no internal for camera */
00940  scalex *= sx;
00941  scaley *= sy;
00942  xc=(double)camera[0];
00943  yc=(double)camera[1];
00944  zc=(double)camera[2];
00945  theta *= PIo180;
00946  phi   *= PIo180;
00947  alpha *= PIo180;
00948  CameraAlpha=alpha;
00949  CameraTheta=theta;
00950  CameraHeight=zc;
00951  tram(t1,-xc,-yc,-zc);
00952  rotz(t2,-phi);
00953  m4by4(t2,t1,t3);
00954  rotx(t1,-alpha);
00955  m4by4(t1,t3,t2);
00956  roty(t3,-theta);   /* camera banking */
00957  m4by4(t3,t2,trr);
00958  SelectObject(hdc,GetStockObject(BLACK_PEN));
00959  DrawStagePerspective(hdc,hwnd,1,camera,FALSE);
00960  if(GetQueueStatus(QS_ALLINPUT)){
00961    MSG msg;
00962    while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)){
00963      TranslateMessage(&msg);
00964      DispatchMessage(&msg);
00965    }
00966  }
00967  return;
00968 }
00969 
00970 void FreePreview(void){
00971  int i;
00972  if(nPreviewFrames == 0 || PreviewBitmaps == NULL)return;
00973  for(i=0;i<nPreviewFrames;i++){
00974    if(PreviewBitmaps[i] != NULL)DeleteObject(PreviewBitmaps[i]);
00975  }
00976  X__Free(PreviewBitmaps);
00977  PreviewBitmaps=NULL;
00978  nPreviewFrames=0;
00979 }
00980 
00981 void MoveCtrlWindow(HWND hdlg,int id,
00982                    int tx, int ty, int cx, int cy,
00983                    int type){
00984  POINT pp;
00985  RECT wRect;
00986  GetWindowRect(GetDlgItem(hdlg,id),&wRect);
00987  pp.x=wRect.left; pp.y=wRect.top;
00988  ScreenToClient(hdlg,&pp);
00989  wRect.left=pp.x; wRect.top=pp.y;
00990  pp.x=wRect.right; pp.y=wRect.bottom;
00991  ScreenToClient(hdlg,&pp);
00992  wRect.right=pp.x; wRect.bottom=pp.y;
00993  if(type == 0){
00994    wRect.right  += (tx - cx);
00995    wRect.bottom += (ty - cy);
00996  }
00997  else{
00998    if(type == 1)OffsetRect(&wRect,(tx - cx),0);
00999    else         OffsetRect(&wRect,0,(ty - cy));
01000  }
01001  MoveWindow(GetDlgItem(hdlg,id),wRect.left,wRect.top,
01002             wRect.right-wRect.left,wRect.bottom-wRect.top,TRUE);
01003 }
01004 
01005 static BOOL CALLBACK PreviewDlgProc(HWND hdlg, UINT msg,
01006                                     WPARAM wparam, LPARAM lparam){
01007  static BOOL bMakingPreview=FALSE;
01008  static HWND hWndStatus;
01009  static int cx,cy,ox,oy;
01010  HWND hctl;
01011  int i,tx,ty;
01012  char str[32];
01013  RECT wRect;
01014  LPRECT lpRect;
01015  switch( msg ) {
01016    case WM_INITDIALOG:
01017      SetClassLong(hdlg,GCL_HICON,
01018                  (LONG)LoadIcon(ghinst_main,"ANIMATORICON"));
01019      hWndStatus=CreateWindowEx(0L,STATUSCLASSNAME,"",
01020                 WS_CHILD | !WS_BORDER | WS_VISIBLE,
01021                 0,0,0,0,
01022                 hdlg,
01023                 (HMENU)NULL,
01024                 (HINSTANCE)NULL,
01025                 NULL);
01026      SendMessage(hWndStatus,SB_SETTEXT,(WPARAM)SBT_NOBORDERS,(LPARAM)NULL);
01027      if(preview_quickdraw == 1)
01028        SendDlgItemMessage(hdlg,DLG_PREVIEW_QUICK,BM_SETCHECK,TRUE,0);
01029      else
01030        SendDlgItemMessage(hdlg,DLG_PREVIEW_FULL,BM_SETCHECK,TRUE,0);
01031      if(preview_speed == 30)
01032        SendDlgItemMessage(hdlg,DLG_PREVIEW_30,BM_SETCHECK,TRUE,0);
01033      else if(preview_speed == 25)
01034        SendDlgItemMessage(hdlg,DLG_PREVIEW_25,BM_SETCHECK,TRUE,0);
01035      else if(preview_speed == 15)
01036        SendDlgItemMessage(hdlg,DLG_PREVIEW_15,BM_SETCHECK,TRUE,0);
01037      else if(preview_speed == 5)
01038        SendDlgItemMessage(hdlg,DLG_PREVIEW_5,BM_SETCHECK,TRUE,0);
01039      else if(preview_speed == 1)
01040        SendDlgItemMessage(hdlg,DLG_PREVIEW_1,BM_SETCHECK,TRUE,0);
01041      for(i=0;i<6;i++){
01042        PreviewButtonBitmaps[i]=LoadBitmap(ghinst_main,
01043          MAKEINTRESOURCE(PreviewButtonIDs[i]));
01044      }
01045      if(LOBYTE(LOWORD(GetVersion())) < 4){;}
01046      else{
01047        SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),BM_SETIMAGE,
01048                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[0]);
01049        SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),BM_SETIMAGE,
01050                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[1]);
01051        SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),BM_SETIMAGE,
01052                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[2]);
01053        SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),BM_SETIMAGE,
01054                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[3]);
01055        SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_LAST),BM_SETIMAGE,
01056                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[4]);
01057      }
01058      SetDlgItemInt(hdlg,DLG_PREVIEW_RANGE1,1,FALSE);
01059      SetDlgItemInt(hdlg,DLG_PREVIEW_RANGEN,Nframes,FALSE);
01060 //     CentreDialogOnScreen(hdlg);
01061      GetWindowRect(hdlg,&wRect);
01062      ox=wRect.right-wRect.left;
01063      oy=wRect.bottom-wRect.top;
01064      GetClientRect(hdlg,&wRect);
01065      cx=wRect.right;
01066      cy=wRect.bottom;
01067      PostMessage(hdlg,(WM_USER+100),0,0);
01068      return (TRUE);
01069    case (WM_USER+100):{
01070        int xp,yp,xl,yl;
01071        xp=GetPrivateProfileInt(IniSection,"PRPOSX",-1,IniFilename);
01072        yp=GetPrivateProfileInt(IniSection,"PRPOSY",-1,IniFilename);
01073        xl=GetPrivateProfileInt(IniSection,"PRSIZX",-1,IniFilename);
01074        yl=GetPrivateProfileInt(IniSection,"PRSIZY",-1,IniFilename);
01075        if(xp < 0 || yp < 0 || xl < 0 || yl < 0)CentreDialogOnScreen(hdlg);
01076        else     SetWindowPos(hdlg,NULL,xp,yp,xl,yl,SWP_NOZORDER);
01077        ShowWindow(hdlg,SW_SHOW);
01078      }
01079      break;
01080    case WM_DESTROY:{
01081        RECT rc; char str[32];
01082        for(i=0;i<6;i++)if(PreviewButtonBitmaps[i] != NULL)
01083          DeleteObject(PreviewButtonBitmaps[i]);
01084        GetWindowRect(hdlg,&rc);
01085        sprintf(str,"%ld",rc.left);
01086        WritePrivateProfileString(IniSection,"PRPOSX",str,IniFilename);
01087        sprintf(str,"%ld",rc.top);
01088        WritePrivateProfileString(IniSection,"PRPOSY",str,IniFilename);
01089        sprintf(str,"%ld",rc.right-rc.left);
01090        WritePrivateProfileString(IniSection,"PRSIZX",str,IniFilename);
01091        sprintf(str,"%ld",rc.bottom-rc.top);
01092        WritePrivateProfileString(IniSection,"PRSIZY",str,IniFilename);
01093      }
01094      break;
01095    case WM_HSCROLL:
01096      if((HWND)lparam == (hctl=GetDlgItem(hdlg,DLG_PREVIEW_SCROLL))){
01097        i=iPlayFrame;
01098        switch (LOWORD(wparam)) {
01099          case TB_TOP:           i=0; break;
01100          case TB_BOTTOM:        i=nPreviewFrames-1; break;
01101          case TB_PAGEDOWN:      break;
01102          case TB_LINEDOWN:      i++; break;
01103          case TB_PAGEUP:        break;
01104          case TB_LINEUP:        i--; break;
01105          case TB_THUMBTRACK:
01106          case TB_THUMBPOSITION: i=HIWORD(wparam);break;
01107          default: break;
01108        }
01109        i=min(nPreviewFrames-1,max(i,0));
01110        if(i != iPlayFrame){
01111          iPlayFrame=i;
01112          InvalidateRect(hwndPreview,NULL,FALSE);
01113        }
01114      }
01115      break;
01116    case WM_SIZING:
01117      lpRect=(LPRECT)lparam;
01118      if((lpRect->right - lpRect->left) < ox)
01119        lpRect->right = lpRect->left+ox;
01120      if((lpRect->bottom - lpRect->top) < oy)
01121        lpRect->bottom = lpRect->top+oy;
01122      return TRUE;
01123      break;
01124    case WM_SIZE:
01125      SendMessage(hWndStatus,WM_SIZE,wparam,lparam);
01126      tx=LOWORD(lparam); ty=HIWORD(lparam);
01127      MoveCtrlWindow(hdlg,DLG_PREVIEW_WIN,tx,ty,cx,cy,0);
01128      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX1,tx,ty,cx,cy,0);
01129      MoveCtrlWindow(hdlg,IDCANCEL,tx,ty,cx,cy,1);
01130      MoveCtrlWindow(hdlg,DLG_PREVIEW_MAKE,tx,ty,cx,cy,1);
01131      MoveCtrlWindow(hdlg,DLG_PREVIEW_PROGRESS,tx,ty,cx,cy,1);
01132      MoveCtrlWindow(hdlg,DLG_PREVIEW_RANGE1,tx,ty,cx,cy,1);
01133      MoveCtrlWindow(hdlg,DLG_PREVIEW_RANGEN,tx,ty,cx,cy,1);
01134      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX2,tx,ty,cx,cy,1);
01135      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX3,tx,ty,cx,cy,1);
01136      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX4,tx,ty,cx,cy,1);
01137      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX5,tx,ty,cx,cy,1);
01138      MoveCtrlWindow(hdlg,DLG_PREVIEW_TX6,tx,ty,cx,cy,1);
01139      MoveCtrlWindow(hdlg,DLG_PREVIEW_QUICK,tx,ty,cx,cy,1);
01140      MoveCtrlWindow(hdlg,DLG_PREVIEW_FULL,tx,ty,cx,cy,1);
01141      MoveCtrlWindow(hdlg,DLG_PREVIEW_1,tx,ty,cx,cy,1);
01142      MoveCtrlWindow(hdlg,DLG_PREVIEW_5,tx,ty,cx,cy,1);
01143      MoveCtrlWindow(hdlg,DLG_PREVIEW_15,tx,ty,cx,cy,1);
01144      MoveCtrlWindow(hdlg,DLG_PREVIEW_25,tx,ty,cx,cy,1);
01145      MoveCtrlWindow(hdlg,DLG_PREVIEW_30,tx,ty,cx,cy,1);
01146      MoveCtrlWindow(hdlg,DLG_PREVIEW_FIRST,tx,ty,cx,cy,2);
01147      MoveCtrlWindow(hdlg,DLG_PREVIEW_PREVIOUS,tx,ty,cx,cy,2);
01148      MoveCtrlWindow(hdlg,DLG_PREVIEW_PLAY,tx,ty,cx,cy,2);
01149      MoveCtrlWindow(hdlg,DLG_PREVIEW_NEXT,tx,ty,cx,cy,2);
01150      MoveCtrlWindow(hdlg,DLG_PREVIEW_LAST,tx,ty,cx,cy,2);
01151      MoveCtrlWindow(hdlg,DLG_PREVIEW_SCROLL,tx,ty,cx,cy,2);
01152      InvalidateRect(hdlg,NULL,TRUE);
01153      cx=tx; cy=ty;
01154      break;
01155    case WM_PAINT:
01156      PaintDialogBackground(hdlg,ghinst_main);
01157      break;
01158    case WM_COMMAND:
01159      switch(LOWORD(wparam)){
01160        case DLG_PREVIEW_FULL:  preview_quickdraw=0; break;
01161        case DLG_PREVIEW_QUICK: preview_quickdraw=1; break;
01162        case DLG_PREVIEW_30:    preview_speed=30;    break;
01163        case DLG_PREVIEW_25:    preview_speed=25;    break;
01164        case DLG_PREVIEW_15:    preview_speed=15;    break;
01165        case DLG_PREVIEW_5:     preview_speed=5;     break;
01166        case DLG_PREVIEW_1:     preview_speed=1;     break;
01167        case DLG_PREVIEW_FIRST:
01168          iPlayFrame=0;
01169          SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01170                             TRUE,iPlayFrame);
01171          InvalidateRect(hwndPreview,NULL,FALSE);
01172          break;
01173        case DLG_PREVIEW_PREVIOUS:
01174          iPlayFrame -= 1;
01175          iPlayFrame = max(0,iPlayFrame);
01176          SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01177                             TRUE,iPlayFrame);
01178          InvalidateRect(hwndPreview,NULL,FALSE);
01179          break;
01180        case DLG_PREVIEW_NEXT:
01181          iPlayFrame += 1;
01182          iPlayFrame = min(nPreviewFrames-1,iPlayFrame);
01183          SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01184                             TRUE,iPlayFrame);
01185          InvalidateRect(hwndPreview,NULL,FALSE);
01186          break;
01187        case DLG_PREVIEW_LAST:
01188          iPlayFrame=nPreviewFrames-1;
01189          SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01190                             TRUE,iPlayFrame);
01191          InvalidateRect(hwndPreview,NULL,FALSE);
01192          break;
01193        case DLG_PREVIEW_PLAY:
01194          if(preview_playing){
01195            preview_playing=0;
01196            KillTimer(hwndPreview,PreviewTimer); PreviewTimer=0;
01197            SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01198                               TRUE,iPlayFrame);
01199            LoadString(ghinst_main,IDX_MISC_PLAY,str,32);
01200            SendDlgItemMessage(hdlg,DLG_PREVIEW_PLAY,WM_SETTEXT,
01201                               0,(LPARAM)str);
01202            SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),BM_SETIMAGE,
01203                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[2]);
01204            EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_MAKE),TRUE);
01205            EnableWindow(GetDlgItem(hdlg,IDCANCEL),TRUE);
01206            EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),TRUE);
01207            EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_LAST),TRUE);
01208            EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),TRUE);
01209            EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),TRUE);
01210          }
01211          else{
01212            if(preview_speed == 1)i=1000;
01213            if(preview_speed == 5)i=200;
01214            if(preview_speed == 15)i=66;
01215            if(preview_speed == 25)i=40;
01216            if(preview_speed == 30)i=33;
01217            if((PreviewTimer=SetTimer(hwndPreview,1,i,NULL)) != 0){
01218              preview_playing=1;
01219              LoadString(ghinst_main,IDX_MISC_STOP,str,32);
01220              SendDlgItemMessage(hdlg,DLG_PREVIEW_PLAY,WM_SETTEXT,
01221                                 0,(LPARAM)str);
01222              SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),BM_SETIMAGE,
01223                  (WPARAM)0,(LPARAM)PreviewButtonBitmaps[5]);
01224              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_MAKE),FALSE);
01225              EnableWindow(GetDlgItem(hdlg,IDCANCEL),FALSE);
01226              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),FALSE);
01227              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_LAST),FALSE);
01228              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),FALSE);
01229              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),FALSE);
01230            }
01231          }
01232          break;
01233        case DLG_PREVIEW_MAKE:
01234          if(bMakingPreview){
01235            FreePreview();
01236            break;
01237          }
01238          if(preview_playing)break;
01239          if(PreviewBitmaps != NULL)FreePreview();
01240          if(hwndPreview != NULL){
01241            HDC     hdc,hdcMem;
01242            RECT    rc;
01243            HBITMAP hbm,hbmold=NULL;
01244            char    str[32];
01245            long    i,cf_store,qd_store;
01246            BOOL    err;
01247            if((PreviewBitmaps=(HBITMAP *)X__Malloc(sizeof(HBITMAP)*Nframes))
01248               != NULL){
01249              StartPreviewFrame=GetDlgItemInt(hdlg,DLG_PREVIEW_RANGE1,&err,FALSE);
01250              EndPreviewFrame=GetDlgItemInt(hdlg,DLG_PREVIEW_RANGEN,&err,FALSE);
01251              StartPreviewFrame=max(1,StartPreviewFrame);
01252              StartPreviewFrame=min(Nframes,StartPreviewFrame);
01253              EndPreviewFrame=max(1,EndPreviewFrame);
01254              EndPreviewFrame=min(Nframes,EndPreviewFrame);
01255              EndPreviewFrame=max(StartPreviewFrame,EndPreviewFrame);
01256              nPreviewFrames=EndPreviewFrame-StartPreviewFrame+1;
01257 //             nPreviewFrames=Nframes;  //
01258              bMakingPreview=TRUE;
01259              SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETRANGE,
01260                                 (WPARAM)TRUE,
01261                                 (LPARAM)MAKELONG(0,nPreviewFrames-1));
01262              SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETLINESIZE,0,1);
01263              SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPAGESIZE,0,0);
01264              SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETTIC,0,
01265                                 (LPARAM)(nPreviewFrames/2));
01266              cf_store=CurrentFrame;
01267              qd_store=global_quickdraw;
01268              ActivateAllMenus(ghwnd_main,MF_GRAYED);
01269              EnableToolPannels(ALL_PANNELS,FALSE);
01270              LoadString(ghinst_main,IDX_MISC_CANCELPREVIEW,res_str,256);
01271              SetDlgItemText(hdlg,DLG_PREVIEW_MAKE,res_str);
01272              EnableWindow(GetDlgItem(hdlg,IDCANCEL),FALSE);
01273              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),FALSE);
01274              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),FALSE);
01275              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_LAST),FALSE);
01276              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),FALSE);
01277              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),FALSE);
01278              for(i=0;i<nPreviewFrames;i++)PreviewBitmaps[i]=NULL;
01279              SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PROGRESS),PBM_SETRANGE,0,MAKELPARAM(0,nPreviewFrames));
01280              SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PROGRESS),PBM_SETSTEP,(WPARAM)1,0);
01281              SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PROGRESS),PBM_SETPOS,(WPARAM)0,0);
01282              hdc=GetDC(hwndPreview);
01283              GetClientRect(hwndPreview,&rc);
01284              CopyRect(&mRect,&rc);
01285              global_quickdraw=preview_quickdraw;
01286              for(i=0;i<nPreviewFrames;i++){
01287                CurrentFrame=StartPreviewFrame+i;
01288 //               CurrentFrame=i+1;
01289                LoadString(ghinst_main,IDX_MISC_PREPARINGFRAME,res_str,256);
01290                sprintf(str,res_str,
01291                        CurrentFrame,Nframes);
01292                SendPrgmText(str);
01293                if((hbm=CreateBitmap(rc.right,rc.bottom,1,1,NULL)) == NULL){
01294                  ReleaseDC(hwndPreview,hdc);
01295                  CurrentFrame=cf_store;
01296                  global_quickdraw=qd_store;
01297                  ActivateAllMenus(ghwnd_main,MF_ENABLED);
01298                  EnableToolPannels(ALL_PANNELS,TRUE);
01299                  LoadString(ghinst_main,IDX_MISC_MAKEPREVIEW,res_str,256);
01300                  SetDlgItemText(hdlg,DLG_PREVIEW_MAKE,res_str);
01301                  EnableWindow(GetDlgItem(hdlg,IDCANCEL),TRUE);
01302                  EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),TRUE);
01303                  EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),TRUE);
01304                  EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_LAST),TRUE);
01305                  EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),TRUE);
01306                  EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),TRUE);
01307                  FreePreview();
01308                  bMakingPreview=FALSE;
01309                  return FALSE;
01310                }
01311                PreviewBitmaps[i]=hbm;
01312                hdcMem=CreateCompatibleDC(hdc);
01313                hbmold=SelectObject(hdcMem,hbm);
01314                DrawPreviewFrame(hwndPreview,hdcMem,hbm);
01315                sprintf(str,"%4.4ld",CurrentFrame);
01316                TextOut(hdcMem,1,1,str,strlen(str));
01317                BitBlt(hdc,0,0,rc.right,rc.bottom,hdcMem,0,0,SRCCOPY);
01318                SelectObject(hdcMem,hbmold);
01319                DeleteDC(hdcMem);
01320                SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PROGRESS),PBM_SETPOS,
01321                           (WPARAM)i,0);
01322              }
01323              ReleaseDC(hwndPreview,hdc);
01324              SendMessage(GetDlgItem(hdlg,DLG_PREVIEW_PROGRESS),PBM_SETPOS,
01325                          (WPARAM)nPreviewFrames,0);
01326              CurrentFrame=cf_store;
01327              global_quickdraw=qd_store;
01328              ActivateAllMenus(ghwnd_main,MF_ENABLED);
01329              EnableToolPannels(ALL_PANNELS,TRUE);
01330              LoadString(ghinst_main,IDX_MISC_PREVIEWCOMPLETE,res_str,256);
01331              SendPrgmText(res_str);
01332              iPlayFrame=0;
01333              InvalidateRect(hwndPreview,NULL,FALSE);
01334              UpdateWindow(hwndPreview);
01335              LoadString(ghinst_main,IDX_MISC_MAKEPREVIEW,res_str,256);
01336              SetDlgItemText(hdlg,DLG_PREVIEW_MAKE,res_str);
01337              EnableWindow(GetDlgItem(hdlg,IDCANCEL),TRUE);
01338              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PLAY),TRUE);
01339              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_FIRST),TRUE);
01340              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_LAST),TRUE);
01341              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_PREVIOUS),TRUE);
01342              EnableWindow(GetDlgItem(hdlg,DLG_PREVIEW_NEXT),TRUE);
01343              SendDlgItemMessage(hdlg,DLG_PREVIEW_SCROLL,TBM_SETPOS,
01344                                 TRUE,iPlayFrame);
01345              bMakingPreview=FALSE;
01346            }
01347          }
01348          break;
01349        case IDCANCEL:
01350          EndDialog(hdlg,TRUE);
01351          return(TRUE);
01352        default:
01353          break;
01354      }
01355      break;
01356    default: break;
01357  }
01358  return(FALSE);
01359 }
01360 
01361 static LRESULT CALLBACK PreviewWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,
01362                                                            LPARAM lParam){
01363  HDC hDC;
01364  RECT rc;
01365  PAINTSTRUCT ps;
01366  switch (uMsg) {
01367    case WM_CREATE:
01368      hwndPreview=hWnd;
01369      break;
01370    case WM_TIMER:
01371      switch(wParam){
01372        case 1:
01373          iPlayFrame++;
01374          if(iPlayFrame >= nPreviewFrames)iPlayFrame=0;
01375          SendDlgItemMessage(GetParent(hWnd),DLG_PREVIEW_SCROLL,
01376                             TBM_SETPOS,TRUE,iPlayFrame);
01377          InvalidateRect(hWnd,NULL,FALSE);
01378      }
01379      break;
01380    case WM_PAINT:
01381      hDC=BeginPaint(hWnd,&ps);
01382      if(PreviewBitmaps != NULL && PreviewBitmaps[iPlayFrame] != NULL){
01383        HDC hdcMem;
01384        PAINTSTRUCT ps;
01385        RECT rc;
01386        HBITMAP hbmold;
01387        hdcMem=CreateCompatibleDC(hDC);
01388        hbmold=SelectObject(hdcMem,PreviewBitmaps[iPlayFrame]);
01389        GetClientRect(hWnd,&rc);
01390        if(rc.right == mRect.right && rc.bottom == mRect.bottom)
01391          BitBlt(hDC,0,0,rc.right,rc.bottom,hdcMem,0,0,SRCCOPY);
01392        else
01393          StretchBlt(hDC,   0,0,rc.right,rc.bottom,
01394                     hdcMem,0,0,mRect.right,mRect.bottom,SRCCOPY);
01395        SelectObject(hdcMem,hbmold);
01396        DeleteDC(hdcMem);
01397      }
01398      EndPaint(hWnd,&ps);
01399      break;
01400    default:
01401      return(DefWindowProc(hWnd,uMsg,wParam,lParam));
01402  }
01403  return( 0L );
01404 }
01405 
01406 int MakePreview(void){
01407  WNDCLASS   wc;
01408  static BOOL preview_busy=FALSE;
01409  if(preview_busy)return FAIL;
01410  if(Nframes < 2){
01411    SendPrgmQuery(IDQ_PREVIEW_NOMAKE,0);
01412    return FAIL;
01413  }
01414  wc.lpszClassName = lpszAnimatorPreviewClass;
01415  wc.style = CS_SAVEBITS;
01416  wc.lpfnWndProc = (WNDPROC)PreviewWndProc;
01417  wc.cbClsExtra = 0;
01418  wc.cbWndExtra = 0;
01419  wc.hInstance = ghinst_main;
01420  wc.hIcon = LoadIcon(ghinst_main,"ANIMATORICON");
01421  wc.hCursor = NULL;
01422  wc.hbrBackground = NULL;
01423  wc.lpszMenuName = NULL;
01424  if(!RegisterClass(&wc))return FAIL;
01425  preview_busy=TRUE;
01426  hwndPreview=NULL;
01427  iPlayFrame=0;
01428  DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_PREVIEW),ghwnd_main,
01429                 (DLGPROC)PreviewDlgProc);
01430  FreePreview();
01431  hwndPreview=NULL;
01432  UnregisterClass(lpszAnimatorPreviewClass,ghinst_main);
01433  preview_busy=FALSE;
01434  return OK;
01435 }
01436 
01437 // end preview code
01438 
01439 #include "..\effects\sfxinfo.h"
01440 
01441 static BOOL CalculateEffectedVertices(double mr,
01442                                       double tall[4][4],
01443                                       double tcamera[4][4],
01444                                       double tpos[4][4],
01445                                       BOOL ground,
01446                                       point p, point gpos, point cpos,
01447                                       object *Op, Svertex *Vp){
01448  float t,vmax[3],vmin[3];
01449  sfxinfo SFX,*SFXinfo;
01450  sfxdata SFD,*SFXdata;
01451  FARPROC fpFun;
01452  void *(*fpFun1)(char *, sfxinfo *, Svertex *);
01453  void *(*fpFun2)(char *, sfxinfo *, sfxdata *, Svertex *);
01454  double x0,y0,z0,x1,y1,z1;
01455  long Nv,i,j;
01456  if(Op->hEffect == NULL || Op->effect == NULL)return FALSE;
01457  if((fpFun=GetProcAddress(Op->hEffect,"_PreviewExternalEffect")) == NULL){
01458    return FALSE;
01459  }
01460  Nv=Op->npoints;
01461  t=(float)(Op->lastframe - Op->firstframe+1);
01462  t=(float)(CurrentFrame - Op->firstframe+1)/t;
01463  SFXinfo=&SFX;
01464  SFX.nvert=Nv;
01465  SFX.time=t;
01466  SFX.ltime=(long)(t*1000);
01467  SFX.Nfaces=0;
01468  SFX.Faces=NULL;
01469 #if __LITE__
01470  SFX.version=0;
01471 #else
01472  SFX.version=1;
01473 #endif
01474  for(j=0;j<3;j++){
01475    SFX.origin[j]=Op->origin[j];
01476    vmax[j]= -1.e30;
01477    vmin[j]=  1.e30;
01478  }
01479  fpFun1 = (void *)fpFun;
01480  if(mr < 0.0){
01481    for(i=0;i<Nv;i++){
01482      for(j=0;j<3;j++){
01483        Vp[i][j]=(float)(Op->points[i][j] - Op->origin[j]);
01484        vmin[j] = min(vmin[j],Vp[i][j]);
01485        vmax[j] = max(vmax[j],Vp[i][j]);
01486      }
01487    }
01488  }
01489  else if(Op->last != NULL){
01490    long l,m;
01491    for(i=0;i<Nv;i++){
01492      for(j=0;j<3;j++){
01493        l = Op->points[i][j] - Op->origin[j];
01494        m = Op->last->points[i][j] - Op->last->origin[j];
01495        Vp[i][j] = (double)(l-m)*mr + (double)m;
01496        vmin[j] = min(vmin[j],Vp[i][j]);
01497        vmax[j] = max(vmax[j],Vp[i][j]);
01498      }
01499    }
01500  }
01501  for(j=0;j<3;j++){
01502    SFX.vmin[j]=(long)vmin[j];
01503    SFX.vmax[j]=(long)vmax[j];
01504  }
01505  (*fpFun1)(Op->effect,SFXinfo,Vp);
01506  if((fpFun=GetProcAddress(Op->hEffect,"_PreviewGlobalEffect")) == NULL){
01507    for(i=0;i<Nv;i++){ /* just the local effect */
01508      x0=(double)Vp[i][0]; y0=(double)Vp[i][1]; z0=(double)Vp[i][2];
01509      m4by1(tall,x0,y0,z0,&x1,&y1,&z1);
01510      Vp[i][0]=(float)x1; Vp[i][1]=(float)y1; Vp[i][2]=(float)z1;
01511    }
01512  }
01513  else{
01514    for(i=0;i<Nv;i++){
01515      m4by1(tpos,
01516            (double)Vp[i][0],(double)Vp[i][1],(double)Vp[i][2],
01517            &x1,&y1,&z1);
01518      Vp[i][0]=(float)x1; Vp[i][1]=(float)y1; Vp[i][2]=(float)z1;
01519    }
01520    SFXdata=&SFD;
01521    memset(SFXdata,0,sizeof(sfxdata));
01522    SFD.size=sizeof(sfxdata);
01523    SFD.version=1;
01524    SFD.ground=ground;
01525    VECCOPY(p,SFD.pos)
01526    VECCOPY(gpos,SFD.ground_pos)
01527    VECCOPY(cpos,SFD.camera_pos)
01528    fpFun2 = (void *)fpFun;
01529    (*fpFun2)(Op->effect,SFXinfo,SFXdata,Vp);
01530    for(i=0;i<Nv;i++){
01531      m4by1(tcamera,
01532            (double)Vp[i][0],(double)Vp[i][1],(double)Vp[i][2],
01533            &x1,&y1,&z1);
01534      Vp[i][0]=(float)x1; Vp[i][1]=(float)y1; Vp[i][2]=(float)z1;
01535    }
01536  }
01537  return TRUE;
01538 }
01539 
01540 static void ClipToPlane(double *x1, double *y1, double *z1,
01541                         double x2, double y2, double z2, long Cp){
01542  double mu;
01543  mu=(y2 - *y1);
01544  if(fabs(mu) < 1.e-3)mu=1.e-3;
01545  mu=((double)Cp - *y1)/mu;
01546  *x1 = *x1 + mu * (x2 - *x1);
01547  *y1 = *y1 + mu * (y2 - *y1);
01548  *z1 = *z1 + mu * (z2 - *z1);
01549  return;
01550 }
01551 
01552 static void ProjectToX(long *x1, long *y1, long *x2, long *y2, long x){
01553  double dx,dy;
01554  dx=(double)(*x2 - *x1);
01555  dy=(double)(*y2 - *y1);
01556  *y1 = *y1 + (long)((double)(x - *x1)*dy/dx);
01557  *x1 = x;
01558 }
01559 
01560 static void ProjectToY(long *x1, long *y1, long *x2, long *y2, long y){
01561  double dx,dy;
01562  dx=(double)(*x2 - *x1);
01563  dy=(double)(*y2 - *y1);
01564  *x1 = *x1 + (long)((double)(y - *y1)*dx/dy);
01565  *y1 = y;
01566 }
01567 
01568 static BOOL ClipToWindow(long *x1, long *y1,
01569                          long *x2, long *y2,
01570                          long xmin, long ymin,
01571                          long xmax, long ymax){
01572  if(*x1 < xmin && *x2 < xmin)return FALSE;
01573  if(*x1 > xmax && *x2 > xmax)return FALSE;
01574  if(*y1 < ymin && *y2 < ymin)return FALSE;
01575  if(*y1 > ymax && *y2 > ymax)return FALSE;
01576  if(*x1 >= xmin && *x1 <= xmax &&
01577     *y1 >= ymin && *y1 <= ymax &&
01578     *x2 >= xmin && *x2 <= xmax &&
01579     *y2 >= ymin && *y2 <= ymax)return TRUE;
01580  if     (*x1 < xmin)ProjectToX(x1,y1,x2,y2,xmin);
01581  else if(*x1 > xmax)ProjectToX(x1,y1,x2,y2,xmax);
01582  if     (*x2 < xmin)ProjectToX(x2,y2,x1,y1,xmin);
01583  else if(*x2 > xmax)ProjectToX(x2,y2,x1,y1,xmax);
01584  if     (*y1 < ymin)ProjectToY(x1,y1,x2,y2,ymin);
01585  else if(*y1 > ymax)ProjectToY(x1,y1,x2,y2,ymax);
01586  if     (*y2 < ymin)ProjectToY(x2,y2,x1,y1,ymin);
01587  else if(*y2 > ymax)ProjectToY(x2,y2,x1,y1,ymax);
01588  return TRUE;
01589 }
01590 
01591 /* Warning on mirror??? should be  + scale*x1 etc WHY */
01592 
01593 void DrawViewRobot(HDC hdcView, HBITMAP hbmView, HWND hWnd,
01594                    node *Np, int arm, int axis,
01595                    double ra, double ua,
01596                    BOOL zoom,BOOL zoom_state){
01597  RECT    rc;
01598  double  scale,size,x1,y1,z1,x2,y2,z2,t1[4][4],t2[4][4],t3[4][4];
01599  vector  cc;
01600  int     pwinr,pwinb,pwincx,pwincy;
01601  int     ix1,iy1,ix2,iy2;
01602  long    i,j,k,n;
01603  object  *Op;
01604  skel    *sp;
01605  if(hdcView == NULL || hbmView == NULL)return;
01606  GetClientRect(hWnd,&rc);
01607  PatBlt(hdcView,0,0,rc.right,rc.bottom,PATCOPY);
01608  GetClientRect(hWnd,&rc);
01609  pwinr=rc.right; pwinb=rc.bottom;
01610  pwincx=rc.right/2; pwincy=rc.bottom/2;
01611  if(Np->type == ROBOT && ((Op=Np->fobj) != NULL))while(Op != NULL){
01612    if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
01613      if((n=Op->nskeleton) == 0 || (sp=Op->skeleton) == NULL)break;
01614      /* InterpolateRobot - Not Needed other windows call it */
01615      size=(double)GetRobotVolume(n,NULL,cc);
01616      scale=0.75*(double)pwinr/size;
01617      if(zoom && arm >=0 && arm < n){
01618        if(zoom_state && (j=(sp+arm)->id) >= 0 && j < n){
01619          tram(t1,-((sp+j)->pp[0]),-((sp+j)->pp[1]),-((sp+j)->pp[2]));
01620          scale *= 5.0;
01621        }
01622        else{
01623          tram(t1,-((sp+arm)->pp[0]),-((sp+arm)->pp[1]),-((sp+arm)->pp[2]));
01624          scale *= 4.0;
01625        }
01626      }
01627      else tram(t1,-cc[0],-cc[1],-cc[2]);
01628      rotz(t2, ra*PIo180);
01629      m4by4(t2,t1,t3);
01630      rotx(t1,-ua*PIo180);
01631      m4by4(t1,t3,t2);
01632      /* Bounding Box */
01633      SelectObject(hdcView,GetStockObject(BLACK_PEN));
01634      for(k=0;k<n;k++){
01635        m4by4(t2,(sp+k)->T,t3);
01636        for(i=0;i<12;i++){
01637          m4by1(t3,(double)(sp+k)->bx[ep1[i]][0]
01638                  ,(double)(sp+k)->bx[ep1[i]][1]
01639                  ,(double)(sp+k)->bx[ep1[i]][2]
01640                  ,&x1,&y1,&z1);
01641          m4by1(t3,(double)(sp+k)->bx[ep2[i]][0]
01642                  ,(double)(sp+k)->bx[ep2[i]][1]
01643                  ,(double)(sp+k)->bx[ep2[i]][2]
01644                  ,&x2,&y2,&z2);
01645          ix1=(int)(pwincx-scale*x1);
01646          iy1=(int)(pwincy-scale*z1);
01647          ix2=(int)(pwincx-scale*x2);
01648          iy2=(int)(pwincy-scale*z2);
01649          MoveToEx(hdcView,ix1,iy1,NULL);
01650          LineTo(hdcView,ix2,iy2);
01651        }
01652      }
01653      /* skeleton */
01654      SelectObject(hdcView,ghWireframePen);
01655      for(k=0;k<n;k++){
01656        x1=(double)sp[k].pp[0]; y1=(double)sp[k].pp[1]; z1=(double)sp[k].pp[2];
01657        m4by1(t2,x1,y1,z1,&x2,&y2,&z2);
01658        sp[k].wk[0]=(long)x2; sp[k].wk[1]=(long)y2; sp[k].wk[2]=(long)z2;
01659      }
01660      for(k=0;k<n;k++){
01661        x1=(double)sp[k].wk[0]; y1=(double)sp[k].wk[1]; z1=(double)sp[k].wk[2];
01662        j=sp[k].id;  /* j is parent ID */
01663        if(j < 0)continue;
01664        x2=(double)sp[j].wk[0]; y2=(double)sp[j].wk[1]; z2=(double)sp[j].wk[2];
01665        ix1=(int)(pwincx-scale*x1); iy1=(int)(pwincy-scale*z1);
01666        ix2=(int)(pwincx-scale*x2); iy2=(int)(pwincy-scale*z2);
01667        MoveToEx(hdcView,ix1,iy1,NULL); LineTo(hdcView,ix2,iy2);
01668        if(k == arm && axis < 7){ /* draw node and axis */
01669          HPEN hPenT;             /* ix2,iy2 is parent  */
01670          vector pp,x={1.0,0.0,0.0},y={0.0,1.0,0.0},z={0.0,0.0,1.0};
01671          Ellipse(hdcView,ix1-3,iy1-3,ix1+4,iy1+4);
01672          if     (axis == 0)VECCOPY((double)sp[j].vv,pp)
01673          else if(axis == 1)VECCOPY((double)sp[j].uu,pp)
01674          else if(axis == 2)VECCOPY((double)sp[j].ww,pp)
01675          else if(axis == 3)VECCOPY(x,pp)
01676          else if(axis == 4)VECCOPY(y,pp)
01677          else if(axis == 5)VECCOPY(z,pp)
01678          if(axis == 0 && (i=sp[j].id) >= 0){ /* do axis 0 other way */
01679            x1=sp[i].pp[0]; y1=sp[i].pp[1]; z1=sp[i].pp[2];
01680          }
01681          else if(axis < 6){
01682            x1=(double)sp[j].pp[0]+(double)pp[0]*size*0.1;
01683            y1=(double)sp[j].pp[1]+(double)pp[1]*size*0.1;
01684            z1=(double)sp[j].pp[2]+(double)pp[2]*size*0.1;
01685          }
01686          else {x1=sp[k].pp[0]; y1=sp[k].pp[1]; z1=sp[k].pp[2];}
01687          m4by1(t2,x1,y1,z1,&x2,&y2,&z2);
01688          ix1=(int)(pwincx-scale*x2); iy1=(int)(pwincy-scale*z2);
01689          hPenT=SelectObject(hdcView,GetStockObject(WHITE_PEN));
01690          MoveToEx(hdcView,ix2,iy2,NULL); LineTo(hdcView,ix1,iy1);
01691          MoveToEx(hdcView,ix2-1,iy2-1,NULL); LineTo(hdcView,ix2+2,iy2-1);
01692          MoveToEx(hdcView,ix2-1,iy2  ,NULL); LineTo(hdcView,ix2+2,iy2  );
01693          MoveToEx(hdcView,ix2-1,iy2+1,NULL); LineTo(hdcView,ix2+2,iy2+1);
01694          SelectObject(hdcView,hPenT);
01695        }
01696      }
01697      break;
01698    }
01699    Op=Op->next;
01700  }
01701  InvalidateRect(hWnd,NULL,FALSE);
01702 }

Generated on Sun Apr 27 14:20:08 2014 for OpenFX by  doxygen 1.5.6