LENS1.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 // lens1.c   - included in lens.c
00025 
00026 static void  BlurBuffer(fullscreenbuffer *s, long Xmax, long Ymax){
00027   long i,j;
00028   double sum;
00029   for(i=0;i<Ymax-1;i++)for(j=0;j<Xmax-1;j++){
00030     sum  = (double)((s+i*Xmax+j)->R);
00031     sum += (double)((s+i*Xmax+j+1)->R);
00032     sum += (double)((s+(i+1)*Xmax+j)->R);
00033     sum += (double)((s+(i+1)*Xmax+j+1)->R);
00034     (s+i*Xmax+j)->R = (unsigned char)(sum*0.25);
00035     sum  = (double)((s+i*Xmax+j)->G);
00036     sum += (double)((s+i*Xmax+j+1)->G);
00037     sum += (double)((s+(i+1)*Xmax+j)->G);
00038     sum += (double)((s+(i+1)*Xmax+j+1)->G);
00039     (s+i*Xmax+j)->G = (unsigned char)(sum*0.25);
00040     sum  = (double)((s+i*Xmax+j)->B);
00041     sum += (double)((s+i*Xmax+j+1)->B);
00042     sum += (double)((s+(i+1)*Xmax+j)->B);
00043     sum += (double)((s+(i+1)*Xmax+j+1)->B);
00044     (s+i*Xmax+j)->B = (unsigned char)(sum*0.25);
00045   }
00046   return;
00047 }
00048 
00049 static void MixBuffer(fullscreenbuffer *s, fullscreenbuffer *t,
00050                       long Xmax, long Ymax){
00051  int r,g,b;
00052  long i,j;
00053  for(i=0;i<Ymax-1;i++)for(j=0;j<Xmax-1;j++){
00054    r=(int)t->R+(int)s->R;
00055    g=(int)t->G+(int)s->G;
00056    b=(int)t->B+(int)s->B;
00057    t->R=(r>255) ? 255:r;
00058    t->G=(g>255) ? 255:g;
00059    t->B=(b>255) ? 255:b;
00060    s++; t++;
00061  }
00062  return;
00063 }
00064 
00065 double DistFromHidingObject(int x, int y, double d,
00066                             double *Zb,
00067                             int border, int X, int Y){
00068  long i,j;
00069  double e,*Z,dmin,dr;
00070  dmin=(double)(X*10);
00071  for(i=x-border;i<=x+border;i++)for(j=y-border;j<=y+border;j++){
00072    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00073    e = *(Zb + (j * X) + i);
00074    if(e < d){
00075      dr=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00076      if(dr < dmin)dmin=dr;
00077    }
00078  }
00079  return dmin;
00080 }
00081 
00082 double DistFromVisibleObject(int x, int y, double d,
00083                             double *Zb,
00084                             int border, int X, int Y){
00085  long i,j;
00086  double e,*Z,dmin,dr;
00087  dmin=(double)(X*10);
00088  for(i=x-border;i<=x+border;i++)for(j=y-border;j<=y+border;j++){
00089    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00090    e = *(Zb + (j * X) + i);
00091    if(e > d){
00092      dr=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00093      if(dr < dmin)dmin=dr;
00094    }
00095  }
00096  return dmin;
00097 }
00098 
00099 double Grad(double x, double y1, double y2, int x1, int x2){
00100  double g;
00101  if(x <= x1)return y1;
00102  if(x >= x2)return y2;
00103  g=(y2-y1)/(double)(x2-x1);
00104  return y1+g*(x-(double)x1);
00105 }
00106 
00107 void DrawInBuffer(fullscreenbuffer *Screen, int Xmax, int Ymax,
00108                   int x, int y, unsigned char v,
00109                   double rr, double gg, double bb){
00110  int r,g,b;
00111  fullscreenbuffer *S;
00112  if(x < 0 || y < 0 || x >= Xmax || y >= Ymax)return;
00113  S=(Screen+y*Xmax+x);
00114  r=(int)S->R+(int)((double)v*rr);
00115  g=(int)S->G+(int)((double)v*gg);
00116  b=(int)S->B+(int)((double)v*bb);
00117  S->R=(r>255) ? 255:r;
00118  S->G=(g>255) ? 255:g;
00119  S->B=(b>255) ? 255:b;
00120 }
00121 
00122 #define frac(z) fmod(z,1.0)
00123 
00124 void DrawAApixel(double x, double y, double w, double h, double C,
00125                  fullscreenbuffer *S, int X, int Y,
00126                  double r, double g, double b){
00127   int xa,xb,ya,yb,i,j,brite;
00128   double x2,y2,lfrac,rfrac,tfrac,bfrac,xfrac,yfrac;
00129   brite=(int)C;
00130   if(x < 0 || y < 0)return;
00131   x -= w*0.5; y -= h*0.5;
00132   x2 = x + w;
00133   y2 = y + w;
00134   xa = (int)x;
00135   xb = (int)x2;
00136   ya = (int)y;
00137   yb = (int)y2;
00138   lfrac = 1.0-frac(x);
00139   rfrac = frac(x2);
00140   tfrac = 1.0-frac(y);
00141   bfrac = frac(y2);
00142   if (xa==xb) {
00143     xfrac = lfrac+rfrac-1.0;
00144     if (ya==yb) {
00145       DrawInBuffer(S,X,Y,xa,ya,xfrac*(tfrac+bfrac-1.0)*brite,r,g,b);
00146     }
00147     else {
00148       DrawInBuffer(S,X,Y,xa,ya,xfrac*tfrac*brite,r,g,b);
00149       for (j=ya+1; j<yb; j++) DrawInBuffer(S,X,Y,xa,j,xfrac*brite,r,g,b);
00150       DrawInBuffer(S,X,Y,xa,yb,xfrac*bfrac*brite,r,g,b);
00151     }
00152   }
00153   else {
00154     if (ya==yb) {
00155       yfrac = tfrac+bfrac-1.0;
00156       DrawInBuffer(S,X,Y,xa,ya,yfrac*lfrac*brite,r,g,b);
00157       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,ya,yfrac*brite,r,g,b);
00158       DrawInBuffer(S,X,Y,xb,ya,yfrac*rfrac*brite,r,g,b);
00159     }
00160     else {
00161       DrawInBuffer(S,X,Y,xa,ya,tfrac*lfrac*brite,r,g,b);
00162       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,ya,tfrac*brite,r,g,b);
00163       DrawInBuffer(S,X,Y,xb,ya,tfrac*rfrac*brite,r,g,b);
00164       for (j=ya+1; j<yb; j++) {
00165         DrawInBuffer(S,X,Y,xa,j,lfrac*brite,r,g,b);
00166         for (i=xa+1; i<xb; i++)DrawInBuffer(S,X,Y,i,j,brite,r,g,b);
00167         DrawInBuffer(S,X,Y,xb,j,rfrac*brite,r,g,b);
00168       }
00169       DrawInBuffer(S,X,Y,xa,yb,bfrac*lfrac*brite,r,g,b);
00170       for (i=xa+1; i<xb; i++) DrawInBuffer(S,X,Y,i,yb,bfrac*brite,r,g,b);
00171       DrawInBuffer(S,X,Y,xb,yb,bfrac*rfrac*brite,r,g,b);
00172     }
00173   }
00174 }
00175 
00176 #define DIST(i,j)  sqrt((double)i * (double)i + (double)j * (double)j)
00177 
00178 static double GetW(double l, double dx, double dy,
00179                    double Wmin, double Wmax, double iScale,
00180                    BOOL linear){
00181  double d,f;
00182  d=DIST(dx,dy);
00183  f=d/l;
00184  if(linear){
00185    if(f < 0.5)return (Wmin+2.0*f*(Wmax-Wmin))*(double)iScale;
00186    return (Wmin+(Wmax-Wmin)*2.0*(1.0-f))*(double)iScale;
00187  }
00188  else{
00189    double y,dx,dw;
00190    dw=(Wmax-Wmin);
00191    if(f < 0.5)f=1.0-f;
00192    f = 2.0*(f-0.5);
00193    y=Wmax-dw*f*f*f;
00194    return y*(double)iScale;
00195  }
00196  return 0.0;
00197 }
00198 
00199 static double GetC(double l, double dx, double dy,
00200                    double Wmin, double Wmax, double iScale,
00201                    BOOL linear){
00202  double d,f;
00203  d=DIST(dx,dy);
00204  f=d/l;
00205  if(f < 0.5)return Wmax; //(Wmin+2.0*f*(Wmax-Wmin))*(double)iScale;
00206  return (Wmin+(Wmax-Wmin)*2.0*(1.0-f));
00207 }
00208 
00209 static void DrawFlareInBuffer(long x, long y, long idx, long idy,
00210                               fullscreenbuffer *Screen,
00211                               long X, long Y, double iScale,
00212                               double Cin,
00213                               double Wmin, double Wmax,
00214                               double z, float *Zb,
00215                               BOOL bDraw, BOOL linear){
00216  long i,j;
00217  double grad,error,W,l,C;
00218  if(iScale <1.1)Cin *= 2; Cin=min(255,Cin); C=Cin;
00219  if(idx == 0 && idy == 0)return;
00220  l=DIST(idx,idy);
00221  if(abs(idx) >= abs(idy)){
00222    grad=(double)idy/(double)idx; j=y;
00223    if(idy >= 0)error = -0.5; else error = 0.5;
00224    if(idx >= 0){
00225      for(i=x;i<x+idx;i++){
00226        error += grad;
00227        if(idy >= 0){
00228          if(error > 0.0){j++; error -= 1.0;}
00229        }
00230        else{
00231          if(error < 0.0){j--; error += 1.0;}
00232        }
00233        W=GetW(l,(double)(i-x),(double)(j-y),Wmin,Wmax,iScale,linear);
00234        if(!linear)C=GetC(l,(double)(i-x),(double)(j-y),Cin*0.25,Cin,1.0,TRUE);
00235        DrawAApixel((double)i,(double)j,W,W,C,Screen,X,Y,1,1,1);
00236      }
00237    }
00238    else{
00239      for(i=x;i>x+idx;i--){
00240        error -= grad;
00241        if(idy >= 0){
00242          if(error > 0.0){j++; error -= 1.0;}
00243        }
00244        else{
00245          if(error < 0.0){j--; error += 1.0;}
00246        }
00247        W=GetW(l,(double)(i-x),(double)(j-y),Wmin,Wmax,iScale,linear);
00248        if(!linear)C=GetC(l,(double)(i-x),(double)(j-y),Cin*0.25,Cin,1.0,TRUE);
00249        DrawAApixel((double)i,(double)j,W,W,C,Screen,X,Y,1,1,1);
00250      }
00251    }
00252  }
00253  else{
00254    grad=(double)idx/(double)idy; j=x;
00255    if(idx >= 0)error = -0.5; else error = 0.5;
00256    if(idy >= 0){
00257      for(i=y;i<y+idy;i++){
00258        error += grad;
00259        if(idx >= 0){
00260          if(error > 0.0){j++; error -= 1.0;}
00261        }
00262        else{
00263          if(error < 0.0){j--; error += 1.0;}
00264        }
00265        W=GetW(l,(double)(j-x),(double)(i-y),Wmin,Wmax,iScale,linear);
00266        if(!linear)C=GetC(l,(double)(j-x),(double)(i-y),Cin*0.25,Cin,1.0,TRUE);
00267        DrawAApixel((double)j,(double)i,W,W,C,Screen,X,Y,1,1,1);
00268      }
00269    }
00270    else{
00271      for(i=y;i>y+idy;i--){
00272        error -= grad;
00273        if(idx >= 0){
00274          if(error > 0.0){j++; error -= 1.0;}
00275        }
00276        else{
00277          if(error < 0.0){j--; error += 1.0;}
00278        }
00279        W=GetW(l,(double)(j-x),(double)(i-y),Wmin,Wmax,iScale,linear);
00280        if(!linear)C=GetC(l,(double)(j-x),(double)(i-y),Cin*0.25,Cin,1.0,TRUE);
00281        DrawAApixel((double)j,(double)i,W,W,C,Screen,X,Y,1,1,1);
00282      }
00283    }
00284  }
00285  return;
00286 }
00287 
00288 static double GetWL(double l, double dx, double dy,
00289                    double Wmin, double Wmax,
00290                    BOOL linear){
00291  double d,f;
00292  d=DIST(dx,dy);
00293  f=d/l;
00294  return (Wmax-(Wmax-Wmin)*f);
00295 }
00296 
00297 
00298 static void DrawFadedFlareInBuffer(long x, long y, long idx, long idy,
00299                               fullscreenbuffer *Screen,
00300                               long X, long Y,
00301                               double Cin,
00302                               double r, double g, double b,
00303                               double Wmin, double Wmax,
00304                               double z, float *Zb,
00305                               BOOL bDraw, BOOL linear){
00306  long i,j;
00307  double grad,error,W,l,C;
00308  C=Cin;
00309  l=DIST(idx,idy);
00310  if(abs(idx) >= abs(idy)){
00311    grad=(double)idy/(double)idx; j=y;
00312    if(idy >= 0)error = -0.5; else error = 0.5;
00313    if(idx >= 0){
00314      for(i=x;i<x+idx;i++){
00315        error += grad;
00316        if(idy >= 0){
00317          if(error > 0.0){j++; error -= 1.0;}
00318        }
00319        else{
00320          if(error < 0.0){j--; error += 1.0;}
00321        }
00322        W=GetWL(l,(double)(i-x),(double)(j-y),Wmin,Wmax,linear);
00323        DrawAApixel((double)i,(double)j,W,W,C,Screen,X,Y,r,g,b);
00324      }
00325    }
00326    else{
00327      for(i=x;i>x+idx;i--){
00328        error -= grad;
00329        if(idy >= 0){
00330          if(error > 0.0){j++; error -= 1.0;}
00331        }
00332        else{
00333          if(error < 0.0){j--; error += 1.0;}
00334        }
00335        W=GetWL(l,(double)(i-x),(double)(j-y),Wmin,Wmax,linear);
00336        DrawAApixel((double)i,(double)j,W,W,C,Screen,X,Y,r,g,b);
00337      }
00338    }
00339  }
00340  else{
00341    grad=(double)idx/(double)idy; j=x;
00342    if(idx >= 0)error = -0.5; else error = 0.5;
00343    if(idy >= 0){
00344      for(i=y;i<y+idy;i++){
00345        error += grad;
00346        if(idx >= 0){
00347          if(error > 0.0){j++; error -= 1.0;}
00348        }
00349        else{
00350          if(error < 0.0){j--; error += 1.0;}
00351        }
00352        W=GetWL(l,(double)(j-x),(double)(i-y),Wmin,Wmax,linear);
00353        DrawAApixel((double)j,(double)i,W,W,C,Screen,X,Y,r,g,b);
00354      }
00355    }
00356    else{
00357      for(i=y;i>y+idy;i--){
00358        error -= grad;
00359        if(idx >= 0){
00360          if(error > 0.0){j++; error -= 1.0;}
00361        }
00362        else{
00363          if(error < 0.0){j--; error += 1.0;}
00364        }
00365        W=GetWL(l,(double)(j-x),(double)(i-y),Wmin,Wmax,linear);
00366        DrawAApixel((double)j,(double)i,W,W,C,Screen,X,Y,r,g,b);
00367      }
00368    }
00369  }
00370  return;
00371 }
00372 
00373 static void DrawHaloInBuffer(long x, long y,
00374                              fullscreenbuffer *Screen,
00375                              long X, long Y, long radius,
00376                              double z, float *Zb,
00377                              BOOL bDraw,
00378                              double maxV,
00379                              double R, double G, double B){
00380  /* mix in a white halo at the screen buffer location of the light source */
00381  long i,j;
00382  double d;
00383  fullscreenbuffer *S;
00384  for(i=x-radius;i<=x+radius;i++)for(j=y-radius;j<=y+radius;j++){
00385    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00386    S=(Screen + j*X + i);
00387    d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00388    if(d < radius*0.25)d=maxV;
00389    else d=maxV*1.3333*((double)radius-d)/(double)radius;
00390    d=max(0.0,d);
00391    if(bDraw || Zb == NULL || z < *(Zb + j*X + i)){
00392      S->R = (unsigned char)min(255.0,(double)S->R+d*R);
00393      S->G = (unsigned char)min(255.0,(double)S->G+d*G);
00394      S->B = (unsigned char)min(255.0,(double)S->B+d*B);
00395    }
00396  }
00397  return;
00398 }
00399 
00400 static void DrawDiskInBuffer(long x, long y,
00401                              fullscreenbuffer *Screen,
00402                              long X, long Y, long radius,
00403                              double z, float *Zb,
00404                              BOOL bDraw,
00405                              double minV, double maxV,
00406                              double R, double G, double B){
00407  long i,j;
00408  double d;
00409  fullscreenbuffer *S;
00410  for(i=x-radius;i<=x+radius;i++)for(j=y-radius;j<=y+radius;j++){
00411    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00412    S=(Screen + j*X + i);
00413    d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00414    if(d < (double)radius){
00415      d=minV+(maxV-minV)*((double)radius-d)/(double)radius;
00416        S->R = (unsigned char)min(255.0,(double)S->R+d*R);
00417      S->G = (unsigned char)min(255.0,(double)S->G+d*G);
00418      S->B = (unsigned char)min(255.0,(double)S->B+d*B);
00419    }
00420  }
00421  return;
00422 }
00423 
00424 static void DrawDiskWithFade(long x, long y,
00425                              fullscreenbuffer *Screen,
00426                              long X, long Y,
00427                              long radius, long dradius,
00428                              double z, float *Zb,
00429                              BOOL bDraw,
00430                              double minV, double maxV,
00431                              double R, double G, double B){
00432  long i,j;
00433  double d,dr;
00434  fullscreenbuffer *S;
00435  for(i=x-dradius;i<=x+dradius;i++)for(j=y-dradius;j<=y+dradius;j++){
00436    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00437    if(bDraw || Zb == NULL || z < *(Zb + j*X + i)){
00438      S=(Screen + j*X + i);
00439      d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00440      if(d < (double)radius){
00441        d=minV+(maxV-minV)*((double)radius-d)/(double)radius;
00442        S->R = (unsigned char)min(255.0,(double)S->R+d*R);
00443        S->G = (unsigned char)min(255.0,(double)S->G+d*G);
00444        S->B = (unsigned char)min(255.0,(double)S->B+d*B);
00445      }
00446      else if(d < (double)dradius){
00447        d -= (double)radius; dr = (double)(dradius-radius);
00448        d=minV*(dr-d)/dr;
00449        S->R = (unsigned char)min(255.0,(double)S->R+d*R);
00450        S->G = (unsigned char)min(255.0,(double)S->G+d*G);
00451        S->B = (unsigned char)min(255.0,(double)S->B+d*B);
00452      }
00453    }
00454  }
00455  return;
00456 }
00457 
00458 static void DrawCircleInBuffer(long x, long y,
00459                              fullscreenbuffer *Screen,
00460                              long X, long Y,
00461                              long iradius, long oradius,
00462                              double minV, double maxV,
00463                              double R, double G, double B){
00464  long i,j;
00465  double d,dc;
00466  fullscreenbuffer *S;
00467  dc=0.5*(double)(iradius+oradius);
00468  for(i=x-oradius;i<=x+oradius;i++)for(j=y-oradius;j<=y+oradius;j++){
00469    if(i < 0 || i >= X || j < 0 || j >= Y)continue;
00470    S=(Screen + j*X + i);
00471    d=sqrt((double)(i-x)*(double)(i-x) + (double)(j-y)*(double)(j-y));
00472    if(d >= (double)iradius && d <= (double)oradius){
00473      if(d > dc){
00474        d=maxV-(maxV-minV)*(d-dc)/((double)oradius-dc);
00475      }
00476      else{
00477        d=minV+(maxV-minV)*(d-(double)iradius)/(dc-(double)iradius);
00478      }
00479      S->R = (unsigned char)min(255.0,(double)S->R+d*R);
00480      S->G = (unsigned char)min(255.0,(double)S->G+d*G);
00481      S->B = (unsigned char)min(255.0,(double)S->B+d*B);
00482    }
00483  }
00484  return;
00485 }
00486 
00487 long _RenderImageProcess(char *PrmList, XIMAGE *lpXimage){
00488  int i,j,Nl,li,n=45;
00489  char dummy[255];
00490  double x,y,z,radius,angle,atnd,atnc,atnr,atn,atnV=1.0;
00491  long v,model,type,flicker,hide,sx,sy,ipx,ipy,ipz,id;
00492  long xx,yy,Xmax,Ymax,Xc,Yc,oborder=2,border=5,dborder=8;
00493  long xBlue,yBlue,xBrown,yBrown,xGreen,yGreen,xT,yT;
00494  double bscale,rscale,iScale,ascale,lscale,dlscale,d2r,lc,dx,dy;
00495  double cr=1.0,cg=1.0,cb=1.0;
00496  float *Zb;
00497  BOOL  bDraw=TRUE;
00498 #include "pro_key.c"
00499 //debug=fopen("d:debug.evi","w");
00500 //MessageBox(NULL,PrmList,NULL,MB_OK);
00501  sscanf(PrmList,"%s %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %f %ld %lf",
00502         dummy,&type,&flicker,&hide,&sx,&sy,&ipx,&ipy,&ipz,&model,&v,
00503         &bscale,&rscale,&id,&angle);
00504  if(type == 1 && (lpXimage->Nlights == 0 || lpXimage->Lights == NULL))return 1;
00505  if(lpXimage->Morph){
00506    double mr=lpXimage->MorphRatio;
00507    long q_v,q_model,q_type,q_flicker,q_hide,q_sx,q_sy,q_ipx,q_ipy,q_ipz,q_id;
00508    double q_bscale,q_rscale;
00509    sscanf(lpXimage->mParameters,
00510         "%s %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %f %f %ld",
00511         dummy,&q_type,&q_flicker,&q_hide,&q_sx,&q_sy,&q_ipx,&q_ipy,&q_ipz,
00512         &q_model,&q_v,
00513         &q_bscale,&q_rscale,&q_id);
00514    bscale=q_bscale+mr*(bscale-q_bscale);
00515    rscale=q_rscale+mr*(rscale-q_rscale);
00516  }
00517  Xmax=lpXimage->Xmax;  Ymax=lpXimage->Ymax;
00518  Xc=Xmax/2; Yc=Ymax/2;
00519  iScale=rscale*(double)Xmax/320;
00520  atnV *= bscale;
00521  ascale=5.0/32767.0;
00522  lscale=80.0*(double)iScale;
00523  dlscale=80.0/32767.0*(double)iScale;
00524  d2r=3.1415626/180.0;
00525  border  *= iScale;
00526  oborder *= iScale;
00527  dborder *= iScale;
00528  Zb=lpXimage->Zbuffer;
00529  if(flicker)srand(lpXimage->Frame);
00530  else       srand(1);
00531  if(type == 1 || type == 4 || type == 5)Nl=lpXimage->Nlights;
00532  else Nl=1;
00533  for(li=0;li<Nl;li++){
00534    if(type == 4 && lpXimage->Lights[li].type != DUMMYL)continue;
00535    if(type == 5 && lpXimage->Lights[li].AnimatorID != id)continue;
00536    if(type == 1 || type == 4 || type == 5){
00537      x=lpXimage->Lights[li].p[0];
00538      y=lpXimage->Lights[li].p[1];
00539      z=lpXimage->Lights[li].p[2];
00540      cr=(double)(lpXimage->Lights[li].color[0])/255.0;
00541      cg=(double)(lpXimage->Lights[li].color[1])/255.0;
00542      cb=(double)(lpXimage->Lights[li].color[2])/255.0;
00543    }
00544    else if(type == 2){
00545      TransformIntoView(lpXimage->ViewTransform,
00546                        (double)ipx,(double)ipy,(double)ipz,
00547                        &x,&y,&z);
00548    }
00549    else if(type == 3){
00550      hide=0; y=1.1;
00551    }
00552    if(y >= 1.000){
00553      if(type == 3){
00554        xx=sx; yy=sy;
00555      }
00556      else{
00557        xx=Xc + (long)(lpXimage->Xscale*x/y);
00558        yy=Yc - (long)(lpXimage->Yscale*z/y);
00559      }
00560      if(xx >= -border && xx < Xmax+border &&
00561         yy >= -border && yy < Ymax+border){
00562        dx=(double)(xx-Xc);  dy=(double)(yy-Yc);
00563        lc=DIST(dx,dy);  dx /= lc; dy /= lc;
00564        atnc=atnV; atn=atnV;
00565        if(xx < border && yy < border){
00566          if(xx < yy){
00567            atn  = Grad((double)xx,0.0,atnV,0,border);
00568            atnc = Grad((double)xx,0.0,atnV,-border,border);
00569          }
00570          else{
00571            atn  = Grad((double)yy,0.0,atnV,0,border);
00572            atnc = Grad((double)yy,0.0,atnV,-border,border);
00573          }
00574        }
00575        else if(xx > Xmax-border && yy > Ymax-border){
00576          if(xx-Xmax > yy-Ymax){
00577            atn  = Grad((double)xx,atnV,0.0,Xmax-border,Xmax);
00578            atnc = Grad((double)xx,atnV,0.0,Xmax-border,Xmax+border);
00579          }
00580          else{
00581            atn  = Grad((double)yy,atnV,0.0,Ymax-border,Ymax);
00582            atnc = Grad((double)yy,atnV,0.0,Ymax-border,Ymax+border);
00583          }
00584        }
00585        else if(xx < border && yy > Ymax-border){
00586          if(border-xx > yy-(Ymax-border)){
00587            atn  = Grad((double)xx,0.0,atnV,0,border);
00588            atnc = Grad((double)xx,0.0,atnV,-border,border);
00589          }
00590          else{
00591            atn  = Grad((double)yy,atnV,0.0,Ymax-border,Ymax);
00592            atnc = Grad((double)yy,atnV,0.0,Ymax-border,Ymax+border);
00593          }
00594        }
00595        else if(xx > Xmax-border && yy < border){
00596          if(border-yy > xx-(Xmax-border)){
00597            atn  = Grad((double)yy,0.0,atnV,0,border);
00598            atnc = Grad((double)yy,0.0,atnV,-border,border);
00599          }
00600          else{
00601            atn  = Grad((double)xx,atnV,0.0,Xmax-border,Xmax);
00602            atnc = Grad((double)xx,atnV,0.0,Xmax-border,Xmax+border);
00603          }
00604        }
00605        else if(xx < border){
00606          atn  = Grad((double)xx,0.0,atnV,0,border);
00607          atnc = Grad((double)xx,0.0,atnV,-border,border);
00608        }
00609        else if(yy < border){
00610          atn  = Grad((double)yy,0.0,atnV,0,border);
00611          atnc = Grad((double)yy,0.0,atnV,-border,border);
00612        }
00613        else if(xx > Xmax-border){
00614          atn  = Grad((double)xx,atnV,0.0,Xmax-border,Xmax);
00615          atnc = Grad((double)xx,atnV,0.0,Xmax-border,Xmax+border);
00616        }
00617        else if(yy > Ymax-border){
00618          atn  = Grad((double)yy,atnV,0.0,Ymax-border,Ymax);
00619          atnc = Grad((double)yy,atnV,0.0,Ymax-border,Ymax+border);
00620        }
00621        atnd=atnV; atnr=1.0;
00622        if(hide && Zb != NULL && xx >= 0 && yy >= 0 && xx < Xmax && yy < Ymax){
00623          double dd;
00624          if(y < *(Zb + (yy * Xmax) + xx)){  // visible
00625            dd=DistFromHidingObject(xx,yy,y,Zb,border,Xmax,Ymax);
00626            if(dd < border){
00627              atn  = Grad(dd,atnV*0.2,atnV,0,border);
00628              atnc = Grad(dd,atnV*0.5,atnV,0,border);
00629            }
00630          }
00631          if(y > *(Zb + (yy * Xmax) + xx)){  // hidden
00632            dd=DistFromVisibleObject(xx,yy,y,Zb,dborder,Xmax,Ymax);
00633            if(dd < oborder){
00634              atn  = Grad(dd,atnV*0.2,0.0,0,oborder);
00635              atnc = Grad(dd,atnV*0.5,0.0,0,oborder);
00636            }
00637            else if(dd < dborder){
00638              atn=0.0; atnc=0.0;
00639              atnr = Grad(dd,1.0,0.0,0,dborder);
00640            }
00641            else continue;
00642          }
00643        }
00644        if(model < 3){  /* draw inter-lens reflections */
00645        DrawDiskInBuffer(Xc+(long)(1.8*lc*dx),Yc+(long)(1.8*lc*dy), // big brown
00646                         lpXimage->Screen,Xmax,Ymax,
00647                         (long)(120*iScale),
00648                         y,Zb,bDraw,20.0*atn,30.0*atn,
00649                         1.0,0.1,0.05);
00650        DrawCircleInBuffer(Xc+(long)(1.3*lc*dx),Yc+(long)(1.3*lc*dy),
00651                         lpXimage->Screen,Xmax,Ymax,            // yellow disk
00652                         (long)(10*iScale),(long)(13*iScale),
00653                         0.0*atn,30.0*atn,
00654                         1.0,1.0,0.2);
00655        DrawDiskInBuffer(Xc+(long)(1.3*lc*dx),Yc+(long)(1.3*lc*dy),
00656                         lpXimage->Screen,Xmax,Ymax,            // centre of yellow disk
00657                         (long)(15*iScale),
00658                         y,Zb,bDraw,
00659                         10.0*atn,20.0*atn,
00660                         1.0,1.0,0.2);
00661 
00662        xBlue=Xc+(long)(0.5*lc*dx); yBlue=Yc+(long)(0.5*lc*dy);
00663        DrawDiskWithFade(xBlue,yBlue, // blue overlapping
00664                         lpXimage->Screen,Xmax,Ymax,
00665                         (long)(20*iScale),(long)(25*iScale),
00666                         y,Zb,bDraw,
00667                         40.0*atn,60.0*atn,
00668                         0.0,0.0,1.0);
00669        DrawDiskWithFade(xBlue+(long)(8*iScale*dx),yBlue+(long)(8*iScale*dy),
00670                         lpXimage->Screen,Xmax,Ymax,
00671                         (long)(6*iScale),(long)(8*iScale),
00672                         y,Zb,bDraw,
00673                         40.0*atn,44.0*atn,
00674                         0.0,0.0,1.0);
00675        DrawDiskWithFade(xBlue-(long)(6*iScale*dx),yBlue-(long)(6*iScale*dy),
00676                         lpXimage->Screen,Xmax,Ymax,
00677                         (long)(9*iScale),(long)(11*iScale),
00678                         y,Zb,bDraw,
00679                         40.0*atn,44.0*atn,
00680                         0.0,0.0,1.0);
00681 
00682        xBrown=Xc-(long)(0.5*lc*dx); yBrown=Yc-(long)(0.5*lc*dy);
00683        DrawDiskWithFade(xBrown,yBrown, // brown overlapping
00684                         lpXimage->Screen,Xmax,Ymax,
00685                         (long)(18*iScale),(long)(21*iScale),
00686                         y,Zb,bDraw,
00687                         40.0*atn,44.0*atn,
00688                         1.0,0.1,0.2);
00689        DrawDiskWithFade(xBrown-(long)(8*iScale*dx),yBrown-(long)(8*iScale*dy),
00690                         lpXimage->Screen,Xmax,Ymax,
00691                         (long)(5*iScale),(long)(7*iScale),
00692                         y,Zb,bDraw,
00693                         40.0*atn,44.0*atn,
00694                         1.0,0.1,0.2);
00695        DrawDiskWithFade(xBrown+(long)(6*iScale*dx),yBrown+(long)(6*iScale*dy),
00696                         lpXimage->Screen,Xmax,Ymax,
00697                         (long)(10*iScale),(long)(12*iScale),
00698                         y,Zb,bDraw,40.0*atn,44.0*atn,
00699                         1.0,0.1,0.2);
00700 
00701        xBrown=Xc+(long)(0.35*lc*dx); yBrown=Yc+(long)(0.35*lc*dy);
00702        DrawDiskInBuffer(xBrown,yBrown, // single brown
00703                         lpXimage->Screen,Xmax,Ymax,
00704                         (long)(5*iScale),
00705                         y,Zb,bDraw,
00706                         40.0*atn,44.0*atn,
00707                         1.0,0.1,0.2);
00708 
00709        xT=Xc-(long)(0.8*lc*dx); yT=Yc-(long)(0.8*lc*dy);
00710        DrawHaloInBuffer(xT,yT,lpXimage->Screen,Xmax,Ymax,
00711                         (long)(10*iScale),
00712                         y,Zb,bDraw,
00713                         160.0*atn,
00714                         0.2,0.2,1.0);  // blue halo
00715        DrawHaloInBuffer(xT-(long)(2*iScale*dx),yT-(long)(2*iScale*dy),
00716                         lpXimage->Screen, // white bit
00717                         Xmax,Ymax,
00718                         (long)(2*iScale),
00719                         y,Zb,bDraw,
00720                         64.0*atn,
00721                         1.0,1.0,1.0);
00722        DrawDiskWithFade(xT+(long)(8*iScale*dx),yT+(long)(8*iScale*dy),
00723                         lpXimage->Screen,Xmax,Ymax,
00724                         (long)(11*iScale),(long)(13*iScale), // green bit
00725                         y,Zb,bDraw,
00726                         40.0*atn,44.0*atn,
00727                         0.5,0.8,0.2);
00728 
00729        xGreen=Xc-(long)(0.8*lc*dx); yGreen=Yc-(long)(0.8*lc*dy);
00730        DrawDiskInBuffer(xGreen,yGreen, // green disk
00731                         lpXimage->Screen,Xmax,Ymax,
00732                         (long)(30*iScale),
00733                         y,Zb,bDraw,
00734                         20.0*atn,44.0*atn,
00735                         0.4,0.5,0.2);
00736        DrawCircleInBuffer(xGreen,yGreen,
00737                         lpXimage->Screen,Xmax,Ymax,    // green outline
00738                         (long)(28*iScale),(long)(30*iScale),
00739                         0.0*atn,30.0*atn,
00740                         1.0,1.0,0.2);
00741 
00742        xT=Xc-(long)(1.2*lc*dx); yT=Yc-(long)(1.2*lc*dy); // opposite rainbow
00743        DrawCircleInBuffer(xT,yT,
00744                         lpXimage->Screen,Xmax,Ymax,
00745                         (long)(60*iScale),(long)(62*iScale),
00746                         10.0*atn,30.0*atn,
00747                         1.0,0.2,0.2);
00748        DrawCircleInBuffer(xT,yT,
00749                         lpXimage->Screen,Xmax,Ymax,
00750                         (long)(58*iScale),(long)(61*iScale),
00751                         30.0*atn,30.0*atn,
00752                         0.2,1.0,0.2);
00753        DrawCircleInBuffer(xT,yT,
00754                         lpXimage->Screen,Xmax,Ymax,
00755                         (long)(56*iScale),(long)(59*iScale),
00756                         10.0*atn,30.0*atn,
00757                         0.2,0.2,1.0);
00758 
00759        DrawAApixel(Xmax/2,Ymax/2,1.0*iScale,1.0*iScale,   // bright screen centre
00760                    255.0*atn,
00761                    lpXimage->Screen,Xmax,Ymax,
00762                    1,1,1);
00763        xT=Xc-(long)(0.35*lc*dx); yT=Yc-(long)(0.35*lc*dy);
00764        DrawHaloInBuffer(xT,yT,lpXimage->Screen,           // bright offcentre
00765                         Xmax,Ymax,
00766                         (long)(3*iScale),
00767                         y,Zb,bDraw,
00768                         255.0*atn,
00769                         0.8,0.8,1.0);
00770        } /* end inter-lens reflections */
00771        if(model == 1){
00772          DrawHaloInBuffer(xx,yy,lpXimage->Screen,Xmax,Ymax, // light halo
00773                           (long)(3*iScale),
00774                           y,Zb,bDraw,
00775                           255.0*atnc,
00776                           1.0,1.0,1.0);
00777          DrawHaloInBuffer(xx,yy,lpXimage->Screen,Xmax,Ymax, // light halo red disk
00778                           (long)(20*iScale),
00779                           y,Zb,bDraw,
00780                           80.0*atn,
00781                           1.0,0.5,0.2);
00782          DrawCircleInBuffer(xx,yy,
00783                           lpXimage->Screen,Xmax,Ymax,       // light halo outer ring
00784                           (long)(20*iScale),(long)(23*iScale),
00785                           50.0*atn,80.0*atn,
00786                           1.0,0.5,0.0);
00787          for(j=0;j<n;j++){  /* outlying spines */
00788            double a,l;
00789            long   idx,idy;
00790            a=360.0/(double)n*(double)j+ascale*(double)rand();
00791            a *= d2r;
00792            l=lscale+dlscale*(double)rand();
00793            l *= atn;
00794            idx=(long)(l*cos(a)); idy=(long)(l*sin(a));
00795            DrawFlareInBuffer(xx,yy,idx,idy,lpXimage->Screen,Xmax,Ymax,
00796                              iScale/rscale, /* don't scale size */
00797                              20.0*atn, // brightness 0-255
00798                              0.2,0.8,  // min width max width
00799                              y,Zb,bDraw,TRUE);
00800          }
00801          for(i=0;i<3;i++)for(j=0;j<n;j++){ /* centre spines */
00802            double a,l,C;
00803            long   idx,idy;
00804            a=360.0/(double)n*(double)j+ascale*(double)rand();
00805            a *= d2r;
00806            l=lscale+dlscale*(double)rand();
00807            if     (i == 0){l /= 5; l *= atnc; C=32.0*atn;}
00808            else if(i == 1){l /= 10; C=64.0*atn;}
00809            else if(i == 2){l /= 20; C=128.0*atnc;}
00810            idx=(long)(l*cos(a)); idy=(long)(l*sin(a));
00811            DrawFlareInBuffer(xx,yy,idx,idy,lpXimage->Screen,Xmax,Ymax,
00812                              iScale,
00813                              C,
00814                              0.2,0.8,
00815                              y,Zb,bDraw,TRUE);
00816          }
00817        }
00818        else if(model == 2 || model == 3){ /* model2/3 */
00819          DrawHaloInBuffer(xx,yy,lpXimage->Screen,Xmax,Ymax, // light halo
00820                           (long)(20*iScale),
00821                           y,Zb,bDraw,
00822                           255.0*atnc,
00823                           1.0,1.0,1.0);
00824          DrawHaloInBuffer(xx,yy,lpXimage->Screen,Xmax,Ymax, // light halo red disk
00825                           (long)(30*iScale),
00826                           y,Zb,bDraw,
00827                           80.0*atnc,
00828                           1.0,0.5,0.2);
00829          DrawCircleInBuffer(xx,yy,
00830                           lpXimage->Screen,Xmax,Ymax,       // light halo outer ring
00831                           (long)(150*iScale),(long)(160*iScale),
00832                           50.0*atn,80.0*atn,
00833                           1.0,0.5,0.0);
00834          if(model == 2)DrawDiskWithFade(xx,yy,
00835                          lpXimage->Screen,Xmax,Ymax,        // big obscured disk
00836                           (long)(27*iScale)*atnr,
00837                           (long)(40*iScale)*atnr,
00838                           y,Zb,(BOOL)(!hide),
00839                           100.0*atnd,100.0*atnd,
00840                           1.0,1.0,1.0);
00841          if(model == 2)for(j=0;j<10;j++){  /* spines */
00842            double a,l,ddx,ddy;
00843            long   xs,ys,idx,idy;
00844            a= -90.0 + 360.0/(double)10*(double)j;
00845            a *= d2r;
00846            l=lscale*1.5;
00847            l *= atn/bscale;  /* don't scale for brightness */
00848            ddx=l*cos(a); ddy=l*sin(a);
00849            idx=(long)ddx; idy=(long)ddy;
00850            xs=xx+(long)(ddx*0.09); ys=yy+(long)(ddy*0.09);
00851            DrawFlareInBuffer(xs,ys,idx,idy,lpXimage->Screen,Xmax,Ymax,
00852                              iScale/rscale, /* don't scale size */
00853                              40.0*atnc/bscale, // brightness 0-255
00854                              0.0,1.4*atnc/bscale,  // min width max width
00855                              y,Zb,bDraw,FALSE);
00856            DrawFlareInBuffer(xs,ys,idx,idy,lpXimage->Screen,Xmax,Ymax,
00857                              iScale/rscale, /* don't scale size */
00858                              20.0*atnc/bscale, // brightness 0-255
00859                              0.0,2.8*atnc/bscale,  // min width max width
00860                              y,Zb,bDraw,FALSE);
00861            xs=xx+(long)(ddx*0.2); ys=yy+(long)(ddy*0.2);
00862            DrawFlareInBuffer(xs,ys,idx,idy,lpXimage->Screen,Xmax,Ymax,
00863                              iScale/rscale, /* don't scale size */
00864                              10.0*atnc/bscale, // brightness 0-255
00865                              0.0,4.5*atnc/bscale,  // min width max width
00866                              y,Zb,bDraw,FALSE);
00867          }
00868        }
00869        else { /* model=4 */
00870          fullscreenbuffer *Screen;
00871          if((Screen=(fullscreenbuffer *)X__Malloc(Xmax*Ymax*
00872              (long)sizeof(fullscreenbuffer))) != NULL){
00873            memset(Screen,0,Xmax*Ymax*sizeof(fullscreenbuffer));
00874            for(j=0;j<8;j++){  /* outer */
00875              double a,l;
00876              long   idx,idy;
00877              a=360.0/(double)8*(double)j+22.5;
00878              a *= d2r;
00879              l=lscale;
00880              l *= atn;
00881              idx=(long)(l*cos(a)); idy=(long)(l*sin(a));
00882              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00883                              Screen,
00884                              Xmax,Ymax,
00885                              8.0*atn, // brightness 0-255
00886                              cr,cg,cb, // colour
00887                              4.0*iScale/2,4.5*iScale/2,  // min width max width
00888                              y,Zb,
00889                              bDraw,TRUE);
00890              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00891                              Screen,
00892                              Xmax,Ymax,
00893                              16.0*atn, // brightness 0-255
00894                              cr,cg,cb, // colour
00895                              1.0*iScale/2,3.0*iScale/2,  // min width max width
00896                              y,Zb,
00897                              bDraw,TRUE);
00898              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00899                              Screen,
00900                              Xmax,Ymax,
00901                              80.0*atn, // brightness 0-255
00902                              1.0,1.0,1.0, // colour
00903                              0.0,2.0*iScale/2,  // min width max width
00904                              y,Zb,
00905                              bDraw,TRUE);
00906              idx /= 2; idy /=2;
00907              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00908                              Screen,
00909                              Xmax,Ymax,
00910                              16.0*atn, // brightness 0-255
00911                              cr,cg,cb, // colour
00912                              0.0,2.0*iScale/2,  // min width max width
00913                              y,Zb,
00914                              bDraw,TRUE);
00915            }
00916            for(j=0;j<8;j++){  /* inner */
00917              double a,l;
00918              long   idx,idy;
00919              a=360.0/(double)8*(double)j;
00920              a *= d2r;
00921              l=lscale/2;
00922              l *= atn;
00923              idx=(long)(l*cos(a)); idy=(long)(l*sin(a));
00924              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00925                              Screen,
00926                              Xmax,Ymax,
00927                              64.0*atn, // brightness 0-255
00928                              cr,cg,cb, // colour
00929                              0.8*iScale/2,1.5*iScale/2,  // min width max width
00930                              y,Zb,bDraw,TRUE);
00931            }
00932            n=36;
00933            for(j=0;j<n;j++){  /* jitter */
00934              double a,l;
00935              long   idx,idy;
00936              a=360.0/(double)n*(double)j+ascale*(double)rand();
00937              a *= d2r;
00938              l=(lscale+dlscale*(double)rand())/30;
00939              l *= atn;
00940              idx=(long)(l*cos(a)); idy=(long)(l*sin(a));
00941              DrawFadedFlareInBuffer(xx,yy,idx,idy,
00942                              Screen,
00943                              Xmax,Ymax,
00944                              255.0*atn, // brightness 0-255
00945                              1.0,1.0,1.0, // colour
00946                              0.8*iScale/2,1.2*iScale/2,  // min width max width
00947                              y,Zb,bDraw,TRUE);
00948            }
00949            DrawDiskWithFade(xx,yy,Screen,Xmax,Ymax, // light halo
00950                           (long)(5*iScale), (long)(20*iScale),
00951                           y,Zb,bDraw,
00952                           128.0*atnc/bscale,255.0*atnc/bscale,
00953                           cr,cg,cb);
00954            if(Xmax > 320)BlurBuffer(Screen,Xmax,Ymax);
00955            MixBuffer(Screen,lpXimage->Screen,Xmax,Ymax);
00956            X__Free(Screen);
00957          }
00958        }
00959      }
00960    }
00961  }
00962 //fclose(debug);
00963  return 1;
00964 }

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