Back to index

radiance  4R0+20100331
Classes | Defines | Typedefs | Functions | Variables
ambient.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ambrec
struct  ambtree
struct  AMBSAMP
struct  AMBHEMI

Defines

#define AVGREFL   0.5 /* assumed average reflectance */
#define AMBVALSIZ   75 /* number of bytes in portable AMBVAL struct */
#define AMBMAGIC   557 /* magic number for ambient value files */
#define AMBFMT   "Radiance_ambval" /* format id string */

Typedefs

typedef struct ambrec AMBVAL
typedef struct ambtree AMBTREE

Functions

void setambres (int ar)
void setambacc (double newa)
void setambient (void)
void multambient (COLOR aval, RAY *r, FVECT nrm)
void ambdone (void)
void ambnotify (OBJECT obj)
double sumambient (COLOR acol, RAY *r, FVECT rn, int al, AMBTREE *at, FVECT c0, double s)
double makeambient (COLOR acol, RAY *r, FVECT rn, int al)
void extambient (COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv)
int ambsync (void)
double doambient (COLOR acol, RAY *r, double wt, FVECT pg, FVECT dg)
void inithemi (AMBHEMI *hp, COLOR ac, RAY *r, double wt)
int divsample (AMBSAMP *dp, AMBHEMI *h, RAY *r)
void comperrs (AMBSAMP *da, AMBHEMI *hp)
void posgradient (FVECT gv, AMBSAMP *da, AMBHEMI *hp)
void dirgradient (FVECT gv, AMBSAMP *da, AMBHEMI *hp)
void putambmagic (FILE *fp)
int hasambmagic (FILE *fp)
int writambval (AMBVAL *av, FILE *fp)
int ambvalOK (AMBVAL *av)
int readambval (AMBVAL *av, FILE *fp)
void lookamb (FILE *fp)
void writamb (FILE *fp)

Variables

double maxarad
double minarad

Class Documentation

struct ambrec

Definition at line 18 of file ambient.h.

Collaboration diagram for ambrec:
Class Members
float dir
float gdir
float gpos
unsigned long latick
int lvl
struct ambrec * next
float pos
float rad
COLOR val
float weight
struct ambtree

Definition at line 31 of file ambient.h.

Collaboration diagram for ambtree:
Class Members
AMBVAL * alist
struct ambtree * kid
struct AMBSAMP

Definition at line 36 of file ambient.h.

Class Members
float k
int n
short p
float r
short t
COLOR v
struct AMBHEMI

Definition at line 44 of file ambient.h.

Class Members
COLOR acoef
short np
int ns
short nt
FVECT ux
FVECT uy
FVECT uz

Define Documentation

#define AMBFMT   "Radiance_ambval" /* format id string */

Definition at line 60 of file ambient.h.

#define AMBMAGIC   557 /* magic number for ambient value files */

Definition at line 59 of file ambient.h.

#define AMBVALSIZ   75 /* number of bytes in portable AMBVAL struct */

Definition at line 58 of file ambient.h.

#define AVGREFL   0.5 /* assumed average reflectance */

Definition at line 55 of file ambient.h.


Typedef Documentation

typedef struct ambtree AMBTREE
typedef struct ambrec AMBVAL

Function Documentation

void ambdone ( void  )

Definition at line 201 of file ambient.c.

