DRAWVIEW.C

Go to the documentation of this file.
00001 /* file drawview.c  */
00002 
00003 #define MODULE_DRAW 1
00004 
00005 #include "animate.h"
00006 
00007 static void GetInternalMotion(align *Ap, long frame, double dframe,
00008                               short *im, double *ima);
00009 static double GetFollowOnOffset(node *Np, long frame, double dframe,
00010                                 point Offset);
00011 static int CheckInterrupt(void);
00012 static void CalculateOffset(node *Np,long frame, double dframe, point dp, double sx,
00013                             double sy, double sz);
00014 static void CalculateSize(node *Np, long frame, double dframe,
00015                           double *sx, double *sy, double *sz);
00016 static void DrawLightCone(HDC hdc[], short status, node *Np,
00017                           short al_type, point Offset, point TrackedOffset,
00018                           double p, double t, double a,
00019                           short im, double ima, double cone,
00020                           double edge);
00021 static void DrawLightExtent(HDC hdc[], short status, node *Np,
00022                           short al_type, point Offset,
00023                           double sz);
00024 static void DrawCameraFOV(HDC hdc[],
00025                           short status, node *Np, short al_type,
00026                           point Offset, point TrackedOffset,
00027                           double p, double t, double a,
00028                           short im, double ima,
00029                           double sx, double sy, double sz);
00030 static short DrawQuickObject(HDC hdc[], object *Op, point Offset
00031                    , double p, double t, double a
00032                    , short im, double ima
00033                    , double sx, double sy, double sz, short status);
00034 static short DrawNurbsObject(HDC hdc[], object *Op, point Offset
00035                    , double p, double t, double a
00036                    , short im, double ima
00037                    , double sx, double sy, double sz, short status);
00038 static void DrawAxis(HDC hdc[], point v1, short status);
00039 static int OnModelEdge(int npx, int npy,
00040                        int sh1, int sv1, int sh2, int sv2,
00041                        point v1, point v2,
00042                        double *dc);
00043 
00044 static int zoom_abort=NO;
00045 static int order_list[3][3]={ {0,1,2},{1,2,0},{2,0,1} };
00046 
00047 static int CheckInterrupt(void){
00048  int i;
00049  MSG msg;
00050  if(do_NOT_abort)return 0;
00051  if(tool_move_flag){
00052 //MessageBeep(MB_OK);
00053    zoom_abort=1;
00054  }
00055  else zoom_abort=0;
00056  return zoom_abort;
00057 }
00058 
00059 void ScalePoint(double scalex, double scaley, double scalez,
00060                 point p, point r){
00061   r[0] = (long)(scalex*(double)p[0]);
00062   r[1] = (long)(scaley*(double)p[1]);
00063   r[2] = (long)(scalez*(double)p[2]);
00064 }
00065 
00066 void CopyPoint(point p1, point p2){
00067  p2[0]=p1[0]; p2[1]=p1[1]; p2[2]=p1[2];
00068 }
00069 
00070 void AddPoints(point p1, point p2, point result){
00071  result[0]=p1[0]+p2[0];
00072  result[1]=p1[1]+p2[1];
00073  result[2]=p1[2]+p2[2];
00074 }
00075 
00076 void SubPoints(point p1, point p2, point result){
00077  result[0]=p1[0]-p2[0];
00078  result[1]=p1[1]-p2[1];
00079  result[2]=p1[2]-p2[2];
00080 }
00081 
00082 short in_stage_triview(point vp){
00083  if( ((vp[0] > TVpointX) && (vp[0] < TVpointX+TVsizeX))
00084   && ((vp[1] > TVpointY) && (vp[1] < TVpointY+TVsizeY))
00085   && ((vp[2] > TVpointZ) && (vp[2] < TVpointZ+TVsizeZ))
00086    )return 1;
00087  return 0;
00088 }
00089 
00090 static short ep1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
00091 static short ep2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
00092 static point Pointer[6]={{  0,  0,  0}
00093                         ,{  0, 20,  0}
00094                         ,{  0, 30,  0}
00095                         ,{  3, 20,  0}
00096                         ,{ -3, 20,  0}
00097                         ,{  0,  0, 10}};
00098 static short pp1[5]={0,2,2,3,0};
00099 static short pp2[5]={1,3,4,4,5};
00100 static point Rectang[4]={{  0,  0,  0}
00101                         ,{ UNIT*4,  0,  0}
00102                         ,{ UNIT*4,-UNIT*4,  0}
00103                         ,{  0,-UNIT*4,  0}};
00104 static short rp1[4]={0,1,2,3};
00105 static short rp2[4]={1,2,3,0};
00106 static point trpoints[13],srpoints[10];
00107 
00108 void get_centre_stage(point p, point TVp, point TVclipMin, point TVclipMax){
00109  node *Np;
00110  object *Op;
00111  pathpoint *Pp;
00112  point  Offset,TrackedOffset;
00113  short im;
00114  double phi,theta,alpha,sx,sy,sz,ima;
00115  long i,xmin,xmax,ymin,ymax,zmin,zmax,d;
00116  xmin=ymin=zmin=MAXUNIT; xmax=ymax=zmax = -MAXUNIT;
00117  for(i=0;i<3;i++)TVclipMin[i]=TVclipMax[i]=0;
00118  if((Np=FirstNp) != NULL)while(Np != NULL){
00119    if((Op=Np->fobj) != NULL)while(Op != NULL){
00120      if((CurrentFrame >= Op->firstframe) && (CurrentFrame <= Op->lastframe)){
00121        GetTransform(0,CurrentFrame,1.0,Np,Op,Offset,TrackedOffset,&phi,&theta,&alpha,
00122                     &sx,&sy,&sz,&im,&ima);
00123        if(Op->type == NORMAL || Op->type == ANIMOBJ){
00124          for(i=0;i<8;i++){
00125            srpoints[i][0] = (long)((double)Op->outline[i][0])*sx;
00126            srpoints[i][1] = (long)((double)Op->outline[i][1])*sy;
00127            srpoints[i][2] = (long)((double)Op->outline[i][2])*sz;
00128          }
00129          Transform(8,srpoints,trpoints,Offset,phi,theta,alpha,im,ima);
00130          for(i=0;i<8;i++){
00131            if(trpoints[i][0] < xmin)xmin=trpoints[i][0];
00132            if(trpoints[i][0] > xmax)xmax=trpoints[i][0];
00133            if(trpoints[i][1] < ymin)ymin=trpoints[i][1];
00134            if(trpoints[i][1] > ymax)ymax=trpoints[i][1];
00135            if(trpoints[i][2] < zmin)zmin=trpoints[i][2];
00136            if(trpoints[i][2] > zmax)zmax=trpoints[i][2];
00137          }
00138        }
00139        else if(Op->type == ROBOT){
00140          if(Op->nskeleton > 0 && Op->skeleton != NULL){
00141            double t1[4][4],x,y,z;
00142            RobotTransform(Offset,phi,theta,alpha,sx,sy,sz,im,ima,t1);
00143            for(i=0;i<Op->nskeleton;i++){
00144              m4by1(t1,(double)(Op->skeleton+i)->p[0],
00145                       (double)(Op->skeleton+i)->p[1],
00146                       (double)(Op->skeleton+i)->p[2],&x,&y,&z);
00147              if(x < xmin)xmin=x;
00148              if(y > xmax)xmax=y;
00149              if(z < ymin)ymin=z;
00150              if(x > ymax)ymax=x;
00151              if(y < zmin)zmin=y;
00152              if(z > zmax)zmax=z;
00153            }
00154          }
00155        }
00156        else if(Op->type == PATH){
00157          Pp=Op->firstpathpoint; while(Pp != NULL){
00158             CopyPoint(Pp->p,srpoints[0]);
00159             Transform(1,srpoints,trpoints,Offset,phi,theta,alpha,im,ima);
00160             if(trpoints[0][0] < xmin)xmin=trpoints[0][0];
00161             if(trpoints[0][0] > xmax)xmax=trpoints[0][0];
00162             if(trpoints[0][1] < ymin)ymin=trpoints[0][1];
00163             if(trpoints[0][1] > ymax)ymax=trpoints[0][1];
00164             if(trpoints[0][2] < zmin)zmin=trpoints[0][2];
00165             if(trpoints[0][2] > zmax)zmax=trpoints[0][2];
00166             Pp=Pp->next;
00167          }
00168        }
00169        else{
00170          if(Offset[0] < xmin)xmin=Offset[0];
00171          if(Offset[0] > xmax)xmax=Offset[0];
00172          if(Offset[1] < ymin)ymin=Offset[1];
00173          if(Offset[1] > ymax)ymax=Offset[1];
00174          if(Offset[2] < zmin)zmin=Offset[2];
00175          if(Offset[2] > zmax)zmax=Offset[2];
00176        }
00177      }
00178      Op=Op->next;
00179    }
00180    Np=Np->next;
00181  }
00182  p[0]=(xmax+xmin)/2; p[1]=(ymax+ymin)/2; p[2]=(zmax+zmin)/2;
00183  d=max(labs(xmax-xmin),labs(ymax-ymin)); d=max(d,labs(zmax-zmin));
00184  TVclipMin[0]=xmin;TVclipMin[1]=ymin;TVclipMin[2]=zmin;
00185  TVclipMax[0]=xmax;TVclipMax[1]=ymax;TVclipMax[2]=zmax;
00186  d=max(d,UNIT); d=min(d,MAXUNIT); d = d+d*0.3; d /= 2;
00187  TVp[0]=p[0]-d; TVp[1]=p[1]-d; TVp[2]=p[2]-d;
00188 }
00189 
00190 void Transform(long n ,point Ain[], point Aout[], point Offset,
00191                double p, double t, double a, short im, double ima){
00192  long i;
00193  double tr1[4][4],tr2[4][4],tr3[4][4],trpos[4][4],x,y,z;
00194  if(im > 0){
00195    if     (im == 1)rotz(tr1,ima*PIo180);
00196    else if(im == 2)rotx(tr1,ima*PIo180);
00197    else if(im == 3)roty(tr1,ima*PIo180);
00198    roty(tr3,t*PI/180.0);
00199    m4by4(tr3,tr1,tr2);
00200  }
00201  else roty(tr2,t*PIo180);
00202  rotx(tr3,a*PIo180);
00203  m4by4(tr3,tr2,tr1);
00204  rotz(tr2,p*PIo180);
00205  m4by4(tr2,tr1,trpos);
00206  for(i=0;i<n;i++){
00207   m4by1(trpos,(double)Ain[i][0],(double)Ain[i][1],(double)Ain[i][2],&x,&y,&z);
00208   Aout[i][0]=(long)x;  Aout[i][1]=(long)y;  Aout[i][2]=(long)z;
00209   AddPoints(Aout[i],Offset,Aout[i]);
00210  }
00211 }
00212 
00213 static void GetInternalMotion(align *Ap, long frame, double dframe,
00214                               short *im, double *ima){
00215  double ratio,dp;
00216  *im = Ap->im;
00217  if(Ap->firstframe == Ap->lastframe){
00218    *ima=0.0;
00219  }
00220  else{
00221    ratio=((double)frame+dframe  - (double)Ap->firstframe)
00222         /(double)(Ap->lastframe+1 - Ap->firstframe);
00223    dp = 360.0*ratio*Ap->ima ;    /* ima is +1 for anti clock one turn */
00224    if(dp < -180.0)dp += 360.0;
00225    if(dp >  180.0)dp -= 360.0;
00226    *ima = dp;
00227  }
00228 }
00229 
00230 void CalculateDirection(point C, point T, double * phi,
00231                         double * theta, double * alpha){
00232  double dx,dy,dz,dxy;
00233  *phi=0; *theta=0; *alpha=0;
00234  dx=(double)(T[0]-C[0]);
00235  dy=(double)(T[1]-C[1]);
00236  dz=(double)(T[2]-C[2]);
00237  dxy=sqrt(dx*dx+dy*dy);
00238  if(dxy < 1.0e-10)return;
00239  *phi=asin(dy/dxy);
00240  if(dx < 0.0){*phi = PI - *phi;  if(*phi > PI) *phi = *phi-2*PI;}
00241  *alpha=asin(dz/sqrt(dx*dx+dy*dy+dz*dz));
00242  *phi   *= 180.0/PI;
00243  *phi   -=  90.0;
00244  *alpha *= 180.0/PI;
00245  return;
00246 }
00247 
00248 static void CalculateOffset(node *Np,long frame, double dframe,
00249                             point dp, double sx,
00250                             double sy, double sz){ /* get object offset */
00251  object *Op;
00252  double mr;
00253  dp[0]=dp[1]=dp[2]=0;
00254  if((Op=Np->fobj) != NULL)while(Op != NULL){
00255    if((frame >= Op->firstframe) && (frame <= Op->lastframe)){
00256      if(Op->morph != NO && Op->last != NULL){
00257        mr=(double)(Op->lastframe - Op->firstframe+1);
00258        mr=((double)frame + dframe - (double)Op->firstframe)/mr;
00259        dp[0] = (long)((double)(Op->offset[0] -
00260               Op->last->offset[0])*mr + Op->last->offset[0])*sx;
00261        dp[1] = (long)((double)(Op->offset[1] -
00262               Op->last->offset[1])*mr + Op->last->offset[1])*sy;
00263        dp[2] = (long)((double)(Op->offset[2] -
00264               Op->last->offset[2])*mr + Op->last->offset[2])*sz;
00265      }
00266      else{
00267        dp[0] = (long)(Op->offset[0] * sx);
00268        dp[1] = (long)(Op->offset[1] * sy);
00269        dp[2] = (long)(Op->offset[2] * sz);
00270      }
00271      return;
00272    }
00273    Op=Op->next;
00274  }
00275 }
00276 
00277 static void CalculateSize(node *Np, long frame, double dframe,
00278                           double *sx, double *sy, double *sz){
00279  size *Xp;
00280  double lsx,lsy,lsz,nsx,nsy,nsz,ratio;
00281  double kx[4],ky[4],kz[4];
00282  if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
00283   if(frame >= Xp->firstframe && frame <= Xp->lastframe){
00284     if(Xp->last == NULL){
00285        *sx=Xp->Sx; *sy=Xp->Sy; *sz=Xp->Sz;
00286     }
00287     else{  /* interpolate size by spline tweening */
00288       ratio=((double)frame+dframe - (double)Xp->firstframe)
00289            /(double)(Xp->lastframe+1 - Xp->firstframe);
00290        if(Xp->last->last == NULL ||
00291         (Xp->last->lastframe - Xp->last->firstframe) == 0){
00292         lsx = lsy = lsz = 0.0;
00293       }
00294       else{
00295         lsx=Xp->last->Sx - Xp->last->last->Sx;
00296         lsy=Xp->last->Sy - Xp->last->last->Sy;
00297         lsz=Xp->last->Sz - Xp->last->last->Sz;
00298       }
00299       if(Xp->next == NULL ||
00300         (Xp->next->lastframe - Xp->next->firstframe) == 0){
00301         nsx = nsy = nsz = 0.0;
00302       }
00303       else{
00304         nsx=Xp->next->Sx - Xp->Sx;
00305         nsy=Xp->next->Sy - Xp->Sy;
00306         nsz=Xp->next->Sz - Xp->Sz;
00307       }
00308       SplinesG(kx,Xp->last->Sx,Xp->Sx,lsx,nsx);
00309       SplinesG(ky,Xp->last->Sy,Xp->Sy,lsy,nsy);
00310       SplinesG(kz,Xp->last->Sz,Xp->Sz,lsz,nsz);
00311       *sx = SplinesR(kx,ratio);
00312       *sy = SplinesR(ky,ratio);
00313       *sz = SplinesR(kz,ratio);
00314     }
00315     break;
00316   }
00317   Xp=Xp->next;
00318  }
00319 }
00320 
00321 cameraparam *CalculateCameraProperties(node *Np, long frame, double dframe){
00322   // These are extracted from the Camera objects Scale object
00323  size *Xp;
00324  static cameraparam cc;  // this will retain its value after function returns
00325  double ratio; 
00326  if((Xp=Np->fsiz) != NULL)while(Xp != NULL){
00327   if(frame >= Xp->firstframe && frame <= Xp->lastframe){
00328     if(Xp->last == NULL){
00329       return &(Xp->camera_params);
00330     }
00331     else{  /* interpolate parameters */
00332       ratio=((double)frame+dframe - (double)Xp->firstframe)
00333            /(double)(Xp->lastframe+1 - Xp->firstframe);
00334       memcpy(&cc,&(Xp->camera_params),sizeof(cameraparam));
00335       cc.f_number=(Xp->camera_params.f_number - Xp->last->camera_params.f_number)*ratio + Xp->last->camera_params.f_number;
00336       cc.focal_length=(Xp->camera_params.focal_length - Xp->last->camera_params.focal_length)*ratio + Xp->last->camera_params.focal_length;
00337       cc.focus_distance=(Xp->camera_params.focus_distance - Xp->last->camera_params.focus_distance)*ratio + Xp->last->camera_params.focus_distance;
00338       cc.stereo_separation=(Xp->camera_params.stereo_separation - Xp->last->camera_params.stereo_separation)*ratio + Xp->last->camera_params.stereo_separation;
00339       cc.parallax_distance=(Xp->camera_params.parallax_distance - Xp->last->camera_params.parallax_distance)*ratio + Xp->last->camera_params.parallax_distance;
00340       //return &(Xp->camera_params);
00341       return &(cc);
00342     }
00343   }
00344   Xp=Xp->next;
00345  }
00346  return NULL;
00347 }
00348 
00349 
00350 
00351 static double GetFollowOnOffset(node *Np, long frame, double dframe,
00352                                 point Offset){
00353  position *Pp;
00354  object   *Op;
00355  node     *Npo,*Npi;
00356  point p,RelativeOffset;
00357  long follow_count=0;
00358  double sx=1.0,sy=1.0,sz=1.0,displacement=0.0,ratio = -1.0,length_on_path;
00359  Offset[0]=Offset[1]=Offset[2]=0; Npi=Np;
00360  while(Np != NULL){
00361    if(follow_count++ > 64){
00362      SendPrgmQuery(IDQ_SELFFOLLOW1,0);
00363      SendPrgmQuery(IDQ_SELFFOLLOW2,0);
00364      Pp=Npi->fpos;
00365      if(Pp != NULL)while(Pp != NULL){
00366        Pp->type=TWEEN;
00367        Pp=Pp->next;
00368      }
00369      return 0.0;
00370    }
00371    Pp=Np->fpos; Npo=Np; Np=NULL;
00372    if(Pp != NULL)while(Pp != NULL){
00373      if((frame >= Pp->firstframe) && (frame <= Pp->lastframe)){
00374        if(Pp->type == FOLLOWON){
00375          CalculateSize(Npo,frame,dframe,&sx,&sy,&sz);
00376          CalculateOffset(Npo,frame,dframe,p,sx,sy,sz);
00377          displacement += p[1]; /* forwards displacement */
00378          Np=Pp->onpath;        /* on to next box car */
00379          break;  /* break out of while Pp */
00380        }
00381        else if(Pp->type == FOLLOW && Pp->onpath != NULL &&
00382                Pp->onpath->type == PATH){
00383          CalculateSize(Npo,frame,dframe,&sx,&sy,&sz);
00384          CalculateOffset(Npo,frame,dframe,p,sx,sy,sz);
00385          displacement += p[1]; /* forwards displacement */
00386          ratio = -1.0;
00387          if((Op=GetPathPosition(Pp->onpath,frame,dframe,RelativeOffset,
00388                                 &ratio,&length_on_path)) != NULL){
00389            length_on_path += displacement;
00390            if(length_on_path > 0.0){
00391              if(length_on_path >= Op->pathlength){
00392                if(Op->pathtype == CLOSED){
00393                  ratio = (length_on_path-Op->pathlength)/Op->pathlength;
00394                }
00395                else ratio = 0.99;
00396              }
00397              else ratio = length_on_path/Op->pathlength;
00398            }
00399            else if(Op->pathtype == CLOSED){ /* lop < 0 */
00400              ratio = (Op->pathlength+length_on_path)/Op->pathlength;
00401            }
00402            else ratio = 0.0; // possibly not finished
00403            if(ratio >= 0.0){
00404              if((Op=GetPathPosition(Pp->onpath,frame,dframe,RelativeOffset,
00405                                   &ratio,&length_on_path)) != NULL){
00406                AddPoints(Offset,RelativeOffset,Offset);
00407                GetOffsetPosition(Pp->onpath,Op,frame,dframe,Offset);
00408              }
00409            }
00410          }
00411        }
00412        /* any other type will keep Np = NULL and terminate */
00413      }
00414      Pp=Pp->next;
00415    }
00416  }
00417  return ratio;
00418 }
00419 
00420 double GetOffsetPosition(node *Np, object *Op,
00421                          long frame, double dframe,
00422                          point ObjectOffset){
00423   position *Pp;
00424   point dp,RelativeOffset,TrackedOffset,spl,spn,ofs;
00425   double ratio,kx[4],ky[4],kz[4],rp,ra,rt,rsx,rsy,rsz,rima,
00426          length_on_path,gs,ge;
00427   short rim;
00428   stackdepth++;
00429   ratio=0.0;
00430   if(Np == NULL)return(0.0);
00431   if(stackdepth > 64)longjmp(r_buf,-1);
00432   if((Pp=Np->fpos) != NULL)while(Pp != NULL){
00433    if((frame >= Pp->firstframe) && (frame <= Pp->lastframe)){
00434      if(Pp->type == TWEEN){
00435        if((Pp->last == NULL)) // || (Pp->firstframe == Pp->lastframe))
00436          AddPoints(ObjectOffset,Pp->finish,ObjectOffset);
00437        else{
00438          ratio=((double)frame+dframe - (double)Pp->firstframe)
00439               /(double)(Pp->lastframe+1 - Pp->firstframe);
00440          SubPoints(Pp->finish,Pp->last->finish,dp);
00441          ScalePoint(ratio,ratio,ratio,dp,dp);
00442          AddPoints(Pp->last->finish,dp,dp);
00443          AddPoints(ObjectOffset,dp,ObjectOffset);
00444        }
00445      }
00446      else if(Pp->type == FOLLOW || Pp->type == FOLLOWAT){
00447        if(Pp->type == FOLLOWAT)CopyPoint(ObjectOffset,ofs);
00448        if(Pp->onpath->type == PATH){/* if on path get offset rel to path */
00449          ratio = -1.0;
00450          if(GetPathPosition(Pp->onpath,frame,dframe,RelativeOffset,&ratio,
00451                             &length_on_path) != NULL){/* path has been found OK */
00452            AddPoints(ObjectOffset,RelativeOffset,ObjectOffset);
00453            GetOffsetPosition(Pp->onpath,Op,frame,dframe,ObjectOffset);
00454          }
00455        }
00456        else ratio=GetOffsetPosition(Pp->onpath,Op,frame,dframe,ObjectOffset);
00457        if(Pp->type == FOLLOWAT){
00458          if((Pp->last == NULL)){  // || (Pp->firstframe == Pp->lastframe)){
00459           if((!Pp->fx))ObjectOffset[0]=ofs[0]+Pp->finish[0];
00460           if((!Pp->fy))ObjectOffset[1]=ofs[1]+Pp->finish[1];
00461           if((!Pp->fz))ObjectOffset[2]=ofs[2]+Pp->finish[2];
00462          }
00463          else{
00464            ratio=((double)frame+dframe - (double)Pp->firstframe)
00465                 /(double)(Pp->lastframe+1 - Pp->firstframe);
00466            SubPoints(Pp->finish,Pp->last->finish,dp);
00467            ScalePoint(ratio,ratio,ratio,dp,dp);
00468            AddPoints(Pp->last->finish,dp,dp);
00469            if(!(Pp->fx))ObjectOffset[0]=ofs[0]+dp[0];
00470            if(!(Pp->fy))ObjectOffset[1]=ofs[1]+dp[1];
00471            if(!(Pp->fz))ObjectOffset[2]=ofs[2]+dp[2];
00472          }
00473        }
00474      }
00475      else if(Pp->type == FOLLOWOFF){
00476        GetTransform(1,frame,dframe,
00477                     Pp->onpath,NULL,ObjectOffset,TrackedOffset,
00478                     &rp,&rt,&ra,&rsx,&rsy,&rsz,&rim,&rima);
00479        CalculateOffset(Pp->onpath,frame,dframe,trpoints[0],rsx,rsy,rsz);
00480        Transform(1,trpoints,srpoints,ObjectOffset,rp,rt,ra,rim,rima);
00481        CopyPoint(srpoints[0],ObjectOffset);
00482      }
00483      else if(Pp->type == FOLLOWON){
00484        ratio=GetFollowOnOffset(Pp->onpath,frame,dframe,ObjectOffset);
00485      }
00486      else if(Pp->type == SPLINE){
00487        if((Pp->last == NULL))// || (Pp->firstframe == Pp->lastframe))
00488          AddPoints(ObjectOffset,Pp->finish,ObjectOffset);
00489        else{
00490          ratio=((double)frame+dframe - (double)Pp->firstframe)
00491               /(double)(Pp->lastframe+1 - Pp->firstframe);
00492          if(Pp->last->last != NULL)CopyPoint(Pp->last->last->finish,spl);
00493          else{
00494            SubPoints(Pp->finish,Pp->last->finish,dp);
00495            SubPoints(Pp->last->finish,dp,spl);
00496          }
00497          if(Pp->next != NULL)CopyPoint(Pp->next->finish,spn);
00498          else{
00499            SubPoints(Pp->finish,Pp->last->finish,dp);
00500            AddPoints(Pp->finish,dp,spn);
00501          }
00502 //         SplinesK(kx,spl[0],Pp->last->finish[0],Pp->finish[0],spn[0]);
00503 //         SplinesK(ky,spl[1],Pp->last->finish[1],Pp->finish[1],spn[1]);
00504 //         SplinesK(kz,spl[2],Pp->last->finish[2],Pp->finish[2],spn[2]);
00505          gs=(double)(Pp->finish[0]-spl[0])*Pp->tension_s;
00506          ge=(double)(spn[0]-Pp->last->finish[0])*Pp->tension_e;
00507          SplinesG(kx,Pp->last->finish[0],Pp->finish[0],gs,ge);
00508          gs=(double)(Pp->finish[1]-spl[1])*Pp->tension_s;
00509          ge=(double)(spn[1]-Pp->last->finish[1])*Pp->tension_e;
00510          SplinesG(ky,Pp->last->finish[1],Pp->finish[1],gs,ge);
00511          gs=(double)(Pp->finish[2]-spl[2])*Pp->tension_s;
00512          ge=(double)(spn[2]-Pp->last->finish[2])*Pp->tension_e;
00513          SplinesG(kz,Pp->last->finish[2],Pp->finish[2],gs,ge);
00514          ObjectOffset[0] += SplinesP(kx,ratio);
00515          ObjectOffset[1] += SplinesP(ky,ratio);
00516          ObjectOffset[2] += SplinesP(kz,ratio);
00517        }
00518      }
00519    }
00520    Pp=Pp->next;
00521   }
00522   return ratio;
00523 }
00524 
00525 short GetTransform(short stacking, long frame, double dframe,
00526              node *Np, object *Op,
00527              point ObjectOffset, point TrackedOffset,
00528              double *phi, double *theta, double *alpha,
00529              double *sx,  double *sy,    double *sz,
00530              short *im, double *ima){
00531 /* the returned values of phi theta and alpha are the rotations for
00532    the object about the vertical axis the object direction axis
00533    and the horizontal axis perp. to the direction. To draw the object
00534    I apply the theta rotation first then the alpha rotation and
00535    finally the phi rotation.  The offset translation is then applied
00536    to the object
00537    Rotation is +ve in the anticlockwise direction.
00538    THETA is around Y ie. from rear looking forwards
00539    ALPHA is around X ie. up down
00540    PHI   is around Z ie. rotation in plane
00541    returns type of alignment
00542  */
00543    point TrackedDummy,TrackedOrigin;
00544    align *Ap;
00545    size  *Xp;
00546    short rim;
00547    double dp,dpl,dpn,ratio,rsx,rsy,rsz,rima,length_on_path;
00548    double kx[4],ky[4],kz[4];
00549    long f,ddt;
00550    if(Np == NULL)return TWEEN;
00551    ObjectOffset[0]=0;  ObjectOffset[1]=0;  ObjectOffset[2]=0;
00552    TrackedOffset[0]=0; TrackedOffset[1]=0; TrackedOffset[2]=0;
00553    *phi=0; *theta=0; *alpha=0;
00554    if(Np->type == LIGHT){*sx=15.0; *sy=5.0;}
00555    else                 {*sx=1.0;  *sy=1.0;}
00556    *sz=1.0; *im=0; *ima=0.0;
00557    if(stacking == 0)stackdepth=0;/* set the stack count to the top of stack */
00558    if(stackdepth > 64)longjmp(r_buf,-1);
00559 
00560    CalculateSize(Np,frame,dframe,sx,sy,sz);
00561 
00562    if((Ap=Np->fali) != NULL){
00563     while(Ap != NULL){
00564      if(frame >= Ap->firstframe && frame <= Ap->lastframe){
00565        GetInternalMotion(Ap,frame,dframe,im,ima);
00566        if(Ap->type == TRACK ){
00567          GetOffsetPosition(Ap->topath,Op,frame,dframe,TrackedOffset);
00568          GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset);
00569          CalculateDirection(ObjectOffset,TrackedOffset,phi,theta,alpha);
00570          if((Ap->last == NULL)){// || (Ap->firstframe == Ap->lastframe)){
00571            *theta = Ap->theta;    /* banking while tracking */
00572          }
00573          else{
00574            ratio=((double)frame+dframe - (double)Ap->firstframe)
00575                 /(double)(Ap->lastframe+1 - Ap->firstframe);
00576            dp = Ap->theta - Ap->last->theta;
00577            if(dp < -180.0)dp += 360.0;
00578            if(dp >  180.0)dp -= 360.0;
00579            dp *= ratio;
00580            dp += Ap->last->theta;
00581            if(dp < -180.0)dp += 360.0;
00582            if(dp >  180.0)dp -= 360.0;
00583            *theta = dp;
00584          }
00585        }
00586        else if(Ap->type == COPY){
00587          stackdepth++;
00588          GetTransform(1,frame,dframe,
00589                       Ap->topath,NULL,TrackedOffset,TrackedDummy,/*TO just placer */
00590                       phi,theta,alpha,&rsx,&rsy,&rsz,&rim,&rima);
00591          GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset);
00592        }
00593        else if(Ap->type == TOPATH){
00594          ratio=GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset);
00595          if(Ap->topath->type == PATH && ratio > -1.5){/* offset OK */
00596            if(GetPathPosition(Ap->topath,frame,dframe,TrackedOrigin,&ratio,
00597                               &length_on_path) != NULL){ /* some where on path */
00598              if(ratio < 1.0){ /* not at end of path */
00599                ratio=min(ratio+0.01,1.0);
00600                GetPathPosition(Ap->topath,frame,dframe,TrackedOffset,
00601                                &ratio,&length_on_path);
00602              }
00603              else{ /* at end of path interpolate forwards */
00604                ratio -= 0.1;
00605                GetPathPosition(Ap->topath,frame,dframe,TrackedOffset,
00606                                &ratio,&length_on_path);
00607                SubPoints(TrackedOrigin,TrackedOffset,TrackedOffset);
00608                AddPoints(TrackedOrigin,TrackedOffset,TrackedOffset);
00609              }
00610              CalculateDirection(TrackedOrigin,TrackedOffset,phi,theta,alpha);
00611            }
00612            else{*phi=0; *alpha=0; *theta=0;} /* not on a path */
00613          }
00614          else{ /* not path to follow */
00615            *phi=0; *alpha=0; *theta=0;
00616          }
00617          if((Ap->last == NULL)){// || (Ap->firstframe == Ap->lastframe)){
00618            *theta = Ap->theta;    /* banking on path */
00619          }
00620          else{
00621            ratio=((double)frame+dframe - (double)Ap->firstframe)
00622                 /(double)(Ap->lastframe+1 - Ap->firstframe);
00623            dp = Ap->theta - Ap->last->theta;
00624            if(dp < -180.0)dp += 360.0;
00625            if(dp >  180.0)dp -= 360.0;
00626            dp *= ratio;
00627            dp += Ap->last->theta;
00628            if(dp < -180.0)dp += 360.0;
00629            if(dp >  180.0)dp -= 360.0;
00630            *theta = dp;
00631          }
00632        }
00633        else if(Ap->type == TWEEN){
00634          if((Ap->last == NULL)){ // || (Ap->firstframe == Ap->lastframe)){
00635           *phi=Ap->phi;
00636           *theta=Ap->theta;
00637           *alpha=Ap->alpha;
00638          }
00639          else{
00640            ratio=((double)frame+dframe - (double)Ap->firstframe)
00641                 /(double)(Ap->lastframe+1 - Ap->firstframe);
00642            dp = Ap->phi - Ap->last->phi;
00643            if(dp < -180.0)dp += 360.0;
00644            if(dp >  180.0)dp -= 360.0;
00645            dp *= ratio;
00646            dp += Ap->last->phi;
00647            if(dp < -180.0)dp += 360.0;
00648            if(dp >  180.0)dp -= 360.0;
00649            *phi = dp;
00650            dp = Ap->theta - Ap->last->theta;
00651            if(dp < -180.0)dp += 360.0;
00652            if(dp >  180.0)dp -= 360.0;
00653            dp *= ratio;
00654            dp += Ap->last->theta;
00655            if(dp < -180.0)dp += 360.0;
00656            if(dp >  180.0)dp -= 360.0;
00657            *theta = dp;
00658            dp = Ap->alpha - Ap->last->alpha;
00659            if(dp < -180.0)dp += 360.0;
00660            if(dp >  180.0)dp -= 360.0;
00661            dp *= ratio;
00662            dp += Ap->last->alpha;
00663            if(dp < -180.0)dp += 360.0;
00664            if(dp >  180.0)dp -= 360.0;
00665            *alpha = dp;
00666          }
00667          GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset);
00668        }
00669        else if(Ap->type == SPLINEA){
00670          if((Ap->last == NULL)){ // || (Ap->firstframe == Ap->lastframe)){
00671           *phi=Ap->phi;
00672           *theta=Ap->theta;
00673           *alpha=Ap->alpha;
00674          }
00675          else{
00676            ratio=((double)frame+dframe - (double)Ap->firstframe)
00677                 /(double)(Ap->lastframe+1 - Ap->firstframe);
00678            dp = Ap->phi - Ap->last->phi;
00679            if(dp < -180.0)dp += 360.0;
00680            if(dp >  180.0)dp -= 360.0;
00681            if(Ap->last->last == NULL)dpl=0.0;
00682            else{
00683              dpl = Ap->last->phi - Ap->last->last->phi;
00684              if(dpl < -180.0)dpl += 360.0;
00685              if(dpl >  180.0)dpl -= 360.0;
00686              ddt = Ap->last->lastframe - Ap->last->firstframe;
00687              if(ddt == 0)dpl=0.0; /* single frame  zero gradient */
00688            }
00689            if(Ap->next == NULL)dpn=0.0;
00690            else{
00691              dpn = Ap->next->phi - Ap->phi;
00692              if(dpn < -180.0)dpn += 360.0;
00693              if(dpn >  180.0)dpn -= 360.0;
00694              ddt = Ap->next->lastframe - Ap->next->firstframe;
00695              if(ddt == 0)dpn=0.0;
00696            }
00697            SplinesG(kx,Ap->last->phi,Ap->last->phi+dp,dpl,dpn);
00698            dp=SplinesR(kx,ratio);
00699            if(dp < -180.0)dp += 360.0;
00700            if(dp >  180.0)dp -= 360.0;
00701            *phi = dp;
00702            dp = Ap->theta - Ap->last->theta;
00703            if(dp < -180.0)dp += 360.0;
00704            if(dp >  180.0)dp -= 360.0;
00705            if(Ap->last->last == NULL)dpl=0.0;
00706            else{
00707              dpl = Ap->last->theta - Ap->last->last->theta;
00708              if(dpl < -180.0)dpl += 360.0;
00709              if(dpl >  180.0)dpl -= 360.0;
00710              ddt = Ap->last->lastframe - Ap->last->firstframe;
00711              if(ddt == 0)dpl=0.0;
00712            }
00713            if(Ap->next == NULL)dpn=0.0;
00714            else{
00715              dpn = Ap->next->theta - Ap->theta;
00716              if(dpn < -180.0)dpn += 360.0;
00717              if(dpn >  180.0)dpn -= 360.0;
00718              ddt = Ap->next->lastframe - Ap->next->firstframe;
00719              if(ddt == 0)dpn=0.0;
00720            }
00721            SplinesG(kx,Ap->last->theta,Ap->last->theta+dp,dpl,dpn);
00722            dp=SplinesR(kx,ratio);
00723            if(dp < -180.0)dp += 360.0;
00724            if(dp >  180.0)dp -= 360.0;
00725            *theta = dp;
00726            dp = Ap->alpha - Ap->last->alpha;
00727            if(dp < -180.0)dp += 360.0;
00728            if(dp >  180.0)dp -= 360.0;
00729            if(Ap->last->last == NULL)dpl=0.0;
00730            else{
00731              dpl = Ap->last->alpha - Ap->last->last->alpha;
00732              if(dpl < -180.0)dpl += 360.0;
00733              if(dpl >  180.0)dpl -= 360.0;
00734              ddt = Ap->last->lastframe - Ap->last->firstframe;
00735              if(ddt == 0)dpl=0.0;
00736            }
00737            if(Ap->next == NULL)dpn=0.0;
00738            else{
00739              dpn = Ap->next->alpha - Ap->alpha;
00740              if(dpn < -180.0)dpn += 360.0;
00741              if(dpn >  180.0)dpn -= 360.0;
00742              ddt = Ap->next->lastframe - Ap->next->firstframe;
00743              if(ddt == 0)dpn=0.0;
00744            }
00745            SplinesG(kx,Ap->last->alpha,Ap->last->alpha+dp,dpl,dpn);
00746            dp=SplinesR(kx,ratio);
00747            if(dp < -180.0)dp += 360.0;
00748            if(dp >  180.0)dp -= 360.0;
00749            *alpha = dp;
00750          }
00751          GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset);
00752        }
00753        return Ap->type;  /* alignment has been found and calculated */
00754      }
00755      Ap=Ap->next;
00756     }
00757     GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset); /* no align found */
00758    }
00759    else GetOffsetPosition(Np,Op,frame,dframe,ObjectOffset); /* no align   */
00760    return TWEEN;
00761 }
00762 
00763 //
00764 /* draw actors */
00765 
00766 void DrawActorCentre(HDC hdc[],point v1, double p, double t, double a,
00767                      short im, double ima, double scale){
00768  int sh1,sv1,i;
00769  int ifd,ild;
00770  if(View == TRIVIEW){ifd=0;ild=3;}
00771  else               {ifd=ActiveView; ild=ifd+1;}
00772  if(in_stage_triview(v1)){
00773    for(i=ifd;i<ild;i++){
00774      GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00775      Rectangle(hdc[i],(int)sh1-2,(int)sv1-2,(int)sh1+2,(int)sv1+2);
00776    }
00777  }
00778 }
00779 
00780 void DrawArrow(HDC hdc[], point Offset, double p, double t, double a,
00781                short im, double ima, double scale){
00782  int sh1,sv1,sh2,sv2,i;
00783  point v1,v2;
00784  point Lpointer[6];
00785  short ep;
00786  double s10;
00787  int ifd,ild;
00788  if(View == TRIVIEW){ifd=0;ild=3;}
00789  else               {ifd=ActiveView; ild=ifd+1;}
00790  s10=scale/10.0;
00791  for(i=0;i<6;i++)ScalePoint(s10,s10,s10,Pointer[i],Lpointer[i]);
00792  Transform(6,Lpointer,trpoints,Offset,p,t,a,im,ima);
00793  for(ep=0;ep<5;ep++){
00794    CopyPoint(trpoints[pp1[ep]],v1);
00795    CopyPoint(trpoints[pp2[ep]],v2);
00796    if(in_stage_triview(v1) || in_stage_triview(v2)){
00797      for(i=ifd;i<ild;i++){
00798        GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00799        GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
00800        MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
00801      }
00802    }
00803  }
00804 }
00805 
00806 void DrawDirectionLine(HDC hdc[],
00807                point Offset,
00808                double p, double t, double a,
00809                short im, double ima, double scale){
00810  int sh1,sv1,sh2,sv2,i;
00811  point v1,v2;
00812  point Lpointer[2];
00813  short ep;
00814  double s10;
00815  int ifd,ild;
00816  if(View == TRIVIEW){ifd=0;ild=3;}
00817  else               {ifd=ActiveView; ild=ifd+1;}
00818  s10=scale/10.0;
00819  for(i=0;i<2;i++)ScalePoint(s10,s10,s10,Pointer[i],Lpointer[i]);
00820  Transform(2,Lpointer,trpoints,Offset,p,t,a,im,ima);
00821  CopyPoint(trpoints[0],v1);
00822  CopyPoint(trpoints[1],v2);
00823  if(in_stage_triview(v1) || in_stage_triview(v2)){
00824    for(i=ifd;i<ild;i++){
00825      GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00826      GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
00827      MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
00828    }
00829  }
00830 }
00831 
00832 static short BV_id[3] ={1,2,0};
00833 static short TV_id[3] ={2,1,0};
00834 static short EV_id[6][4]={ 0, 1, 2, 3, 4, 5, 6, 7, 2, 6,10,11,
00835                            0, 4, 8, 9, 1, 5, 9,10, 3, 7,11, 8};
00836 static short QF1[6]={0,4,3,0,2,0}; /* vertices to calculate normals */
00837 static short QF2[6]={1,7,2,4,1,3};
00838 static short QF3[6]={0,4,3,0,2,3};
00839 static short QF4[6]={3,5,7,1,6,7};
00840 
00841 #define CROSS(v1,v2,r)  { \
00842                           r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]);  \
00843                           r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]);  \
00844                           r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]);  \
00845                         }
00846 
00847 static void DrawSolidBox(HDC hdc[]){
00848  int sh1,sv1,sh2,sv2,i,e,f,visi[12];
00849  double n[6][3],n1[3],n2[3];
00850  point v1,v2;
00851  int ifd,ild;
00852  if(View == TRIVIEW){ifd=0;ild=3;}
00853  else               {ifd=ActiveView; ild=ifd+1;}
00854  for(f=0;f<6;f++){ /* calculate normal vector */
00855   for(i=0;i<3;i++){
00856     n1[i]=(double)(trpoints[QF2[f]][i] - trpoints[QF1[f]][i]);
00857     n2[i]=(double)(trpoints[QF4[f]][i] - trpoints[QF3[f]][i]);
00858   }
00859   CROSS(n1,n2,n[f]);
00860   if(WindowBox_view == 0)n[f][1] = -n[f][1];
00861  }
00862  for(i=ifd;i<ild;i++){
00863    for(e=0;e<12;e++)visi[e]=0;
00864    for(f=0;f<6;f++)if(n[f][TV_id[i]] > 0.0){ /* face is visible */
00865      for(e=0;e<4;e++)visi[EV_id[f][e]]=1;
00866    }
00867    for(e=0;e<12;e++)if(visi[e]){
00868      CopyPoint(trpoints[ep1[e]],v1);
00869      CopyPoint(trpoints[ep2[e]],v2);
00870      if(in_stage_triview(v1) || in_stage_triview(v2)) {
00871        GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00872        GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
00873        MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
00874      }
00875    }
00876  }
00877 }
00878 
00879 static void DrawObject(HDC hdc[], object *Op,
00880                point Offset, double p,
00881                double t, double a, short im, double ima,
00882                double sx, double sy, double sz, short status){
00883  int sh1,sv1,sh2,sv2,i,ep;
00884  point  v1,v2;
00885  double mr;
00886  int ifd,ild;
00887  if(View == TRIVIEW){ifd=0;ild=3;}
00888  else               {ifd=ActiveView; ild=ifd+1;}
00889 // if(status == DESELECTED)
00890 //    DrawActorCentre(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00891  if(status == SELECTED)DrawArrow(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00892  if(Op->w_frame.p != NULL){
00893    if(DrawQuickObject(hdc,Op,Offset,p,t,a,im,ima,sx,sy,sz,status) == OK)return;
00894  }
00895  // Don't need this since bounding box is OK
00896  //DrawNurbsObject(hdc,Op,Offset,p,t,a,im,ima,sx,sy,sz,status);
00897  if(Op->morph != NO && Op->last != NULL){
00898    mr=(double)(Op->lastframe - Op->firstframe+1);
00899    mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00900    for(i=0;i<8;i++){
00901      srpoints[i][0] = (long)((double)(Op->outline[i][0] -
00902          Op->last->outline[i][0])*mr + Op->last->outline[i][0])*sx;
00903      srpoints[i][1] = (long)((double)(Op->outline[i][1] -
00904          Op->last->outline[i][1])*mr + Op->last->outline[i][1])*sy;
00905      srpoints[i][2] = (long)((double)(Op->outline[i][2] -
00906          Op->last->outline[i][2])*mr + Op->last->outline[i][2])*sz;
00907    }
00908  }
00909  else{
00910    for(i=0;i<8;i++){
00911      srpoints[i][0] = (long)((double)Op->outline[i][0])*sx;
00912      srpoints[i][1] = (long)((double)Op->outline[i][1])*sy;
00913      srpoints[i][2] = (long)((double)Op->outline[i][2])*sz;
00914    }
00915  }
00916  Transform(8,srpoints,trpoints,Offset,p,t,a,im,ima);
00917 
00918  if(status == SELECTED && tool != NOTOOL && tool != NODETOOL){
00919    DrawSolidBox(hdc);
00920    return;
00921  }
00922 
00923  for(ep=0;ep<12;ep++){
00924    CopyPoint(trpoints[ep1[ep]],v1);
00925    CopyPoint(trpoints[ep2[ep]],v2);
00926    if(in_stage_triview(v1) || in_stage_triview(v2)) {
00927      for(i=ifd;i<ild;i++){
00928        GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00929        GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
00930        MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
00931      }
00932    }
00933  }
00934 }
00935 
00936 static short DrawNurbsObject(HDC hdc[], object *Op, point Offset
00937                    , double p, double t, double a
00938                    , short im, double ima
00939                    , double sx, double sy, double sz, short status){
00940  vector4 *p1;
00941  nurbs *n;
00942  int sh1,sv1,sh2,sv2;
00943  point  v1,v2,*Vp;
00944  long ii,jj,i,j,k,id1,id2,NP;
00945  double mr,w;
00946  int ifd,ild;
00947  if(View == TRIVIEW){ifd=0;ild=3;}
00948  else               {ifd=ActiveView; ild=ifd+1;}
00949  if(Op->nNurbs == 0 || Op->Nurbs == NULL)return FAIL;
00950  for(k=0;k<Op->nNurbs;k++){
00951    n=(Op->Nurbs+k);
00952    if(n->properties.hidden)continue;
00953    if((Vp=(point *)X__Malloc((n->numU * n->numV)*sizeof(point))) == NULL)return FAIL;
00954    if(Op->morph != NO && Op->last != NULL && Op->last->Nurbs != NULL &&
00955       Op->nNurbs == Op->last->nNurbs){
00956      mr=(double)(Op->lastframe - Op->firstframe+1);
00957      mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00958      j=0;
00959      for(ii=0;ii<n->numV;ii++)
00960      for(jj=0;jj<n->numU;jj++){
00961        p1 = &(n->points[ii][jj]);
00962        w=1.0/p1->w;
00963        Vp[j][0]=(long)((p1->x)*w);
00964        Vp[j][1]=(long)((p1->y)*w);
00965        Vp[j][2]=(long)((p1->z)*w);
00966        Vp[j][0] = Vp[j][0]*sx;
00967        Vp[j][1] = Vp[j][1]*sy;
00968        Vp[j][2] = Vp[j][2]*sz;
00969        p1 = &((Op->last->Nurbs+k)->points[ii][jj]);
00970        w=1.0/p1->w;
00971        v1[0]=(long)((p1->x)*w);
00972        v1[1]=(long)((p1->y)*w);
00973        v1[2]=(long)((p1->z)*w);
00974        Vp[j][0] = (long)((double)(Vp[j][0] - v1[0])*mr + v1[0])*sx;
00975        Vp[j][1] = (long)((double)(Vp[j][1] - v1[1])*mr + v1[1])*sy;
00976        Vp[j][2] = (long)((double)(Vp[j][2] - v1[2])*mr + v1[2])*sz;
00977        j++;
00978      }
00979    }
00980    else{
00981      j=0;
00982      for(ii=0;ii<n->numV;ii++)
00983      for(jj=0;jj<n->numU;jj++){
00984        p1 = &(n->points[ii][jj]);
00985        w=1.0/p1->w;
00986        Vp[j][0]=(long)((p1->x)*w);
00987        Vp[j][1]=(long)((p1->y)*w);
00988        Vp[j][2]=(long)((p1->z)*w);
00989        Vp[j][0] = Vp[j][0]*sx;
00990        Vp[j][1] = Vp[j][1]*sy;
00991        Vp[j][2] = Vp[j][2]*sz;
00992        j++;
00993      }
00994    }
00995    Transform((long)(n->numU * n->numV),Vp,Vp,Offset,p,t,a,im,ima);
00996 
00997    for(ii=0;ii<n->numV;ii++)
00998    for(jj=0;jj<n->numU-1;jj++){
00999      id1=(ii*(n->numU)+jj);
01000      id2=(ii*(n->numU)+jj+1);
01001      CopyPoint(Vp[id1],v1);
01002      CopyPoint(Vp[id2],v2);
01003      if(in_stage_triview(v1) || in_stage_triview(v2)){
01004        for(i=ifd;i<ild;i++){
01005          GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01006          GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01007          MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01008        }
01009      }
01010    }
01011    for(jj=0;jj<n->numU;jj++)
01012    for(ii=0;ii<n->numV-1;ii++){
01013      id1=(ii*(n->numU)+jj);
01014      id2=((ii+1)*(n->numU)+jj);
01015      CopyPoint(Vp[id1],v1);
01016      CopyPoint(Vp[id2],v2);
01017      if(in_stage_triview(v1) || in_stage_triview(v2)){
01018        for(i=ifd;i<ild;i++){
01019          GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01020          GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01021          MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01022        }
01023      }
01024    }
01025    X__Free(Vp);
01026  }
01027  return OK;
01028 }
01029 
01030 static void DrawRect(HDC hdc[],point Offset, double p, double t, double a,
01031               short im, double ima, double scalex, double scaley){
01032  int sh1,sv1,sh2,sv2,i;
01033  point v1,v2;
01034  point Lpointer[4];
01035  short ep;
01036  int ifd,ild;
01037  if(View == TRIVIEW){ifd=0;ild=3;}
01038  else               {ifd=ActiveView; ild=ifd+1;}
01039  for(i=0;i<4;i++)ScalePoint(scalex,scaley,1.0,Rectang[i],Lpointer[i]);
01040  Transform(4,Lpointer,trpoints,Offset,p,t,a,im,ima);
01041  for(ep=0;ep<4;ep++){
01042    CopyPoint(trpoints[rp1[ep]],v1);
01043    CopyPoint(trpoints[rp2[ep]],v2);
01044    if(in_stage_triview(v1) || in_stage_triview(v2)){
01045      for(i=ifd;i<ild;i++){
01046        GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01047        GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01048        MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01049      }
01050    }
01051  }
01052 }
01053 
01054 static void DrawGround(HDC hdc[], point v1
01055                 ,double p, double t, double a, short im
01056                 ,double ima, short status, double scalex, double scaley
01057                 ,double scalez){
01058  RECT rc;
01059  int sh1,sv1,i;
01060  int ifd,ild;
01061  if(View == TRIVIEW){ifd=0;ild=3;}
01062  else               {ifd=ActiveView; ild=ifd+1;}
01063  if(status == DESELECTED)
01064     DrawActorCentre(hdc,v1,p,t,a,im,ima,TVsizeX/24);
01065 // if     (status == SELECTED)_setcolor(Col_ase);
01066 // else                       _setcolor(Col_ade);
01067  if(status == SELECTED)
01068     DrawRect(hdc,v1,p,0.0,0.0,im,ima,scalex,scaley);
01069  for(i=ifd;i<ild;i++)if(i != TRITOP){
01070    GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01071    MoveToEx(hdc[i],0,sv1,NULL);
01072    GetClientRect(ghwnd_triview[i],&rc);
01073    LineTo(hdc[i],rc.right+1,sv1);
01074    if(status == SELECTED){
01075      MoveToEx(hdc[i],sh1,sv1,NULL);
01076      GetWindowCoords(i,v1[0],v1[1],v1[2]+(long)(UNIT*2*scalez),&sh1,&sv1);
01077      LineTo(hdc[i],sh1,sv1);
01078    }
01079  }
01080 }
01081 
01082 static void DrawActorBitmap(HDC hdc[], point v1,
01083                 double p, double t, double a, short im, double ima,
01084                 short status, short what_icon){
01085  int sh1,sv1,i,c;
01086  HDC hMemDC;
01087  HBITMAP hbmOld;
01088  HBRUSH holdbrush;
01089  int ifd,ild;
01090  if(View == TRIVIEW){ifd=0;ild=3;}
01091  else               {ifd=ActiveView; ild=ifd+1;}
01092  if(ghCameraBitmap == NULL || ghLightBitmap == NULL)return;
01093  for(i=ifd;i<ild;i++){
01094    hMemDC = CreateCompatibleDC(hdc[i]);
01095    GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01096    if(what_icon == 0){ /* draw Camera icon */
01097      hbmOld = SelectObject(hMemDC,ghCameraBitmap);  c=32;
01098    }
01099    else if(what_icon == 1){ /* Light */
01100      hbmOld = SelectObject(hMemDC,ghLightBitmap); c=16;
01101    }
01102    if(tool != NOTOOL && tool != NODETOOL &&
01103       tool != PAN && tool != INZOOM && status == SELECTED){
01104      BitBlt(hdc[i],sh1-c/2,sv1-16,c,16,hMemDC,0,0,SRCINVERT);
01105    }
01106    else{
01107      BitBlt(hdc[i],sh1-c/2,sv1-16,c,16,hMemDC,0,0,0x00220326); /*  DSna */
01108      if(status == SELECTED)holdbrush=SelectObject(hdc[i],ghSelectedBrush);
01109      else                  holdbrush=SelectObject(hdc[i],ghDeselectedBrush);
01110      BitBlt(hdc[i],sh1-c/2,sv1-16,c,16,hMemDC,0,0,0x00ea02e9); /* DPSao */
01111      SelectObject(hdc[i],holdbrush);
01112    }
01113 //   SelectObject(hdc[i],holdbrush);
01114    SelectObject(hMemDC,hbmOld);
01115    DeleteDC(hMemDC);
01116  }
01117 }
01118 
01119 static void DrawAxis(HDC hdc[], point v1, short status){
01120  int sh1,sv1,i;
01121  int ifd,ild;
01122  if(View == TRIVIEW){ifd=0;ild=3;}
01123  else               {ifd=ActiveView; ild=ifd+1;}
01124  for(i=ifd;i<ild;i++){
01125     GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01126     MoveToEx(hdc[i],sh1-5,sv1,NULL); LineTo(hdc[i],sh1+5,sv1);
01127     MoveToEx(hdc[i],sh1,sv1+5,NULL); LineTo(hdc[i],sh1,sv1-5);
01128     MoveToEx(hdc[i],sh1-2,sv1,NULL);
01129     LineTo(hdc[i],sh1,sv1-2); LineTo(hdc[i],sh1+2,sv1);
01130     LineTo(hdc[i],sh1,sv1+2); LineTo(hdc[i],sh1-2,sv1);
01131  }
01132 }
01133 
01134 static void DrawFullObject(HDC hdc[], object *Op, point Offset
01135                , double p, double t, double a, short im, double ima
01136                , double sx, double sy, double sz, short status){
01137  int k,n,sh1,sv1,sh2,sv2,morphflag;
01138  long ep,i,Nv,Nl,Nm,j,id[2],Sz;
01139  point  v1,v2,*Vp;
01140  double mr;
01141  LOGPEN lopn;
01142  int ifd,ild;
01143  if(View == TRIVIEW){ifd=0;ild=3; n=3;}
01144  else               {ifd=ActiveView; ild=ifd+1; n=1;}
01145  morphflag=0;
01146  if(status == SELECTED)GetObject(ghSelectedPen,sizeof(LOGPEN),&lopn);
01147  else                  GetObject(ghDeselectedPen,sizeof(LOGPEN),&lopn);
01148  if(Op->in_ram)Nv=Op->npoints;
01149  else          Nv=0;
01150  if(Op->morph != NO && Op->last != NULL){
01151    morphflag=1;
01152    mr=(double)(Op->lastframe - Op->firstframe+1);
01153    if(Op->lastframe == Nframes)mr += 1.0; /* for loop it end of sequence */
01154    mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
01155    Nm=Op->last->npoints;
01156    if(!Op->last->in_ram || Nm != Nv)morphflag=0;
01157  }
01158  DrawNurbsObject(hdc,Op,Offset,p,t,a,im,ima,sx,sy,sz,status);
01159  Sz=(long)Nv*(long)sizeof(point);
01160  if(Nv > 0){
01161   if((Vp=(point *)X__Malloc((long)Nv*sizeof(point))) != NULL){
01162    for(j=0;j<Nv;j++){
01163      CopyPoint(Op->points[j],Vp[j]);
01164      if(morphflag == 1){
01165        CopyPoint(Op->last->points[j],v1);
01166        Vp[j][0] -= Op->origin[0];
01167        Vp[j][1] -= Op->origin[1];
01168        Vp[j][2] -= Op->origin[2];
01169        v1[0] -= Op->last->origin[0];
01170        v1[1] -= Op->last->origin[1];
01171        v1[2] -= Op->last->origin[2];
01172        Vp[j][0] = (long)((double)(Vp[j][0] - v1[0])*mr + v1[0])*sx;
01173        Vp[j][1] = (long)((double)(Vp[j][1] - v1[1])*mr + v1[1])*sy;
01174        Vp[j][2] = (long)((double)(Vp[j][2] - v1[2])*mr + v1[2])*sz;
01175      }
01176      else{
01177        Vp[j][0] = (Vp[j][0] - Op->origin[0])*sx;
01178        Vp[j][1] = (Vp[j][1] - Op->origin[1])*sy;
01179        Vp[j][2] = (Vp[j][2] - Op->origin[2])*sz;
01180      }
01181    }
01182    Transform(Nv,Vp,Vp,Offset,p,t,a,im,ima);
01183    if(global_quickdraw){
01184      long qstep,kstep;
01185      qstep=max(1,Nv/100);
01186      for(k=0;k<n;k++){
01187        i=order_list[ActiveView][k];
01188        for(j=0;j<Nv;j+=qstep)if(in_stage_triview(Vp[j])){
01189          GetWindowCoords(i,Vp[j][0],Vp[j][1],Vp[j][2],&sh1,&sv1);
01190          MoveToEx(hdc[i],sh1-1,sv1,NULL); LineTo(hdc[i],sh1+2,sv1);
01191          MoveToEx(hdc[i],sh1,sv1-1,NULL); LineTo(hdc[i],sh1,sv1+2);
01192        }
01193        if(tool_move_flag){
01194 //         InvalidateRect(ghwnd_current,NULL,FALSE);
01195 //         UpdateWindow(ghwnd_current);
01196 //         Sleep(0);
01197        }
01198        if(qstep > 1){
01199          if     (Nv <   100)kstep=1;
01200          else if(Nv <  1000)kstep=2;
01201          else if(Nv <  2500)kstep=3;
01202          else if(Nv <  5000)kstep=4;
01203          else if(Nv < 10000)kstep=6;
01204          else               kstep=8;
01205          for(j=0;j<Nv;j+=kstep){
01206            if(j%qstep == 0)continue;
01207            if(in_stage_triview(Vp[j])){
01208              GetWindowCoords(i,Vp[j][0],Vp[j][1],Vp[j][2],&sh1,&sv1);
01209              MoveToEx(hdc[i],sh1-1,sv1,NULL); LineTo(hdc[i],sh1+2,sv1);
01210              MoveToEx(hdc[i],sh1,sv1-1,NULL); LineTo(hdc[i],sh1,sv1+2);
01211              if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE
01212                 &&  CheckInterrupt()){
01213 //               InvalidateRect(ghwnd_current,NULL,FALSE);
01214 //               UpdateWindow(ghwnd_current);
01215 //               Sleep(0);
01216                goto ABORT;
01217              }
01218            }
01219          }
01220          if(tool_move_flag){
01221 //           InvalidateRect(ghwnd_current,NULL,FALSE);
01222 //           UpdateWindow(ghwnd_current);
01223 //           Sleep(0);
01224          }
01225        }
01226        if(zoom_abort == 1){
01227 //         InvalidateRect(ghwnd_current,NULL,FALSE);
01228 //         UpdateWindow(ghwnd_current);
01229 //         Sleep(0);
01230          goto ABORT;
01231        }
01232      }
01233      goto ABORT;
01234    }
01235    if(Op->in_ram)Nl=Op->nedges; else Nl=0;
01236    if(Nl > 0){
01237      long qstep,kstep;
01238      if(Preferences.detail_auto){
01239        if     (Nl <   100)kstep=1;
01240        else if(Nl <  1000)kstep=2;
01241        else if(Nl <  2500)kstep=3;
01242        else if(Nl <  5000)kstep=4;
01243        else if(Nl < 10000)kstep=6;
01244        else               kstep=8;
01245      }
01246      else{
01247       kstep=max(1,Preferences.detail_step);
01248      }
01249      qstep=0;
01250      for(ep=0;ep<Nl;ep+=kstep){ /* draw edges */
01251        id[0]=Op->edges[ep][0];
01252        id[1]=Op->edges[ep][1];
01253        CopyPoint(Vp[id[0]],v1);
01254        CopyPoint(Vp[id[1]],v2);
01255        if(in_stage_triview(v1) || in_stage_triview(v2)){
01256 //         for(i=ifd;i<ild;i++){
01257          for(k=0;k<n;k++){
01258            i=order_list[ActiveView][k];
01259            GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01260            GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01261            if(abs(sh1-sh2) < 4 && abs(sv1-sv2) < 4){
01262              MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh1+1,sv1);
01263            }
01264            else {
01265              MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01266            }
01267          }
01268          if(HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE
01269            &&  CheckInterrupt())goto ABORT;
01270        }
01271        if(qstep == 50 && tool_move_flag){
01272 //         InvalidateRect(ghwnd_current,NULL,FALSE);
01273 //         UpdateWindow(ghwnd_current);
01274 //         Sleep(0);
01275        }
01276        qstep++;
01277      }
01278      if(tool_move_flag){
01279 //       InvalidateRect(ghwnd_current,NULL,FALSE);
01280 //       UpdateWindow(ghwnd_current);
01281 //       Sleep(0);
01282      }
01283    }
01284    ABORT:
01285    X__Free(Vp);
01286   }
01287  }
01288 }
01289 
01290 static void DrawCameraFOV(HDC hdc[], short status, node *Np, short al_type,
01291                           point Offset, point TrackedOffset,
01292                           double p, double t, double a,
01293                           short im, double ima,
01294                           double sx, double sy, double sz){
01295  HPEN   hOldPen[3];
01296  COLORREF OldColour[3];
01297  int    OldMode[3];
01298  int sh1,sv1,sh2,sv2,i;
01299  static short ccep1[8]={0,1,2,3,4,4,4,4};
01300  static short ccep2[8]={1,2,3,0,0,1,2,3};
01301  point v1,v2;
01302  point Lcone[4];
01303  short ep;
01304  double d,r,asp;
01305  int ifd,ild;
01306  if(View == TRIVIEW){ifd=0;ild=3;}
01307  else               {ifd=ActiveView; ild=ifd+1;}
01308  if(al_type != TRACK){
01309    d=(double)(TVsizeX)*0.4;
01310  }
01311  else{
01312    SubPoints(Offset,TrackedOffset,v1);
01313    d=sqrt((double)v1[0]*(double)v1[0]+
01314           (double)v1[1]*(double)v1[1]+
01315           (double)v1[2]*(double)v1[2]);
01316  }
01317  r=d*0.42/sx;        /* 0.42 with sx=1 => 50 mm lenz in 3DS setup */
01318  asp=r*sx/sy*0.75;   /* 0.75 is for 1.333 ratio */
01319  for(i=0;i<4;i++)Lcone[i][1]=d;
01320  Lcone[0][0]= (long)r;  Lcone[0][2]= (long)asp;
01321  Lcone[1][0]=-(long)r;  Lcone[1][2]= (long)asp;
01322  Lcone[2][0]=-(long)r;  Lcone[2][2]=-(long)asp;
01323  Lcone[3][0]= (long)r;  Lcone[3][2]=-(long)asp;
01324  CopyPoint(Offset,trpoints[4]);
01325  Transform(4,Lcone,trpoints,Offset,p,t,a,im,ima);
01326  if(tool != NOTOOL && tool != NODETOOL &&
01327     tool != PAN && tool != INZOOM && Np == SelectedNode){
01328    for(i=ifd;i<ild;i++){
01329     OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01330 //     OldColour[i]=SetBkColor(hdc[i],RGB(0,0,0));
01331      hOldPen[i]=SelectObject(hdc[i],ghDotInvertPen);
01332    }
01333  }
01334  else{
01335    for(i=ifd;i<ild;i++)OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01336    //OldColour[i]=SetBkColor(hdc[i],gScreenColourRef);
01337    if(status == SELECTED){
01338      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotSelectedPen);
01339    }
01340    else{
01341      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotDeselectedPen);
01342    }
01343  }
01344  for(ep=0;ep<8;ep++){
01345   CopyPoint(trpoints[ccep1[ep]],v1);
01346   CopyPoint(trpoints[ccep2[ep]],v2);
01347   if(in_stage_triview(v1) || in_stage_triview(v2)){
01348     for(i=ifd;i<ild;i++){
01349       GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01350       GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01351       MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01352     }
01353   }
01354  }
01355  for(i=ifd;i<ild;i++){
01356    SelectObject(hdc[i],hOldPen[i]);
01357    SetBkMode(hdc[i],OldMode[i]);
01358 //   SetBkColor(hdc[i],OldColour[i]);
01359  }
01360 }
01361 
01362 static void DrawLightCone(HDC hdc[], short status, node *Np, short type,
01363                           point Offset, point TrackedOffset,
01364                           double p, double t, double a,
01365                           short im, double ima, double cone, double edge){
01366  HPEN   hOldPen[3];
01367  COLORREF OldColour[3];
01368  int OldMode[3];
01369  int sh1,sv1,sh2,sv2,i;
01370  static short lcep1[16]={0,1,2,3,4,5,6,7,8, 9,10,11,12,12,12,12};
01371  static short lcep2[16]={1,2,3,4,5,6,7,8,9,10,11, 0, 0, 3, 6, 9};
01372  static double LconeX[12]={ 1.000, 0.866, 0.500, 0.000,-0.500,-0.866,
01373                            -1.000,-0.866,-0.500, 0.000, 0.500, 0.866};
01374  static double LconeY[12]={ 0.000, 0.500, 0.866, 1.000, 0.866, 0.500,
01375                             0.000,-0.500,-0.866,-1.000,-0.866,-0.500};
01376  point v1,v2;
01377  point Lcone[12];
01378  short ep;
01379  double d,r;
01380  int ifd,ild;
01381  if(View == TRIVIEW){ifd=0;ild=3;}
01382  else               {ifd=ActiveView; ild=ifd+1;}
01383  if(type != TRACK){
01384    d=(double)TVsizeX/2;
01385  }
01386  else{
01387    SubPoints(Offset,TrackedOffset,v1);
01388    d=sqrt((double)v1[0]*(double)v1[0]+
01389           (double)v1[1]*(double)v1[1]+
01390           (double)v1[2]*(double)v1[2]);
01391  }
01392  r=d*tan(cone/360.0*PI);
01393  for(i=0;i<12;i++){
01394   Lcone[i][1]=d;
01395   Lcone[i][0]=(long)(r*LconeX[i]); Lcone[i][2]=(long)(r*LconeY[i]);
01396  }
01397  CopyPoint(Offset,trpoints[12]);
01398  Transform(12,Lcone,trpoints,Offset,p,t,a,im,ima);
01399  if(tool != NOTOOL && tool != NODETOOL &&
01400     tool != PAN && tool != INZOOM && Np == SelectedNode){
01401    for(i=ifd;i<ild;i++){
01402 //     OldColour[i]=SetBkColor(hdc[i],RGB(0,0,0));
01403      OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01404      hOldPen[i]=SelectObject(hdc[i],ghDotInvertPen);
01405    }
01406  }
01407  else{
01408    for(i=ifd;i<ild;i++)OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01409 //   OldColour[i]=SetBkColor(hdc[i],gScreenColourRef);
01410    if(status == SELECTED){
01411      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotSelectedPen);
01412    }
01413    else{
01414      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotDeselectedPen);
01415    }
01416  }
01417  for(ep=0;ep<16;ep++){
01418   CopyPoint(trpoints[lcep1[ep]],v1);
01419   CopyPoint(trpoints[lcep2[ep]],v2);
01420   if(in_stage_triview(v1) || in_stage_triview(v2)){
01421     for(i=ifd;i<ild;i++){
01422       GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01423       GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01424       MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01425     }
01426   }
01427  }
01428  for(i=ifd;i<ild;i++){
01429    SetBkMode(hdc[i],OldMode[i]);
01430    SelectObject(hdc[i],hOldPen[i]);
01431 //   SetBkColor(hdc[i],OldColour[i]);
01432  }
01433 }
01434 
01435 static void DrawLightExtent(HDC hdc[], short status, node *Np, short type,
01436                           point vc, double sz){
01437  HPEN   hOldPen[3];
01438  COLORREF OldColour[3];
01439  HBRUSH hOldBrush[3];
01440  int OldMode[3];
01441  int sh1,sv1,sh2,sv2,s;
01442  int i,ifd,ild;
01443  point vmx,vmn;
01444  if(View == TRIVIEW){ifd=0;ild=3;}
01445  else               {ifd=ActiveView; ild=ifd+1;}
01446  if(tool != NOTOOL && tool != NODETOOL &&
01447     tool != PAN && tool != INZOOM && Np == SelectedNode){
01448    for(i=ifd;i<ild;i++){
01449 //     OldColour[i]=SetBkColor(hdc[i],RGB(0,0,0));
01450      OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01451      hOldPen[i]=SelectObject(hdc[i],ghDotInvertPen);
01452      hOldBrush[i]=SelectObject(hdc[i],GetStockObject(NULL_BRUSH));
01453    }
01454  }
01455  else{
01456    for(i=ifd;i<ild;i++){
01457      OldMode[i]=SetBkMode(hdc[i],TRANSPARENT);
01458 //     OldColour[i]=SetBkColor(hdc[i],gScreenColourRef);
01459      hOldBrush[i]=SelectObject(hdc[i],GetStockObject(NULL_BRUSH));
01460    }
01461    if(status == SELECTED){
01462      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotSelectedPen);
01463    }
01464    else{
01465      for(i=ifd;i<ild;i++)hOldPen[i]=SelectObject(hdc[i],ghDotDeselectedPen);
01466    }
01467  }
01468  vmn[0]=vc[0]-sz*(double)UNIT;
01469  vmn[1]=vc[1]-sz*(double)UNIT;
01470  vmn[2]=vc[2]-sz*(double)UNIT;
01471  vmx[0]=vc[0]+sz*(double)UNIT;
01472  vmx[1]=vc[1]+sz*(double)UNIT;
01473  vmx[2]=vc[2]+sz*(double)UNIT;
01474  for(i=ifd;i<ild;i++){
01475    GetWindowCoords(i,vmn[0],vmn[1],vmn[2],&sh1,&sv1);
01476    GetWindowCoords(i,vmx[0],vmx[1],vmx[2],&sh2,&sv2);
01477    if(sh1 > sh2){s=sh2; sh2=sh1; sh1=s;}
01478    if(sv1 > sv2){s=sv2; sv2=sv1; sv1=s;}
01479    if((sh1 > 0 && sh1 < WindowSizeX[i]) ||
01480       (sh2 > 0 && sh2 < WindowSizeX[i]) ||
01481       (sv1 > 0 && sv1 < WindowSizeY[i]) ||
01482       (sv2 > 0 && sv2 < WindowSizeY[i]))
01483      Ellipse(hdc[i],sh1,sv1,sh2,sv2);
01484  }
01485  for(i=ifd;i<ild;i++){
01486    SelectObject(hdc[i],hOldPen[i]);
01487    SelectObject(hdc[i],hOldBrush[i]);
01488    SetBkMode(hdc[i],OldMode[i]);
01489 //   SetBkColor(hdc[i],OldColour[i]);
01490  }
01491 }
01492 
01493 #define NP Op->w_frame.Np
01494 #define NE Op->w_frame.Ne
01495 static short DrawQuickObject(HDC hdc[], object *Op, point Offset
01496                    , double p, double t, double a
01497                    , short im, double ima
01498                    , double sx, double sy, double sz, short status){
01499  int sh1,sv1,sh2,sv2;
01500  point  v1,v2,*Vp;
01501  long i,j,ep,id1,id2;
01502  double mr;
01503  int ifd,ild;
01504  if(View == TRIVIEW){ifd=0;ild=3;}
01505  else               {ifd=ActiveView; ild=ifd+1;}
01506  if(Op->w_frame.p == NULL || Op->w_frame.e == NULL ||
01507     NP == 0 || NE == 0)return FAIL;
01508  if((Vp=(point *)X__Malloc((NP)*sizeof(point))) == NULL)return FAIL;
01509  if(Op->morph != NO && Op->last != NULL && Op->last->w_frame.p != NULL &&
01510     Op->w_frame.Np == Op->last->w_frame.Np){
01511    mr=(double)(Op->lastframe - Op->firstframe+1);
01512    mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
01513    for(j=0;j<NP;j++){
01514      CopyPoint(Op->w_frame.p[j],Vp[j]);
01515      CopyPoint(Op->last->w_frame.p[j],v1);
01516      Vp[j][0] = (long)((double)(Vp[j][0] - v1[0])*mr + v1[0])*sx;
01517      Vp[j][1] = (long)((double)(Vp[j][1] - v1[1])*mr + v1[1])*sy;
01518      Vp[j][2] = (long)((double)(Vp[j][2] - v1[2])*mr + v1[2])*sz;
01519    }
01520  }
01521  else{
01522   for(j=0;j<NP;j++){
01523     CopyPoint(Op->w_frame.p[j],Vp[j]);
01524     Vp[j][0] = Vp[j][0]*sx;
01525     Vp[j][1] = Vp[j][1]*sy;
01526     Vp[j][2] = Vp[j][2]*sz;
01527   }
01528  }
01529  Transform((long)(NP),Vp,Vp,Offset,p,t,a,im,ima);
01530  for(ep=0;ep<NE;ep++){
01531    id1=Op->w_frame.e[ep][0]; id2=Op->w_frame.e[ep][1];
01532    CopyPoint(Vp[id1],v1);
01533    CopyPoint(Vp[id2],v2);
01534    if(in_stage_triview(v1) || in_stage_triview(v2)){
01535      for(i=ifd;i<ild;i++){
01536        GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
01537        GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
01538        MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
01539      }
01540    }
01541  }
01542  X__Free(Vp);
01543  return OK;
01544 }
01545 
01546 
01547 int CheckBoundingObject(int type, int ifd, int hx, int vy,
01548                object *Op, point Offset, double p,
01549                double t, double a, short im, double ima,
01550                double sx, double sy, double sz, double *dc){
01551  int sh1,sv1,sh2,sv2,i,j,ep,id1,id2;
01552  point  v1,v2,*Vp;
01553  double mr;
01554  if(type == 1){ /* check full */
01555    int morphflag;
01556    long ep,i,Nv,Nl,Nm,j,id[2],Sz;
01557    morphflag=0;
01558    if(Op->in_ram)Nv=Op->npoints;
01559    else          Nv=0;
01560    if(Op->morph != NO && Op->last != NULL){
01561      morphflag=1;
01562      mr=(double)(Op->lastframe - Op->firstframe+1);
01563      if(Op->lastframe == Nframes)mr += 1.0; /* for loop it end of sequence */
01564      mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
01565      Nm=Op->last->npoints;
01566      if(!Op->last->in_ram || Nm != Nv)morphflag=0;
01567    }
01568    Sz=(long)Nv*(long)sizeof(point);
01569    if(Nv > 0){
01570      if((Vp=(point *)X__Malloc((long)Nv*sizeof(point))) != NULL){
01571        for(j=0;j<Nv;j++){
01572          CopyPoint(Op->points[j],Vp[j]);
01573          if(morphflag == 1){
01574            CopyPoint(Op->last->points[j],v1);
01575            Vp[j][0] -= Op->origin[0];
01576            Vp[j][1] -= Op->origin[1];
01577            Vp[j][2] -= Op->origin[2];
01578            v1[0] -= Op->last->origin[0];
01579            v1[1] -= Op->last->origin[1];
01580            v1[2] -= Op->last->origin[2];
01581            Vp[j][0] = (long)((double)(Vp[j][0] - v1[0])*mr + v1[0])*sx;
01582            Vp[j][1] = (long)((double)(Vp[j][1] - v1[1])*mr + v1[1])*sy;
01583            Vp[j][2] = (long)((double)(Vp[j][2] - v1[2])*mr + v1[2])*sz;
01584          }
01585          else{
01586            Vp[j][0] = (Vp[j][0] - Op->origin[0])*sx;
01587            Vp[j][1] = (Vp[j][1] - Op->origin[1])*sy;
01588            Vp[j][2] = (Vp[j][2] - Op->origin[2])*sz;
01589          }
01590        }
01591        Transform(Nv,Vp,Vp,Offset,p,t,a,im,ima);
01592        if(global_quickdraw){
01593          for(j=0;j<Nv;j++)if(in_stage_triview(Vp[j])){
01594            GetWindowCoords(ifd,Vp[j][0],Vp[j][1],Vp[j][2],&sh1,&sv1);
01595            if(CheckClosestObject(ifd,dc,Vp[j],hx,vy,4)){
01596              X__Free(Vp);
01597              return 1;
01598            }
01599          }
01600          X__Free(Vp);
01601          return 0;
01602        }
01603        if(Op->in_ram)Nl=Op->nedges; else Nl=0;
01604        if(Nl > 0) for(ep=0;ep<Nl;ep++){
01605          id[0]=Op->edges[ep][0];
01606          id[1]=Op->edges[ep][1];
01607          CopyPoint(Vp[id[0]],v1);
01608          CopyPoint(Vp[id[1]],v2);
01609          if(in_stage_triview(v1) || in_stage_triview(v2)){
01610            GetWindowCoords(ifd,v1[0],v1[1],v1[2],&sh1,&sv1);
01611            GetWindowCoords(ifd,v2[0],v2[1],v2[2],&sh2,&sv2);
01612            if(OnModelEdge(hx,vy,sh1,sv1,sh2,sv2,v1,v2,dc)){
01613              X__Free(Vp);
01614              return 1;
01615            }
01616          }
01617        }
01618        X__Free(Vp);
01619      }
01620    }
01621    return 0;
01622  }
01623  if(Op->w_frame.p == NULL || Op->w_frame.e == NULL ||
01624     NP == 0 || NE == 0)goto BBOX;
01625  if((Vp=(point *)X__Malloc((NP)*sizeof(point))) == NULL)goto BBOX;
01626  if(Op->morph != NO && Op->last != NULL && Op->last->w_frame.p != NULL &&
01627     Op->w_frame.Np == Op->last->w_frame.Np){
01628    mr=(double)(Op->lastframe - Op->firstframe+1);
01629    mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
01630    for(j=0;j<NP;j++){
01631      CopyPoint(Op->w_frame.p[j],Vp[j]);
01632      CopyPoint(Op->last->w_frame.p[j],v1);
01633      Vp[j][0] = (long)((double)(Vp[j][0] - v1[0])*mr + v1[0])*sx;
01634      Vp[j][1] = (long)((double)(Vp[j][1] - v1[1])*mr + v1[1])*sy;
01635      Vp[j][2] = (long)((double)(Vp[j][2] - v1[2])*mr + v1[2])*sz;
01636    }
01637  }
01638  else{
01639   for(j=0;j<NP;j++){
01640     CopyPoint(Op->w_frame.p[j],Vp[j]);
01641     Vp[j][0] = Vp[j][0]*sx;
01642     Vp[j][1] = Vp[j][1]*sy;
01643     Vp[j][2] = Vp[j][2]*sz;
01644   }
01645  }
01646  Transform((long)(NP),Vp,Vp,Offset,p,t,a,im,ima);
01647  for(ep=0;ep<NE;ep++){
01648    id1=Op->w_frame.e[ep][0]; id2=Op->w_frame.e[ep][1];
01649    CopyPoint(Vp[id1],v1);
01650    CopyPoint(Vp[id2],v2);
01651    if(in_stage_triview(v1) || in_stage_triview(v2)){
01652      GetWindowCoords(ifd,v1[0],v1[1],v1[2],&sh1,&sv1);
01653      GetWindowCoords(ifd,v2[0],v2[1],v2[2],&sh2,&sv2);
01654      if(OnModelEdge(hx,vy,sh1,sv1,sh2,sv2,v1,v2,dc)){
01655        X__Free(Vp);
01656        return 1;
01657      }
01658    }
01659  }
01660  X__Free(Vp);
01661  return 0;
01662  BBOX:
01663  if(Op->morph != NO && Op->last != NULL){
01664    mr=(double)(Op->lastframe - Op->firstframe+1);
01665    mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
01666    for(i=0;i<8;i++){
01667      srpoints[i][0] = (long)((double)(Op->outline[i][0] -
01668          Op->last->outline[i][0])*mr + Op->last->outline[i][0])*sx;
01669      srpoints[i][1] = (long)((double)(Op->outline[i][1] -
01670          Op->last->outline[i][1])*mr + Op->last->outline[i][1])*sy;
01671      srpoints[i][2] = (long)((double)(Op->outline[i][2] -
01672          Op->last->outline[i][2])*mr + Op->last->outline[i][2])*sz;
01673    }
01674  }
01675  else{
01676    for(i=0;i<8;i++){
01677      srpoints[i][0] = (long)((double)Op->outline[i][0])*sx;
01678      srpoints[i][1] = (long)((double)Op->outline[i][1])*sy;
01679      srpoints[i][2] = (long)((double)Op->outline[i][2])*sz;
01680    }
01681  }
01682  Transform(8,srpoints,trpoints,Offset,p,t,a,im,ima);
01683  for(ep=0;ep<12;ep++){
01684    CopyPoint(trpoints[ep1[ep]],v1);
01685    CopyPoint(trpoints[ep2[ep]],v2);
01686    if(in_stage_triview(v1) || in_stage_triview(v2)) {
01687      GetWindowCoords(ifd,v1[0],v1[1],v1[2],&sh1,&sv1);
01688      GetWindowCoords(ifd,v2[0],v2[1],v2[2],&sh2,&sv2);
01689      if(OnModelEdge(hx,vy,sh1,sv1,sh2,sv2,v1,v2,dc))return 1;
01690    }
01691  }
01692  return 0;
01693 }
01694 
01695 static int OnModelEdge(int npx, int npy,
01696                        int sh1, int sv1, int sh2, int sv2,
01697                        point vp1, point vp2,
01698                        double *dc){
01699  int i,found=0;
01700  double x,y,z,mu,a,b,c,d;
01701  a=(double)(sh2-sh1); b=(double)(sv2-sv1);
01702  if((sh2-sh1) != 0 ||  (sv2-sv1) != 0){
01703    x=(double)npx; y=(double)npy;
01704    mu=(a*(x-(double)sh1) + b*(y-(double)sv1))/(a*a+b*b);
01705    if(mu > 0.0001 && mu < 0.9999){
01706      x=a*mu+(double)sh1; y=b*mu+(double)sv1;
01707      sh1=(int)x; sv1=(int)y;
01708      if(abs(npx-sh1) < 4 && abs(npy-sv1) < 4){/* in 2D range */
01709        a=(double)(vp2[0]-vp1[0]);
01710        b=(double)(vp2[1]-vp1[1]);
01711        c=(double)(vp2[2]-vp1[2]);
01712        mu=(a*((double)NpointerX-(double)(vp1[0]))
01713           +b*((double)NpointerY-(double)(vp1[1]))
01714           +c*((double)NpointerZ-(double)(vp1[2])))/(a*a+b*b+c*c);
01715        x=a*mu+(double)(vp1[0]);
01716        y=b*mu+(double)(vp1[1]);
01717        z=c*mu+(double)(vp1[2]);
01718        d=(x-(double)NpointerX)*(x-(double)NpointerX)
01719         +(y-(double)NpointerY)*(y-(double)NpointerY)
01720         +(z-(double)NpointerZ)*(z-(double)NpointerZ);
01721        if(d < *dc){/* closest in 3D */
01722          *dc=d;
01723          found=1;
01724        }
01725      }
01726    }
01727  }
01728  return found;
01729 }
01730 
01731 #undef NP
01732 #undef NE
01733 
01734 // end of draw actor functions
01735 //
01736 
01737 void DrawNode(HDC hDC[], node *Np, short status){
01738  point  ObjectOffset,TrackedOffset;
01739  object *Op;
01740  short im,al_type;
01741  double phi,theta,alpha,sx,sy,sz,ima;
01742  if((Op=Np->fobj) != NULL)while(Op != NULL){
01743   if((CurrentFrame >= Op->firstframe) && (CurrentFrame <= Op->lastframe)){
01744    al_type=GetTransform(0,CurrentFrame,1.0,Np,Op,ObjectOffset,TrackedOffset,
01745                 &phi,&theta,&alpha,&sx,&sy,&sz,&im,&ima);
01746    if((Op->type == PATH) && (Op->firstpathpoint != NULL)){
01747      if(tool == PATHEDITOR && Np == SelectedNode)DrawPath(hDC,
01748        Op,ObjectOffset,phi,theta,alpha,im,ima,EDITING);
01749      else                                        DrawPath(hDC,
01750        Op,ObjectOffset,phi,theta,alpha,im,ima,status);
01751    }
01752    else if(Op->type == NORMAL || Op->type == ANIMOBJ){
01753      if(DrawStatus == 0 || Op->quick_only == 1)
01754        DrawObject(hDC,Op,ObjectOffset,phi,theta,alpha,
01755                   im,ima,sx,sy,sz,status);
01756      else if(DrawStatus == 3 || (DrawStatus == 2 && Np != SelectedNode)
01757                         || (DrawStatus == 1 && Np == SelectedNode))
01758        DrawFullObject(hDC,Op,ObjectOffset,phi,theta,alpha,
01759                       im,ima,sx,sy,sz,status);
01760      else  DrawObject(hDC,Op,ObjectOffset,phi,theta,alpha,
01761                       im,ima,sx,sy,sz,status);
01762    }
01763    else if(Op->type == PARTICLE)
01764      DrawObject(hDC,Op,ObjectOffset,phi,theta,alpha,
01765                 im,ima,sx,sy,sz,status);
01766    else if(Op->type == CAMERA){
01767      DrawActorBitmap(hDC,ObjectOffset,
01768                      phi,theta,alpha,0,0.0,status,0);
01769      if(show_camera_fov)DrawCameraFOV(hDC,status,Np,al_type,
01770                                       ObjectOffset,TrackedOffset,
01771                                       phi,theta,alpha,im,ima,sx,sy,sz);
01772      else DrawArrow(hDC,ObjectOffset,
01773                     phi,theta,alpha,im,ima,TVsizeX/20);
01774    }
01775    else if(Op->type == LIGHT){
01776      DrawActorBitmap(hDC,ObjectOffset,
01777                      phi,theta,alpha,im,ima,status,1);
01778      if(Op->lighttype == SPOTLIGHT){
01779        if(show_light_cones)DrawLightCone(hDC,status,Np,al_type,
01780                                          ObjectOffset,TrackedOffset,
01781                                          phi,theta,alpha,im,ima,sx,sy);
01782        else DrawArrow(hDC,ObjectOffset,
01783                       phi,theta,alpha,im,ima,TVsizeX/20);
01784      }
01785      if(Op->depth_cue && show_light_cones)
01786        DrawLightExtent(hDC,status,Np,al_type,ObjectOffset,sz);
01787    }
01788    else if(Op->type == GROUND)DrawGround(hDC,
01789      ObjectOffset,phi,theta,alpha,im,ima,status,sx,sy,sz);
01790    else if(Op->type == TARGET)DrawAxis(hDC,
01791      ObjectOffset,status);
01792    else if(Op->type == ROBOT){
01793      if(DrawStatus == 3 || (DrawStatus == 2 && Np != SelectedNode)
01794                         || (DrawStatus == 1 && Np == SelectedNode))
01795            DrawFullRobot(hDC,
01796                          Op,ObjectOffset,phi,theta,alpha,
01797                          im,ima,sx,sy,sz,status);
01798      else  DrawRobot(    hDC,
01799                          Op,ObjectOffset,phi,theta,alpha,
01800                          im,ima,sx,sy,sz,status);
01801    }
01802   }
01803   Op=Op->next;
01804  }
01805 }
01806 
01807 void DrawInvertNode(HDC hDC[], node *Np, short status){
01808  int i,oldROP[3];
01809  int ifd,ild;
01810  if(View == TRIVIEW){ifd=0;ild=3;}
01811  else               {ifd=ActiveView; ild=ifd+1;}
01812  if(hDC == NULL){
01813    HDC hdc[3];
01814    for(i=ifd;i<ild;i++){
01815      hdc[i]=GetDC(ghwnd_triview[i]);
01816 //     SelectPalette(hdc[i],ghpaletteScreen,FALSE);
01817      SelectObject(hdc[i],ghInvertPen);
01818      RealizePalette (hdc[i]);
01819      oldROP[i]=SetROP2(hdc[i],R2_XORPEN);
01820    }
01821    DrawNode(hdc,Np,(short)abs(status));
01822    for(i=ifd;i<ild;i++){
01823      SetROP2(hdc[i],oldROP[i]);
01824      ReleaseDC(ghwnd_triview[i],hdc[i]);
01825    }
01826  }
01827  else{
01828    for(i=ifd;i<ild;i++){
01829      if(hDC[i] == NULL)return;
01830      oldROP[i]=SetROP2(hDC[i],R2_XORPEN);
01831    }
01832    DrawNode(hDC,Np,(short)abs(status));
01833    for(i=ifd;i<ild;i++){
01834      SetROP2(hDC[i],oldROP[i]);
01835      if(status >= 0)InvalidateRect(ghwnd_triview[i],NULL,FALSE);
01836    }
01837  }
01838 }
01839 
01840 void ReDrawStageDisplay(BOOL draw_selected){
01841  int i,oldROP[3];
01842  node     *Np;
01843  RECT rc;
01844  HDC hdc;
01845  int ifd,ild;
01846  HCURSOR lhcurSave;
01847  zoom_abort=0;
01848  if(View == TRIVIEW){ifd=0;ild=3;}
01849  else               {ifd=ActiveView; ild=ifd+1;}
01850  for(i=ifd;i<ild;i++){
01851    if(ghdc_triview_Bitmap[i] == NULL)return;
01852    if(ghbm_triview[i] == NULL)return;
01853    GetClientRect(ghwnd_triview[i],&rc);
01854    PatBlt(ghdc_triview_Bitmap[i],0,0,rc.right,rc.bottom,PATCOPY);
01855    SelectObject(ghdc_triview_Bitmap[i],ghDeselectedPen);
01856  }
01857  if(DrawStatus > 0 && global_quickdraw == 0)lhcurSave=SetCursor(ghcurWait);
01858  if(/*grid_on &&*/ draw_grid_on)DrawGrid(ghdc_triview_Bitmap);
01859  if((Np=FirstNp) != NULL)while(Np != NULL){
01860    if(Np != SelectedNode && Np->type != NORMAL && Np->type != ANIMOBJ){
01861      DrawNode(ghdc_triview_Bitmap,Np,DESELECTED);
01862    }
01863    Np=Np->next;
01864  }
01865  if((Np=FirstNp) != NULL)while(Np != NULL){
01866    if(Np != SelectedNode && (Np->type == NORMAL || Np->type == ANIMOBJ)){
01867      DrawNode(ghdc_triview_Bitmap,Np,DESELECTED);
01868    }
01869    Np=Np->next;
01870  }
01871  if(SelectedNode != NULL){
01872    if(tool != NOTOOL && tool != NODETOOL &&
01873       tool != PAN && tool != INZOOM){
01874      for(i=ifd;i<ild;i++){
01875        SelectObject(ghdc_triview_Bitmap[i],ghInvertPen);
01876        oldROP[i]=SetROP2(ghdc_triview_Bitmap[i],R2_XORPEN);
01877      }
01878    }
01879    else{
01880      for(i=ifd;i<ild;i++){
01881        SelectObject(ghdc_triview_Bitmap[i],ghSelectedPen);
01882      }
01883    }
01884    if(tool == PATHEDITOR)DrawNode(ghdc_triview_Bitmap,SelectedNode,EDITING);
01885    else if(draw_selected)DrawNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
01886    if(tool == TRACKER && subtool == SHIFTER)DrawActorTrack(ghdc_triview_Bitmap,0);
01887    if(tool == TRACKER && subtool == ANGLER )DrawActorRotations(ghdc_triview_Bitmap,0);
01888    if(tool != NOTOOL && tool != NODETOOL &&
01889       tool != PAN && tool != INZOOM)
01890      for(i=ifd;i<ild;i++)SetROP2(ghdc_triview_Bitmap[i],oldROP[i]);
01891  }
01892  for(i=ifd;i<ild;i++)DrawArrowIcons(ghdc_triview_Bitmap[i],i);
01893  if(DrawStatus > 0 && global_quickdraw == 0)SetCursor(lhcurSave);
01894  for(i=ifd;i<ild;i++){
01895    InvalidateRect(ghwnd_triview[i],NULL,FALSE);
01896    UpdateWindow(ghwnd_triview[i]);
01897  }
01898  return;
01899 }
01900 
01901 void ReDrawQuickDisplay(BOOL draw_selected){
01902  /* draw directly onto window surface */
01903  int i,oldROP[3];
01904  node     *Np;
01905  RECT rc;
01906  HDC hDC[3];
01907  HBRUSH hOldBrush[3];
01908  int ifd,ild;
01909  zoom_abort=0;
01910  if(View == TRIVIEW){ifd=0;ild=3;}
01911  else               {ifd=ActiveView; ild=ifd+1;}
01912  for(i=ifd;i<ild;i++){
01913    hDC[i]=GetDC(ghwnd_triview[i]);
01914    if(hDC[i] == NULL)return;
01915 //   SelectPalette(hDC[i],ghpaletteScreen,FALSE);
01916    hOldBrush[i]=SelectObject(hDC[i],ghbrushWindow);
01917    RealizePalette(hDC[i]);
01918    GetClientRect(ghwnd_triview[i],&rc);
01919    PatBlt(hDC[i],0,0,rc.right,rc.bottom,PATCOPY);
01920    DrawArrowIcons(hDC[i],i);
01921    SelectObject(hDC[i],ghDeselectedPen);
01922  }
01923  if(draw_grid_on)DrawGrid(hDC);
01924  if((Np=FirstNp) != NULL)while(Np != NULL){
01925    if(Np != SelectedNode && Np->type != NORMAL && Np->type != ANIMOBJ){
01926      DrawNode(hDC,Np,DESELECTED);
01927    }
01928    Np=Np->next;
01929  }
01930  if(SelectedNode != NULL){
01931    if(tool != NOTOOL && tool != NODETOOL &&
01932       tool != PAN && tool != INZOOM){
01933      for(i=ifd;i<ild;i++){
01934        SelectObject(hDC[i],ghInvertPen);
01935        oldROP[i]=SetROP2(hDC[i],R2_XORPEN);
01936      }
01937    }
01938    else{
01939      for(i=ifd;i<ild;i++){
01940        SelectObject(hDC[i],ghSelectedPen);
01941      }
01942    }
01943    if(tool == PATHEDITOR)DrawNode(hDC,SelectedNode,EDITING);
01944    else if(draw_selected)DrawNode(hDC,SelectedNode,SELECTED);
01945    if(tool == TRACKER && subtool == SHIFTER)DrawActorTrack(hDC,0);
01946    if(tool == TRACKER && subtool == ANGLER )DrawActorRotations(hDC,0);
01947    if(tool != NOTOOL && tool != NODETOOL &&
01948       tool != PAN && tool != INZOOM)
01949      for(i=ifd;i<ild;i++)SetROP2(hDC[i],oldROP[i]);
01950  }
01951  for(i=ifd;i<ild;i++)SelectObject(hDC[i],ghDeselectedPen);
01952  if((Np=FirstNp) != NULL)while(Np != NULL){
01953    if(Np != SelectedNode && (Np->type == NORMAL || Np->type == ANIMOBJ)){
01954      DrawNode(hDC,Np,DESELECTED);
01955 //     if(zoom_abort > 0)goto ABORT;
01956    }
01957    Np=Np->next;
01958  }
01959  if(SelectedNode != NULL){
01960    if(tool != NOTOOL && tool != NODETOOL &&
01961       tool != PAN && tool != INZOOM){
01962      for(i=ifd;i<ild;i++){
01963        SelectObject(hDC[i],ghInvertPen);
01964        oldROP[i]=SetROP2(hDC[i],R2_XORPEN);
01965      }
01966    }
01967    else{
01968      for(i=ifd;i<ild;i++){
01969        SelectObject(hDC[i],ghSelectedPen);
01970      }
01971    }
01972    if(tool == PATHEDITOR)DrawNode(hDC,SelectedNode,EDITING);
01973    else if(draw_selected)DrawNode(hDC,SelectedNode,SELECTED);
01974    if(tool == TRACKER && subtool == SHIFTER)DrawActorTrack(hDC,0);
01975    if(tool == TRACKER && subtool == ANGLER )DrawActorRotations(hDC,0);
01976    if(tool != NOTOOL && tool != NODETOOL &&
01977       tool != PAN && tool != INZOOM)
01978      for(i=ifd;i<ild;i++)SetROP2(hDC[i],oldROP[i]);
01979  }
01980 // ABORT:
01981  for(i=ifd;i<ild;i++){
01982    SelectObject(hDC[i],hOldBrush[i]);
01983    ReleaseDC(ghwnd_triview[i],hDC[i]);
01984  }
01985  return;
01986 }
01987 

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