{
       if (ambfp != NULL) {        /* close ambient file */
              ambsync();
              fclose(ambfp);
              ambfp = NULL;
              if (ambinp != NULL) {       
                     fclose(ambinp);
                     ambinp = NULL;
              }
              lastpos = -1;
       }
                                   /* free ambient tree */
       unloadatree(&atrunk, free);
                                   /* reset state variables */
       avsum = 0.;
       navsum = 0;
       nambvals = 0;
       nambshare = 0;
       ambclock = 0;
       lastsort = 0;
       sortintvl = SORT_INTVL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ambnotify ( OBJECT  obj)

Definition at line 227 of file ambient.c.

{
       static int  hitlimit = 0;
       register OBJREC       *o;
       register char  **amblp;

       if (obj == OVOID) {         /* starting over */
              ambset[0] = 0;
              hitlimit = 0;
              return;
       }
       o = objptr(obj);
       if (hitlimit || !ismodifier(o->otype))
              return;
       for (amblp = amblist; *amblp != NULL; amblp++)
              if (!strcmp(o->oname, *amblp)) {
                     if (ambset[0] >= MAXASET) {
                            error(WARNING, "too many modifiers in ambient list");
                            hitlimit++;
                            return;              /* should this be fatal? */
                     }
                     insertelem(ambset, obj);
                     return;
              }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ambsync ( void  )

Definition at line 939 of file ambient.c.

{
       if (ambfp == NULL)
              return(0);
       nunflshed = 0;
       return(fflush(ambfp));
}

Here is the caller graph for this function:

int ambvalOK ( AMBVAL av)

Definition at line 70 of file ambio.c.

{
       double d;

       if (badvec(av->pos)) return(0);
       if (badvec(av->dir)) return(0);
       d = DOT(av->dir,av->dir);
       if (d < 0.9999 || d > 1.0001) return(0);
       if (av->lvl < 0 || av->lvl > 100) return(0);
       if (av->weight <= 0. || av->weight > 1.) return(0);
       if (av->rad <= 0. || av->rad >= FHUGE) return(0);
       if (colval(av->val,RED) < 0. ||
                     colval(av->val,RED) > FHUGE ||
                     colval(av->val,GRN) < 0. ||
                     colval(av->val,GRN) > FHUGE ||
                     colval(av->val,BLU) < 0. ||
                     colval(av->val,BLU) > FHUGE) return(0);
       if (badvec(av->gpos)) return(0);
       if (badvec(av->gdir)) return(0);
       return(1);
}

Here is the caller graph for this function:

void comperrs ( AMBSAMP da,
AMBHEMI hp 
)
void dirgradient ( FVECT  gv,
AMBSAMP da,
AMBHEMI hp 
)
int divsample ( AMBSAMP dp,
AMBHEMI h,
RAY r 
)
double doambient ( COLOR  acol,
RAY r,
double  wt,
FVECT  pg,
FVECT  dg 
)

Definition at line 150 of file ambcomp.c.

{
       double  b, d;
       AMBHEMI  hemi;
       AMBSAMP  *div;
       AMBSAMP  dnew;
       register AMBSAMP  *dp;
       double  arad;
       int  divcnt;
       register int  i, j;
                                   /* initialize hemisphere */
       inithemi(&hemi, acol, r, wt);
       divcnt = hemi.nt * hemi.np;
                                   /* initialize */
       if (pg != NULL)
              pg[0] = pg[1] = pg[2] = 0.0;
       if (dg != NULL)
              dg[0] = dg[1] = dg[2] = 0.0;
       setcolor(acol, 0.0, 0.0, 0.0);
       if (divcnt == 0)
              return(0.0);
                                   /* allocate super-samples */
       if (hemi.ns > 0 || pg != NULL || dg != NULL) {
              div = (AMBSAMP *)malloc(divcnt*sizeof(AMBSAMP));
              if (div == NULL)
                     error(SYSTEM, "out of memory in doambient");
       } else
              div = NULL;
                                   /* sample the divisions */
       arad = 0.0;
       if ((dp = div) == NULL)
              dp = &dnew;
       divcnt = 0;
       for (i = 0; i < hemi.nt; i++)
              for (j = 0; j < hemi.np; j++) {
                     dp->t = i; dp->p = j;
                     setcolor(dp->v, 0.0, 0.0, 0.0);
                     dp->r = 0.0;
                     dp->n = 0;
                     if (divsample(dp, &hemi, r) < 0) {
                            if (div != NULL)
                                   dp++;
                            continue;
                     }
                     arad += dp->r;
                     divcnt++;
                     if (div != NULL)
                            dp++;
                     else
                            addcolor(acol, dp->v);
              }
       if (!divcnt) {
              if (div != NULL)
                     free((void *)div);
              return(0.0);         /* no samples taken */
       }
       if (divcnt < hemi.nt*hemi.np) {
              pg = dg = NULL;             /* incomplete sampling */
              hemi.ns = 0;
       } else if (arad > FTINY && divcnt/arad < minarad) {
              hemi.ns = 0;         /* close enough */
       } else if (hemi.ns > 0) {   /* else perform super-sampling? */
              comperrs(div, &hemi);                     /* compute errors */
              qsort(div, divcnt, sizeof(AMBSAMP), ambcmp);     /* sort divs */
                                          /* super-sample */
              for (i = hemi.ns; i > 0; i--) {
                     dnew = *div;
                     if (divsample(&dnew, &hemi, r) < 0) {
                            dp++;
                            continue;
                     }
                     dp = div;            /* reinsert */
                     j = divcnt < i ? divcnt : i;
                     while (--j > 0 && dnew.k < dp[1].k) {
                            *dp = *(dp+1);
                            dp++;
                     }
                     *dp = dnew;
              }
              if (pg != NULL || dg != NULL)      /* restore order */
                     qsort(div, divcnt, sizeof(AMBSAMP), ambnorm);
       }
                                   /* compute returned values */
       if (div != NULL) {
              arad = 0.0;          /* note: divcnt may be < nt*np */
              for (i = hemi.nt*hemi.np, dp = div; i-- > 0; dp++) {
                     arad += dp->r;
                     if (dp->n > 1) {
                            b = 1.0/dp->n;
                            scalecolor(dp->v, b);
                            dp->r *= b;
                            dp->n = 1;
                     }
                     addcolor(acol, dp->v);
              }
              b = bright(acol);
              if (b > FTINY) {
                     b = 1.0/b;    /* compute & normalize gradient(s) */
                     if (pg != NULL) {
                            posgradient(pg, div, &hemi);
                            for (i = 0; i < 3; i++)
                                   pg[i] *= b;
                     }
                     if (dg != NULL) {
                            dirgradient(dg, div, &hemi);
                            for (i = 0; i < 3; i++)
                                   dg[i] *= b;
                     }
              }
              free((void *)div);
       }
       if (arad <= FTINY)
              arad = maxarad;
       else
              arad = (divcnt+hemi.ns)/arad;
       if (pg != NULL) {           /* reduce radius if gradient large */
              d = DOT(pg,pg);
              if (d*arad*arad > 1.0)
                     arad = 1.0/sqrt(d);
       }
       if (arad < minarad) {
              arad = minarad;
              if (pg != NULL && d*arad*arad > 1.0) {    /* cap gradient */
                     d = 1.0/arad/sqrt(d);
                     for (i = 0; i < 3; i++)
                            pg[i] *= d;
              }
       }
       if ((arad /= sqrt(wt)) > maxarad)
              arad = maxarad;
       return(arad);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void extambient ( COLOR  cr,
AMBVAL ap,
FVECT  pv,
FVECT  nv 
)
int hasambmagic ( FILE *  fp)

Definition at line 36 of file ambio.c.

{
       register int  magic;

       magic = getint(2, fp);
       if (feof(fp))
              return(0);
       return(magic == AMBMAGIC);
}

Here is the caller graph for this function:

void inithemi ( AMBHEMI hp,
COLOR  ac,
RAY r,
double  wt 
)
void lookamb ( FILE *  fp)

Definition at line 92 of file lookamb.c.

{
       while (readambval(&av, fp)) {
              if (dataonly) {
                     printf("%f\t%f\t%f\t", av.pos[0], av.pos[1], av.pos[2]);
                     printf("%f\t%f\t%f\t", av.dir[0], av.dir[1], av.dir[2]);
                     printf("%d\t%f\t%f\t", av.lvl, av.weight, av.rad);
                     printf("%e\t%e\t%e\t", colval(av.val,RED),
                                          colval(av.val,GRN),
                                          colval(av.val,BLU));
                     printf("%f\t%f\t%f\t", av.gpos[0],
                                   av.gpos[1], av.gpos[2]);
                     printf("%f\t%f\t%f\n", av.gdir[0],
                                   av.gdir[1], av.gdir[2]);
              } else {
                     printf("\nPosition:\t%f\t%f\t%f\n", av.pos[0],
                                   av.pos[1], av.pos[2]);
                     printf("Direction:\t%f\t%f\t%f\n", av.dir[0],
                                   av.dir[1], av.dir[2]);
                     printf("Lvl,Wt,Rad:\t%d\t\t%f\t%f\n", av.lvl,
                                   av.weight, av.rad);
                     printf("Value:\t\t%e\t%e\t%e\n", colval(av.val,RED),
                                   colval(av.val,GRN), colval(av.val,BLU));
                     printf("Pos.Grad:\t%f\t%f\t%f\n", av.gpos[0],
                                   av.gpos[1], av.gpos[2]);
                     printf("Dir.Grad:\t%f\t%f\t%f\n", av.gdir[0],
                                   av.gdir[1], av.gdir[2]);
              }
              if (ferror(stdout))
                     exit(1);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

double makeambient ( COLOR  acol,
RAY r,
FVECT  rn,
int  al 
)

Definition at line 442 of file ambient.c.

{
       AMBVAL amb;
       FVECT  gp, gd;
       int    i;

       amb.weight = 1.0;                  /* compute weight */
       for (i = al; i-- > 0; )
              amb.weight *= AVGREFL;
       if (r->rweight < 0.1*amb.weight)   /* heuristic override */
              amb.weight = 1.25*r->rweight;
       setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
                                          /* compute ambient */
       amb.rad = doambient(acol, r, amb.weight, gp, gd);
       if (amb.rad <= FTINY) {
              setcolor(acol, 0.0, 0.0, 0.0);
              return(0.0);
       }
       scalecolor(acol, 1./AVGREFL);             /* undo assumed reflectance */
                                          /* store value */
       VCOPY(amb.pos, r->rop);
       VCOPY(amb.dir, r->ron);
       amb.lvl = al;
       copycolor(amb.val, acol);
       VCOPY(amb.gpos, gp);
       VCOPY(amb.gdir, gd);
                                          /* insert into tree */
       avsave(&amb);                      /* and save to file */
       if (rn != r->ron)
              extambient(acol, &amb, r->rop, rn);       /* texture */
       return(amb.rad);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void multambient ( COLOR  aval,
RAY r,
FVECT  nrm 
)
void posgradient ( FVECT  gv,
AMBSAMP da,
AMBHEMI hp 
)
void putambmagic ( FILE *  fp)

Definition at line 28 of file ambio.c.

{
       putint((long)AMBMAGIC, 2, fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int readambval ( AMBVAL av,
FILE *  fp 
)

Definition at line 95 of file ambio.c.

{
       COLR  col;

       av->lvl = getint(1, fp);
       if (feof(fp))
              return(0);
       av->weight = getflt(fp);
       getvec(av->pos, fp);
       getvec(av->dir, fp);
       if (fread((char *)col, sizeof(col), 1, fp) != 1)
              return(0);
       colr_color(av->val, col);
       av->rad = getflt(fp);
       getvec(av->gpos, fp);
       getvec(av->gdir, fp);
       return(feof(fp) ? 0 : ambvalOK(av));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void setambacc ( double  newa)

Definition at line 125 of file ambient.c.

{
       double  ambdiff;

       if (newa < 0.0)
              newa = 0.0;
       ambdiff = fabs(newa - ambacc);
       if (ambdiff >= .01 && (ambacc = newa) > FTINY && nambvals > 0)
              sortambvals(1);                    /* rebuild tree */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void setambient ( void  )

Definition at line 140 of file ambient.c.

{
       int    readonly = 0;
       long   flen;
       AMBVAL amb;
                                          /* make sure we're fresh */
       ambdone();
                                          /* init ambient limits */
       setambres(ambres);
       setambacc(ambacc);
       if (ambfile == NULL || !ambfile[0])
              return;
       if (ambacc <= FTINY) {
              sprintf(errmsg, "zero ambient accuracy so \"%s\" not opened",
                            ambfile);
              error(WARNING, errmsg);
              return;
       }
                                          /* open ambient file */
       if ((ambfp = fopen(ambfile, "r+")) == NULL)
              readonly = (ambfp = fopen(ambfile, "r")) != NULL;
       if (ambfp != NULL) {
              initambfile(0);                    /* file exists */
              lastpos = ftell(ambfp);
              while (readambval(&amb, ambfp))
                     avinsert(avstore(&amb));
              nambshare = nambvals;              /* share loaded values */
              if (readonly) {
                     sprintf(errmsg,
                            "loaded %u values from read-only ambient file",
                                   nambvals);
                     error(WARNING, errmsg);
                     fclose(ambfp);              /* close file so no writes */
                     ambfp = NULL;
                     return;                     /* avoid ambsync() */
              }
                                          /* align file pointer */
              lastpos += (long)nambvals*AMBVALSIZ;
              flen = lseek(fileno(ambfp), (off_t)0, SEEK_END);
              if (flen != lastpos) {
                     sprintf(errmsg,
                     "ignoring last %ld values in ambient file (corrupted)",
                                   (flen - lastpos)/AMBVALSIZ);
                     error(WARNING, errmsg);
                     fseek(ambfp, lastpos, SEEK_SET);
#ifndef _WIN32 /* XXX we need a replacement for that one */
                     ftruncate(fileno(ambfp), (off_t)lastpos);
#endif
              }
       } else if ((ambfp = fopen(ambfile, "w+")) != NULL) {
              initambfile(1);                    /* else create new file */
              lastpos = ftell(ambfp);
       } else {
              sprintf(errmsg, "cannot open ambient file \"%s\"", ambfile);
              error(SYSTEM, errmsg);
       }
       ambsync();                  /* load previous values */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void setambres ( int  ar)

Definition at line 102 of file ambient.c.

{
       ambres = ar < 0 ? 0 : ar;          /* may be done already */
                                          /* set min & max radii */
       if (ar <= 0) {
              minarad = 0;
              maxarad = thescene.cusize / 2.0;
       } else {
              minarad = thescene.cusize / ar;
              maxarad = 64 * minarad;                   /* heuristic */
              if (maxarad > thescene.cusize / 2.0)
                     maxarad = thescene.cusize / 2.0;
       }
       if (minarad <= FTINY)
              minarad = 10*FTINY;
       if (maxarad <= minarad)
              maxarad = 64 * minarad;
}

Here is the caller graph for this function:

double sumambient ( COLOR  acol,
RAY r,
FVECT  rn,
int  al,
AMBTREE at,
FVECT  c0,
double  s 
)
void writamb ( FILE *  fp)

Definition at line 129 of file lookamb.c.

{
       for ( ; ; ) {
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%f %f %f",
                            &av.pos[0], &av.pos[1], &av.pos[2]) != 3)
                     return;
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%f %f %f",
                            &av.dir[0], &av.dir[1], &av.dir[2]) != 3)
                     return;
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%d %f %f",
                            &av.lvl, &av.weight, &av.rad) != 3)
                     return;
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%f %f %f",
                            &av.val[RED], &av.val[GRN], &av.val[BLU]) != 3)
                     return;
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%f %f %f",
                            &av.gpos[0], &av.gpos[1], &av.gpos[2]) != 3)
                     return;
              if (!dataonly)
                     fscanf(fp, "%*s");
              if (fscanf(fp, "%f %f %f",
                            &av.gdir[0], &av.gdir[1], &av.gdir[2]) != 3)
                     return;
              av.next = NULL;
              writambval(&av, stdout);
              if (ferror(stdout))
                     exit(1);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int writambval ( AMBVAL av,
FILE *  fp 
)

Definition at line 49 of file ambio.c.

{
       COLR  col;

       putint((long)av->lvl, 1, fp);
       putflt(av->weight, fp);
       putvec(av->pos, fp);
       putvec(av->dir, fp);
       setcolr(col, colval(av->val,RED),
                     colval(av->val,GRN), colval(av->val,BLU));
       fwrite((char *)col, sizeof(col), 1, fp);
       putflt(av->rad, fp);
       putvec(av->gpos, fp);
       putvec(av->gdir, fp);
       return(ferror(fp) ? -1 : 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

double maxarad

Definition at line 32 of file ambient.c.

double minarad

Definition at line 33 of file ambient.c.