Back to index

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

Go to the source code of this file.

Classes

struct  SPOT
struct  OBSCACHE
struct  SRCREC
struct  SRCINDEX
struct  VSMATERIAL
struct  SOBJECT
union  SRCFUNC
union  OBSCACHE.p
struct  OBSCACHE.p.f
struct  OBSCACHE.p.d
struct  SRCREC.sl
union  SRCREC.sa
struct  SRCREC.sa.sv

Defines

#define AIMREQT   100 /* required aim success/failure */
#define SHADCACHE   20 /* shadow cache resolution */
#define SDISTANT   01 /* source distant flag */
#define SSKIP   02 /* source skip flag */
#define SPROX   04 /* source proximity flag */
#define SSPOT   010 /* source spotlight flag */
#define SVIRTUAL   020 /* source virtual flag */
#define SFLAT   040 /* source flat flag */
#define SCIR   0100 /* source circular flag */
#define SCYL   0200 /* source cylindrical flag */
#define SFOLLOW   0400 /* source follow path flag */
#define MAXSPART   64 /* maximum partitions per source */
#define SU   0 /* U vector or partition */
#define SV   1 /* V vector or partition */
#define SW   2 /* W vector or partition */
#define S0   3 /* leaf partition */
#define snorm   ss[SW] /* normal vector for flat source */
#define initsrcindex(s)   ((s)->sn = (s)->sp = -1, (s)->np = 0)
#define clrpart(pt)   memset((char *)(pt), '\0', MAXSPART/2)
#define setpart(pt, i, v)   ((pt)[(i)>>2] |= (v)<<(((i)&3)<<1))
#define spart(pt, pi)   ((pt)[(pi)>>2] >> (((pi)&3)<<1) & 3)
#define sflatform(sn, dir)   -DOT(source[sn].snorm, dir)
#define getplaneq(c, o)   (*sfun[(o)->otype].of->getpleq)(c,o)
#define getmaxdisk(c, o)   (*sfun[(o)->otype].of->getdisk)(c,o)
#define setsource(s, o)   (*sfun[(o)->otype].of->setsrc)(s,o)

Typedefs

typedef void srcdirf_t (COLOR cv, void *np, FVECT ldir, double omega)

Functions

OBJRECfindmaterial (OBJREC *o)
void marksources (void)
void freesources (void)
int srcray (RAY *sr, RAY *r, SRCINDEX *si)
void srcvalue (RAY *r)
int sourcehit (RAY *r)
void direct (RAY *r, srcdirf_t *f, void *p)
void srcscatter (RAY *r)
int m_light (OBJREC *m, RAY *r)
void initobscache (int sn)
int srcblocker (RAY *r)
int srcblocked (RAY *r)
void freeobscache (SRCREC *s)
void markclip (OBJREC *m)
double nextssamp (RAY *r, SRCINDEX *si)
int skipparts (int ct[3], int sz[3], int pp[2], unsigned char *pt)
void nopart (SRCINDEX *si, RAY *r)
void cylpart (SRCINDEX *si, RAY *r)
void flatpart (SRCINDEX *si, RAY *r)
double scylform (int sn, FVECT dir)
void initstypes (void)
int newsource (void)
void setflatss (SRCREC *src)
void fsetsrc (SRCREC *src, OBJREC *so)
void ssetsrc (SRCREC *src, OBJREC *so)
void sphsetsrc (SRCREC *src, OBJREC *so)
void rsetsrc (SRCREC *src, OBJREC *so)
void cylsetsrc (SRCREC *src, OBJREC *so)
SPOTmakespot (OBJREC *m)
int spotout (RAY *r, SPOT *s)
double fgetmaxdisk (FVECT ocent, OBJREC *op)
double rgetmaxdisk (FVECT ocent, OBJREC *op)
double fgetplaneq (FVECT nvec, OBJREC *op)
double rgetplaneq (FVECT nvec, OBJREC *op)
int commonspot (SPOT *sp1, SPOT *sp2, FVECT org)
int commonbeam (SPOT *sp1, SPOT *sp2, FVECT org)
int checkspot (SPOT *sp, FVECT nrm)
double spotdisk (FVECT oc, OBJREC *op, SPOT *sp, FVECT pos)
double beamdisk (FVECT oc, OBJREC *op, SPOT *sp, FVECT dir)
double intercircle (FVECT cc, FVECT c1, FVECT c2, double r1s, double r2s)
void markvirtuals (void)
void addvirtuals (int sn, int nr)
void vproject (OBJREC *o, int sn, int n)
OBJRECvsmaterial (OBJREC *o)
int makevsrc (OBJREC *op, int sn, MAT4 pm)
double getdisk (FVECT oc, OBJREC *op, int sn)
int vstestvis (int f, OBJREC *o, FVECT oc, double or2, int sn)
void virtverb (int sn, FILE *fp)

Variables

SRCFUNC sfun []
SRCRECsource
int nsources

Class Documentation

struct SPOT

Definition at line 33 of file source.h.

Class Members
FVECT aim
float flen
float siz
struct OBSCACHE

Definition at line 39 of file source.h.

Class Members
OBJECT obs
union OBSCACHE p
struct SRCREC

Definition at line 53 of file source.h.

Collaboration diagram for SRCREC:
Class Members
unsigned long nhits
unsigned long ntests
OBSCACHE * obscache
union SRCREC sa
int sflags
struct SRCREC sl
FVECT sloc
OBJREC * so
float srad
FVECT ss
float ss2
struct SRCINDEX

Definition at line 87 of file source.h.

Class Members
double dom
short np
int sn
short sp
unsigned char spt
union SRCFUNC

Definition at line 129 of file source.h.

Collaboration diagram for SRCFUNC:
Class Members
VSMATERIAL * mf
SOBJECT * of
union OBSCACHE.p

Definition at line 40 of file source.h.

Class Members
p d
p f
struct OBSCACHE.p.f

Definition at line 41 of file source.h.

Class Members
FVECT u
FVECT v
struct OBSCACHE.p.d

Definition at line 44 of file source.h.

Class Members
int ax
RREAL e1
RREAL e2
FVECT o
struct SRCREC.sl

Definition at line 59 of file source.h.

Class Members
float prox
SPOT * s
union SRCREC.sa

Definition at line 63 of file source.h.

Class Members
long success
sa sv
struct SRCREC.sa.sv

Definition at line 65 of file source.h.

Class Members
short pn
int sn

Define Documentation

#define AIMREQT   100 /* required aim success/failure */

Definition at line 17 of file source.h.

#define clrpart (   pt)    memset((char *)(pt), '\0', MAXSPART/2)

Definition at line 97 of file source.h.

#define getmaxdisk (   c,
 
)    (*sfun[(o)->otype].of->getdisk)(c,o)

Definition at line 142 of file source.h.

#define getplaneq (   c,
 
)    (*sfun[(o)->otype].of->getpleq)(c,o)

Definition at line 141 of file source.h.

#define initsrcindex (   s)    ((s)->sn = (s)->sp = -1, (s)->np = 0)

Definition at line 95 of file source.h.

#define MAXSPART   64 /* maximum partitions per source */

Definition at line 78 of file source.h.

#define S0   3 /* leaf partition */

Definition at line 83 of file source.h.

#define SCIR   0100 /* source circular flag */

Definition at line 29 of file source.h.

#define SCYL   0200 /* source cylindrical flag */

Definition at line 30 of file source.h.

#define SDISTANT   01 /* source distant flag */

Definition at line 23 of file source.h.

#define setpart (   pt,
  i,
  v 
)    ((pt)[(i)>>2] |= (v)<<(((i)&3)<<1))

Definition at line 98 of file source.h.

#define setsource (   s,
 
)    (*sfun[(o)->otype].of->setsrc)(s,o)

Definition at line 143 of file source.h.

#define SFLAT   040 /* source flat flag */

Definition at line 28 of file source.h.

#define sflatform (   sn,
  dir 
)    -DOT(source[sn].snorm, dir)

Definition at line 139 of file source.h.

#define SFOLLOW   0400 /* source follow path flag */

Definition at line 31 of file source.h.

#define SHADCACHE   20 /* shadow cache resolution */

Definition at line 20 of file source.h.

#define snorm   ss[SW] /* normal vector for flat source */

Definition at line 85 of file source.h.

#define spart (   pt,
  pi 
)    ((pt)[(pi)>>2] >> (((pi)&3)<<1) & 3)

Definition at line 99 of file source.h.

#define SPROX   04 /* source proximity flag */

Definition at line 25 of file source.h.

#define SSKIP   02 /* source skip flag */

Definition at line 24 of file source.h.

#define SSPOT   010 /* source spotlight flag */

Definition at line 26 of file source.h.

#define SU   0 /* U vector or partition */

Definition at line 80 of file source.h.

#define SV   1 /* V vector or partition */

Definition at line 81 of file source.h.

#define SVIRTUAL   020 /* source virtual flag */

Definition at line 27 of file source.h.

#define SW   2 /* W vector or partition */

Definition at line 82 of file source.h.


Typedef Documentation

typedef void srcdirf_t(COLOR cv, void *np, FVECT ldir, double omega)

Definition at line 152 of file source.h.


Function Documentation

void addvirtuals ( int  sn,
int  nr 
)

Definition at line 73 of file virtuals.c.

{
       register int  i;
                            /* check relay limit first */
       if (nr <= 0)
              return;
       if (source[sn].sflags & SSKIP)
              return;
                            /* check each virtual object for projection */
       for (i = 0; i < nvobjects; i++)
                                   /* vproject() calls us recursively */
              vproject(objptr(vobject[i]), sn, nr-1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double beamdisk ( FVECT  oc,
OBJREC op,
SPOT sp,
FVECT  dir 
)

Definition at line 461 of file srcsupp.c.

{
       FVECT  onorm;
       double  offs, d, dist;
       register int  i;

       offs = getplaneq(onorm, op);
       d = -DOT(onorm, dir);
       if (d >= -FTINY && d <= FTINY)
              return(0.);
       dist = (DOT(sp->aim, onorm) - offs)/d;
       for (i = 0; i < 3; i++)
              oc[i] = sp->aim[i] + dist*dir[i];
       return(sp->siz/PI/(d*d));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int checkspot ( SPOT sp,
FVECT  nrm 
)

Definition at line 421 of file srcsupp.c.

{
       double  d, d1;

       d = DOT(sp->aim, nrm);
       if (d > FTINY)                     /* center in front? */
              return(1);
                                   /* else check horizon */
       d1 = 1. - sp->siz/(2.*PI);
       return(1.-FTINY-d*d < d1*d1);
}

Here is the caller graph for this function:

int commonbeam ( SPOT sp1,
SPOT sp2,
FVECT  org 
)

Definition at line 396 of file srcsupp.c.

{
       FVECT  cent, c1, c2;
       double  rad2, d;
       register int  i;
                                   /* move centers to common plane */
       d = DOT(sp1->aim, dir);
       for (i = 0; i < 3; i++)
              c1[i] = sp1->aim[i] - d*dir[i];
       d = DOT(sp2->aim, dir);
       for (i = 0; i < 3; i++)
              c2[i] = sp2->aim[i] - d*dir[i];
                                   /* compute overlap */
       rad2 = intercircle(cent, c1, c2, sp1->siz/PI, sp2->siz/PI);
       if (rad2 <= FTINY)
              return(0);
       VCOPY(sp1->aim, cent);
       sp1->siz = PI*rad2;
       return(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int commonspot ( SPOT sp1,
SPOT sp2,
FVECT  org 
)

Definition at line 372 of file srcsupp.c.

{
       FVECT  cent;
       double  rad2, cos1, cos2;

       cos1 = 1. - sp1->siz/(2.*PI);
       cos2 = 1. - sp2->siz/(2.*PI);
       if (sp2->siz >= 2.*PI-FTINY)              /* BIG, just check overlap */
              return(DOT(sp1->aim,sp2->aim) >= cos1*cos2 -
                                   sqrt((1.-cos1*cos1)*(1.-cos2*cos2)));
                            /* compute and check disks */
       rad2 = intercircle(cent, sp1->aim, sp2->aim,
                     1./(cos1*cos1) - 1.,  1./(cos2*cos2) - 1.);
       if (rad2 <= FTINY || normalize(cent) == 0.)
              return(0);
       VCOPY(sp1->aim, cent);
       sp1->siz = 2.*PI*(1. - 1./sqrt(1.+rad2));
       return(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void cylpart ( SRCINDEX si,
RAY r 
)

Definition at line 180 of file srcsamp.c.

{
       double  dist2, safedist2, dist2cent, rad2;
       FVECT  v;
       register SRCREC  *sp;
       int  pi;
                                   /* first check point location */
       clrpart(si->spt);
       sp = source + si->sn;
       rad2 = 1.365 * DOT(sp->ss[SV],sp->ss[SV]);
       v[0] = r->rorg[0] - sp->sloc[0];
       v[1] = r->rorg[1] - sp->sloc[1];
       v[2] = r->rorg[2] - sp->sloc[2];
       dist2 = DOT(v,sp->ss[SU]);
       safedist2 = DOT(sp->ss[SU],sp->ss[SU]);
       dist2 *= dist2 / safedist2;
       dist2cent = DOT(v,v);
       dist2 = dist2cent - dist2;
       if (dist2 <= rad2) {        /* point inside extended cylinder */
              si->np = 0;
              return;
       }
       safedist2 *= 4.*r->rweight*r->rweight/(srcsizerat*srcsizerat);
       if (dist2 <= 4.*rad2 ||            /* point too close to subdivide */
                     dist2cent >= safedist2) {   /* or too far */
              setpart(si->spt, 0, S0);
              si->np = 1;
              return;
       }
       pi = 0;
       si->np = cyl_partit(r->rorg, si->spt, &pi, MAXSPART,
                     sp->sloc, sp->ss[SU], safedist2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void cylsetsrc ( SRCREC src,
OBJREC so 
)

Definition at line 213 of file srcsupp.c.

{
       register CONE  *co;
       register int  i;
       
       src->sa.success = 4*AIMREQT-1;            /* bitch on fourth failure */
       src->so = so;
                                          /* get the cylinder */
       co = getcone(so, 0);
       if (CO_R0(co) <= FTINY)
              objerror(so, USER, "illegal source radius");
       if (CO_R0(co) > .2*co->al)         /* heuristic constraint */
              objerror(so, WARNING, "source aspect too small");
       src->sflags |= SCYL;
       for (i = 0; i < 3; i++)
              src->sloc[i] = .5 * (CO_P1(co)[i] + CO_P0(co)[i]);
       src->srad = .5*co->al;
       src->ss2 = 2.*CO_R0(co)*co->al;
                                          /* set sampling vectors */
       for (i = 0; i < 3; i++)
              src->ss[SU][i] = .5 * co->al * co->ad[i];
       src->ss[SV][0] = src->ss[SV][1] = src->ss[SV][2] = 0.0;
       for (i = 0; i < 3; i++)
              if (co->ad[i] < 0.6 && co->ad[i] > -0.6)
                     break;
       src->ss[SV][i] = 1.0;
       fcross(src->ss[SW], src->ss[SV], co->ad);
       normalize(src->ss[SW]);
       for (i = 0; i < 3; i++)
              src->ss[SW][i] *= .8559 * CO_R0(co);
       fcross(src->ss[SV], src->ss[SW], co->ad);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void direct ( RAY r,
srcdirf_t f,
void *  p 
)

Definition at line 362 of file source.c.

{
       register int  sn;
       register CONTRIB  *scp;
       SRCINDEX  si;
       int  nshadcheck, ncnts;
       int  nhits;
       double  prob, ourthresh, hwt;
       RAY  sr;
                     /* NOTE: srccnt and cntord global so no recursion */
       if (nsources <= 0)
              return;              /* no sources?! */
                                          /* potential contributions */
       initsrcindex(&si);
       for (sn = 0; srcray(&sr, r, &si); sn++) {
              if (sn >= maxcntr) {
                     maxcntr = sn + MAXSPART;
                     srccnt = (CONTRIB *)realloc((void *)srccnt,
                                   maxcntr*sizeof(CONTRIB));
                     cntord = (CNTPTR *)realloc((void *)cntord,
                                   maxcntr*sizeof(CNTPTR));
                     if ((srccnt == NULL) | (cntord == NULL))
                            error(SYSTEM, "out of memory in direct");
              }
              cntord[sn].sndx = sn;
              scp = srccnt + sn;
              scp->sno = sr.rsrc;
                                          /* compute coefficient */
              (*f)(scp->coef, p, sr.rdir, si.dom);
              cntord[sn].brt = intens(scp->coef);
              if (cntord[sn].brt <= 0.0)
                     continue;
#if SHADCACHE
                                          /* check shadow cache */
              if (si.np == 1 && srcblocked(&sr)) {
                     cntord[sn].brt = 0.0;
                     continue;
              }
#endif
              VCOPY(scp->dir, sr.rdir);
              copycolor(sr.rcoef, scp->coef);
                                          /* compute potential */
              sr.revf = srcvalue;
              rayvalue(&sr);
              multcolor(sr.rcol, sr.rcoef);
              copycolor(scp->val, sr.rcol);
              cntord[sn].brt = bright(sr.rcol);
       }
                                          /* sort contributions */
       qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
       {                                  /* find last */
              register int  l, m;

              ncnts = l = sn;
              sn = 0;
              while ((m = (sn + ncnts) >> 1) != l) {
                     if (cntord[m].brt > 0.0)
                            sn = m;
                     else
                            ncnts = m;
                     l = m;
              }
       }
       if (ncnts == 0)
              return;              /* no contributions! */
                                                /* accumulate tail */
        for (sn = ncnts-1; sn > 0; sn--)
                cntord[sn-1].brt += cntord[sn].brt;
                                          /* compute number to check */
       nshadcheck = pow((double)ncnts, shadcert) + .5;
                                          /* modify threshold */
       ourthresh = shadthresh / r->rweight;
                                          /* test for shadows */
       for (nhits = 0, hwt = 0.0, sn = 0; sn < ncnts;
                     hwt += (double)source[scp->sno].nhits /
                            (double)source[scp->sno].ntests,
                     sn++) {
                                          /* check threshold */
              if ((sn+nshadcheck>=ncnts ? cntord[sn].brt :
                            cntord[sn].brt-cntord[sn+nshadcheck].brt)
                            < ourthresh*bright(r->rcol))
                     break;
              scp = srccnt + cntord[sn].sndx;
                                          /* test for hit */
              rayorigin(&sr, SHADOW, r, NULL);
              copycolor(sr.rcoef, scp->coef);
              VCOPY(sr.rdir, scp->dir);
              sr.rsrc = scp->sno;
                                          /* keep statistics */
              if (source[scp->sno].ntests++ > 0xfffffff0) {
                     source[scp->sno].ntests >>= 1;
                     source[scp->sno].nhits >>= 1;
              }
              if (localhit(&sr, &thescene) &&
                            ( sr.ro != source[scp->sno].so ||
                            source[scp->sno].sflags & SFOLLOW )) {
                                          /* follow entire path */
                     raycont(&sr);
                     if (trace != NULL)
                            (*trace)(&sr);       /* trace execution */
                     if (bright(sr.rcol) <= FTINY) {
#if SHADCACHE
                            if ((scp <= srccnt || scp[-1].sno != scp->sno)
                                          && (scp >= srccnt+ncnts-1 ||
                                              scp[1].sno != scp->sno))
                                   srcblocker(&sr);
#endif
                            continue;     /* missed! */
                     }
                     rayparticipate(&sr);
                     multcolor(sr.rcol, sr.rcoef);
                     copycolor(scp->val, sr.rcol);
              } else if (trace != NULL &&
                     (source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW))
                                          == (SDISTANT|SFOLLOW) &&
                            sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) {
                     (*trace)(&sr);              /* trace execution */
                     /* skip call to rayparticipate() & scp->val update */
              }
                                          /* add contribution if hit */
              addcolor(r->rcol, scp->val);
              nhits++;
              source[scp->sno].nhits++;
       }
                                   /* source hit rate */
       if (hwt > FTINY)
              hwt = (double)nhits / hwt;
       else
              hwt = 0.5;
#ifdef DEBUG
       sprintf(errmsg, "%d tested, %d untested, %f conditional hit rate\n",
                     sn, ncnts-sn, hwt);
       eputs(errmsg);
#endif
                                   /* add in untested sources */
       for ( ; sn < ncnts; sn++) {
              scp = srccnt + cntord[sn].sndx;
              prob = hwt * (double)source[scp->sno].nhits /
                            (double)source[scp->sno].ntests;
              if (prob < 1.0)
                     scalecolor(scp->val, prob);
              addcolor(r->rcol, scp->val);
       }
}

Here is the call graph for this function:

double fgetmaxdisk ( FVECT  ocent,
OBJREC op 
)

Definition at line 301 of file srcsupp.c.

{
       double  maxrad2;
       double  d;
       register int  i, j;
       register FACE  *f;
       
       f = getface(op);
       if (f->area == 0.)
              return(0.);
       for (i = 0; i < 3; i++) {
              ocent[i] = 0.;
              for (j = 0; j < f->nv; j++)
                     ocent[i] += VERTEX(f,j)[i];
              ocent[i] /= (double)f->nv;
       }
       d = DOT(ocent,f->norm);
       for (i = 0; i < 3; i++)
              ocent[i] += (f->offset - d)*f->norm[i];
       maxrad2 = 0.;
       for (j = 0; j < f->nv; j++) {
              d = dist2(VERTEX(f,j), ocent);
              if (d > maxrad2)
                     maxrad2 = d;
       }
       return(maxrad2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double fgetplaneq ( FVECT  nvec,
OBJREC op 
)

Definition at line 346 of file srcsupp.c.

{
       register FACE  *fo;

       fo = getface(op);
       VCOPY(nvec, fo->norm);
       return(fo->offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void flatpart ( SRCINDEX si,
RAY r 
)

Definition at line 257 of file srcsamp.c.

{
       register RREAL  *vp;
       FVECT  v;
       double  du2, dv2;
       int  pi;

       clrpart(si->spt);
       vp = source[si->sn].sloc;
       v[0] = r->rorg[0] - vp[0];
       v[1] = r->rorg[1] - vp[1];
       v[2] = r->rorg[2] - vp[2];
       vp = source[si->sn].snorm;
       if (DOT(v,vp) <= 0.) {             /* behind source */
              si->np = 0;
              return;
       }
       dv2 = 2.*r->rweight/srcsizerat;
       dv2 *= dv2;
       vp = source[si->sn].ss[SU];
       du2 = dv2 * DOT(vp,vp);
       vp = source[si->sn].ss[SV];
       dv2 *= DOT(vp,vp);
       pi = 0;
       si->np = flt_partit(r->rorg, si->spt, &pi, MAXSPART,
              source[si->sn].sloc,
              source[si->sn].ss[SU], source[si->sn].ss[SV], du2, dv2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void freeobscache ( SRCREC s)

Definition at line 281 of file srcobstr.c.

{
       if (srcp->obscache == NULL)
              return;
       free((void *)srcp->obscache);
       srcp->obscache = NULL;
}

Here is the caller graph for this function:

void freesources ( void  )

Definition at line 159 of file source.c.

{
       if (nsources > 0) {
#if SHADCACHE
              while (nsources--)
                     freeobscache(&source[nsources]);
#endif
              free((void *)source);
              source = NULL;
              nsources = 0;
       }
       if (maxcntr <= 0)
              return;
       free((void *)srccnt);
       srccnt = NULL;
       free((void *)cntord);
       cntord = NULL;
       maxcntr = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void fsetsrc ( SRCREC src,
OBJREC so 
)

Definition at line 92 of file srcsupp.c.

{
       register FACE  *f;
       register int  i, j;
       double  d;
       
       src->sa.success = 2*AIMREQT-1;            /* bitch on second failure */
       src->so = so;
                                          /* get the face */
       f = getface(so);
       if (f->area == 0.0)
              objerror(so, USER, "zero source area");
                                          /* find the center */
       for (j = 0; j < 3; j++) {
              src->sloc[j] = 0.0;
              for (i = 0; i < f->nv; i++)
                     src->sloc[j] += VERTEX(f,i)[j];
              src->sloc[j] /= (double)f->nv;
       }
       if (!inface(src->sloc, f))
              objerror(so, USER, "cannot hit source center");
       src->sflags |= SFLAT;
       VCOPY(src->snorm, f->norm);
       src->ss2 = f->area;
                                          /* find maximum radius */
       src->srad = 0.;
       for (i = 0; i < f->nv; i++) {
              d = dist2(VERTEX(f,i), src->sloc);
              if (d > src->srad)
                     src->srad = d;
       }
       src->srad = sqrt(src->srad);
                                          /* compute size vectors */
       if (f->nv == 4)                           /* parallelogram case */
              for (j = 0; j < 3; j++) {
                     src->ss[SU][j] = .5*(VERTEX(f,1)[j]-VERTEX(f,0)[j]);
                     src->ss[SV][j] = .5*(VERTEX(f,3)[j]-VERTEX(f,0)[j]);
              }
       else
              setflatss(src);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double getdisk ( FVECT  oc,
OBJREC op,
int  sn 
)

Here is the caller graph for this function:

void initobscache ( int  sn)

Definition at line 59 of file srcobstr.c.

{
       register SRCREC *srcp = &source[sn];
       int           cachelen;
       FVECT         rorg, rdir;
       RREAL         d;
       int           i, j, k;
       int           ax, ax1, ax2;

       if (srcp->sflags & (SSKIP|SPROX|SSPOT|SVIRTUAL))
              return;                     /* don't cache these */
       if (srcp->sflags & SDISTANT)
              cachelen = 4*SHADCACHE*SHADCACHE;
       else if (srcp->sflags & SFLAT)
              cachelen = SHADCACHE*SHADCACHE*3 + (SHADCACHE&1)*SHADCACHE*4;
       else /* spherical distribution */
              cachelen = SHADCACHE*SHADCACHE*6;
                                   /* allocate cache */
       srcp->obscache = (OBSCACHE *)malloc(sizeof(OBSCACHE) +
                                          sizeof(OBJECT)*(cachelen-1));
       if (srcp->obscache == NULL)
              error(SYSTEM, "out of memory in initobscache()");
                                   /* set parameters */
       if (srcp->sflags & SDISTANT) {
              RREAL   amax = 0;
              for (ax1 = 3; ax1--; )
                     if (ABS(srcp->sloc[ax1]) > amax) {
                            amax = ABS(srcp->sloc[ax1]);
                            ax = ax1;
                     }
              srcp->obscache->p.d.ax = ax;
              ax1 = (ax+1)%3;
              ax2 = (ax+2)%3;
              VCOPY(srcp->obscache->p.d.o, thescene.cuorg);
              if (srcp->sloc[ax] > 0)
                     srcp->obscache->p.d.o[ax] += thescene.cusize;
              if (srcp->sloc[ax1] < 0)
                     srcp->obscache->p.d.o[ax1] += thescene.cusize *
                                   srcp->sloc[ax1] / amax;
              if (srcp->sloc[ax2] < 0)
                     srcp->obscache->p.d.o[ax2] += thescene.cusize *
                                   srcp->sloc[ax2] / amax;
              srcp->obscache->p.d.e1 = 1. / (thescene.cusize*(1. +
                            fabs(srcp->sloc[ax1])/amax));
              srcp->obscache->p.d.e2 = 1. / (thescene.cusize*(1. +
                            fabs(srcp->sloc[ax2])/amax));
       } else if (srcp->sflags & SFLAT) {
              VCOPY(srcp->obscache->p.f.u, srcp->ss[SU]);
              normalize(srcp->obscache->p.f.u);
              fcross(srcp->obscache->p.f.v,
                            srcp->snorm, srcp->obscache->p.f.u);
       }
                                   /* clear cache */
       for (i = cachelen; i--; )
              srcp->obscache->obs[i] = OVOID;
                                   /* cast shadow rays */
       if (srcp->sflags & SDISTANT) {
              for (k = 3; k--; )
                     rdir[k] = -srcp->sloc[k];
              for (i = 2*SHADCACHE; i--; )
                     for (j = 2*SHADCACHE; j--; ) {
                            VCOPY(rorg, srcp->obscache->p.d.o);
                            rorg[ax1] += (i+.5) /
                                   (2*SHADCACHE*srcp->obscache->p.d.e1);
                            rorg[ax2] += (j+.5) /
                                   (2*SHADCACHE*srcp->obscache->p.d.e2);
                            castshadow(sn, rorg, rdir);
                     }
       } else if (srcp->sflags & SFLAT) {
              d = 0.01*srcp->srad;
              VSUM(rorg, srcp->sloc, srcp->snorm, d);
              for (i = SHADCACHE; i--; )
                     for (j = SHADCACHE; j--; ) {
                            d = 2./SHADCACHE*(i+.5) - 1.;
                            VSUM(rdir, srcp->snorm,
                                          srcp->obscache->p.f.u, d);
                            d = 2./SHADCACHE*(j+.5) - 1.;
                            VSUM(rdir, rdir, srcp->obscache->p.f.v, d);
                            normalize(rdir);
                            castshadow(sn, rorg, rdir);
                     }
              for (k = 2; k--; )
                  for (i = SHADCACHE; i--; )
                     for (j = SHADCACHE>>1; j--; ) {
                            d = 2./SHADCACHE*(i+.5) - 1.;
                            if (k)
                                   VSUM(rdir, srcp->obscache->p.f.u,
                                          srcp->obscache->p.f.v, d);
                            else
                                   VSUM(rdir, srcp->obscache->p.f.v,
                                          srcp->obscache->p.f.u, d);
                            d = 1. - 2./SHADCACHE*(j+.5);
                            VSUM(rdir, rdir, srcp->snorm, d);
                            normalize(rdir);
                            castshadow(sn, rorg, rdir);
                            d = 2.*DOT(rdir, srcp->snorm);
                            rdir[0] = d*srcp->snorm[0] - rdir[0];
                            rdir[1] = d*srcp->snorm[1] - rdir[1];
                            rdir[2] = d*srcp->snorm[2] - rdir[2];
                            castshadow(sn, rorg, rdir);
                     }
       } else /* spherical distribution */
           for (k = 6; k--; ) {
              ax = k%3;
              ax1 = (k+1)%3;
              ax2 = (k+2)%3;
              for (i = SHADCACHE; i--; )
                     for (j = SHADCACHE; j--; ) {
                            rdir[0]=rdir[1]=rdir[2] = 0.;
                            rdir[ax] = k<3 ? 1. : -1.;
                            rdir[ax1] = 2./SHADCACHE*(i+.5) - 1.;
                            rdir[ax2] = 2./SHADCACHE*(j+.5) - 1.;
                            normalize(rdir);
                            d = 1.05*srcp->srad;
                            VSUM(rorg, srcp->sloc, rdir, d);
                            castshadow(sn, rorg, rdir);
                     }
           }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void initstypes ( void  )

Definition at line 31 of file srcsupp.c.

{
       extern VSMATERIAL  mirror_vs, direct1_vs, direct2_vs;
       static SOBJECT  fsobj = {fsetsrc, flatpart, fgetplaneq, fgetmaxdisk};
       static SOBJECT  ssobj = {ssetsrc, nopart};
       static SOBJECT  sphsobj = {sphsetsrc, nopart};
       static SOBJECT  cylsobj = {cylsetsrc, cylpart};
       static SOBJECT  rsobj = {rsetsrc, flatpart, rgetplaneq, rgetmaxdisk};

       sfun[MAT_MIRROR].mf = &mirror_vs;
       sfun[MAT_DIRECT1].mf = &direct1_vs;
       sfun[MAT_DIRECT2].mf = &direct2_vs;
       sfun[OBJ_FACE].of = &fsobj;
       sfun[OBJ_SOURCE].of = &ssobj;
       sfun[OBJ_SPHERE].of = &sphsobj;
       sfun[OBJ_CYLINDER].of = &cylsobj;
       sfun[OBJ_RING].of = &rsobj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

double intercircle ( FVECT  cc,
FVECT  c1,
FVECT  c2,
double  r1s,
double  r2s 
)

Definition at line 483 of file srcsupp.c.

{
       double  a2, d2, l;
       FVECT  disp;
       register int  i;

       for (i = 0; i < 3; i++)
              disp[i] = c2[i] - c1[i];
       d2 = DOT(disp,disp);
                                   /* circle within overlap? */
       if (r1s < r2s) {
              if (r2s >= r1s + d2) {
                     VCOPY(cc, c1);
                     return(r1s);
              }
       } else {
              if (r1s >= r2s + d2) {
                     VCOPY(cc, c2);
                     return(r2s);
              }
       }
       a2 = .25*(2.*(r1s+r2s) - d2 - (r2s-r1s)*(r2s-r1s)/d2);
                                   /* no overlap? */
       if (a2 <= 0.)
              return(0.);
                                   /* overlap, compute center */
       l = sqrt((r1s - a2)/d2);
       for (i = 0; i < 3; i++)
              cc[i] = c1[i] + l*disp[i];
       return(a2);
}

Here is the caller graph for this function:

int m_light ( OBJREC m,
RAY r 
)
SPOT* makespot ( OBJREC m)

Definition at line 250 of file srcsupp.c.

{
       register SPOT  *ns;

       if ((ns = (SPOT *)m->os) != NULL)
              return(ns);
       if ((ns = (SPOT *)malloc(sizeof(SPOT))) == NULL)
              return(NULL);
       if (m->oargs.farg[3] <= FTINY)
              objerror(m, USER, "zero angle");
       ns->siz = 2.0*PI * (1.0 - cos(PI/180.0/2.0 * m->oargs.farg[3]));
       VCOPY(ns->aim, m->oargs.farg+4);
       if ((ns->flen = normalize(ns->aim)) == 0.0)
              objerror(m, USER, "zero focus vector");
       m->os = (char *)ns;
       return(ns);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int makevsrc ( OBJREC op,
int  sn,
MAT4  pm 
)

Here is the caller graph for this function:

void markclip ( OBJREC m)

Definition at line 334 of file srcobstr.c.

{
       OBJECT  *set2add, *oldset;

       m_clip(m, NULL);            /* initialize modifier list */
       if ((set2add = (OBJECT *)m->os) == NULL || !set2add[0])
              return;

       if (antimodlist == NULL) {  /* start of list */
              antimodlist = setsave(set2add);
              return;
       }
                                   /* else add to previous list */
       oldset = antimodlist;
       antimodlist = (OBJECT *)malloc((oldset[0]+set2add[0]+1)*sizeof(OBJECT));
       if (antimodlist == NULL)
              error(SYSTEM, "out of memory in markclip");
       setunion(antimodlist, oldset, set2add);
       free((void *)oldset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void marksources ( void  )

Definition at line 72 of file source.c.

{
       int  foundsource = 0;
       int  i;
       register OBJREC  *o, *m;
       register int  ns;
                                   /* initialize dispatch table */
       initstypes();
                                   /* find direct sources */
       for (i = 0; i < nsceneobjs; i++) {
       
              o = objptr(i);

              if (!issurface(o->otype) || o->omod == OVOID)
                     continue;
                                   /* find material */
              m = findmaterial(objptr(o->omod));
              if (m == NULL)
                     continue;
              if (m->otype == MAT_CLIP) {
                     markclip(m);  /* special case for antimatter */
                     continue;
              }
              if (!islight(m->otype))
                     continue;     /* not source modifier */
       
              if (m->oargs.nfargs != (m->otype == MAT_GLOW ? 4 :
                            m->otype == MAT_SPOT ? 7 : 3))
                     objerror(m, USER, "bad # arguments");

              if (m->otype == MAT_GLOW &&
                            o->otype != OBJ_SOURCE &&
                            m->oargs.farg[3] <= FTINY)
                     continue;                   /* don't bother */
              if (m->oargs.farg[0] <= FTINY && m->oargs.farg[1] <= FTINY &&
                            m->oargs.farg[2] <= FTINY)
                     continue;                   /* don't bother */

              if (sfun[o->otype].of == NULL ||
                            sfun[o->otype].of->setsrc == NULL)
                     objerror(o, USER, "illegal material");

              if ((ns = newsource()) < 0)
                     goto memerr;

              setsource(&source[ns], o);

              if (m->otype == MAT_GLOW) {
                     source[ns].sflags |= SPROX;
                     source[ns].sl.prox = m->oargs.farg[3];
                     if (source[ns].sflags & SDISTANT)
                            source[ns].sflags |= SSKIP;
              } else if (m->otype == MAT_SPOT) {
                     source[ns].sflags |= SSPOT;
                     if ((source[ns].sl.s = makespot(m)) == NULL)
                            goto memerr;
                     if (source[ns].sflags & SFLAT &&
                            !checkspot(source[ns].sl.s,source[ns].snorm)) {
                            objerror(o, WARNING,
                                   "invalid spotlight direction");
                            source[ns].sflags |= SSKIP;
                     }
              }
#if  SHADCACHE
              initobscache(ns);
#endif
              if (!(source[ns].sflags & SSKIP))
                     foundsource++;
       }
       if (!foundsource) {
              error(WARNING, "no light sources found");
              return;
       }
       markvirtuals();                    /* find and add virtual sources */
                            /* allocate our contribution arrays */
       maxcntr = nsources + MAXSPART;     /* start with this many */
       srccnt = (CONTRIB *)malloc(maxcntr*sizeof(CONTRIB));
       cntord = (CNTPTR *)malloc(maxcntr*sizeof(CNTPTR));
       if ((srccnt == NULL) | (cntord == NULL))
              goto memerr;
       return;
memerr:
       error(SYSTEM, "out of memory in marksources");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void markvirtuals ( void  )

Definition at line 30 of file virtuals.c.

{
       register OBJREC  *o;
       register int  i;
                                   /* check number of direct relays */
       if (directrelay <= 0)
              return;
                                   /* find virtual source objects */
       for (i = 0; i < nsceneobjs; i++) {
              o = objptr(i);
              if (!issurface(o->otype) || o->omod == OVOID)
                     continue;
              if (!isvlight(vsmaterial(o)->otype))
                     continue;
              if (sfun[o->otype].of == NULL ||
                            sfun[o->otype].of->getpleq == NULL) {
                     objerror(o,WARNING,"secondary sources not supported");
                     continue;
              }
              if (nvobjects == 0)
                     vobject = (OBJECT *)malloc(sizeof(OBJECT));
              else
                     vobject = (OBJECT *)realloc((void *)vobject,
                            (unsigned)(nvobjects+1)*sizeof(OBJECT));
              if (vobject == NULL)
                     error(SYSTEM, "out of memory in addvirtuals");
              vobject[nvobjects++] = i;
       }
       if (nvobjects == 0)
              return;
#ifdef DEBUG
       fprintf(stderr, "found %d virtual source objects\n", nvobjects);
#endif
                                   /* append virtual sources */
       for (i = nsources; i-- > 0; )
              addvirtuals(i, directrelay);
                                   /* done with our object list */
       free((void *)vobject);
       nvobjects = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int newsource ( void  )

Definition at line 52 of file srcsupp.c.

{
       if (nsources == 0)
              source = (SRCREC *)malloc(SRCINC*sizeof(SRCREC));
       else if (nsources%SRCINC == 0)
              source = (SRCREC *)realloc((void *)source,
                            (unsigned)(nsources+SRCINC)*sizeof(SRCREC));
       if (source == NULL)
              return(-1);
       source[nsources].sflags = 0;
       source[nsources].nhits = 1;
       source[nsources].ntests = 2;       /* initial hit probability = 50% */
#if SHADCACHE
       source[nsources].obscache = NULL;
#endif
       return(nsources++);
}

Here is the caller graph for this function:

double nextssamp ( RAY r,
SRCINDEX si 
)

Definition at line 23 of file srcsamp.c.

{
       int  cent[3], size[3], parr[2];
       SRCREC  *srcp;
       FVECT  vpos;
       double  d;
       register int  i;
nextsample:
       while (++si->sp >= si->np) {       /* get next sample */
              if (++si->sn >= nsources)
                     return(0.0);  /* no more */
              if (source[si->sn].sflags & SSKIP)
                     si->np = 0;
              else if (srcsizerat <= FTINY)
                     nopart(si, r);
              else {
                     for (i = si->sn; source[i].sflags & SVIRTUAL;
                                   i = source[i].sa.sv.sn)
                            ;             /* partition source */
                     (*sfun[source[i].so->otype].of->partit)(si, r);
              }
              si->sp = -1;
       }
                                   /* get partition */
       cent[0] = cent[1] = cent[2] = 0;
       size[0] = size[1] = size[2] = MAXSPART;
       parr[0] = 0; parr[1] = si->sp;
       if (!skipparts(cent, size, parr, si->spt))
              error(CONSISTENCY, "bad source partition in nextssamp");
                                   /* compute sample */
       srcp = source + si->sn;
       if (dstrsrc > FTINY) {                    /* jitter sample */
              dimlist[ndims] = si->sn + 8831;
              dimlist[ndims+1] = si->sp + 3109;
              d = urand(ilhash(dimlist,ndims+2)+samplendx);
              if (srcp->sflags & SFLAT) {
                     multisamp(vpos, 2, d);
                     vpos[SW] = 0.5;
              } else
                     multisamp(vpos, 3, d);
              for (i = 0; i < 3; i++)
                     vpos[i] = dstrsrc * (1. - 2.*vpos[i]) *
                                   (double)size[i]/MAXSPART;
       } else
              vpos[0] = vpos[1] = vpos[2] = 0.0;

       for (i = 0; i < 3; i++)
              vpos[i] += (double)cent[i]/MAXSPART;
                                   /* avoid circular aiming failures */
       if ((srcp->sflags & SCIR) && (si->np > 1 || dstrsrc > 0.7)) {
              FVECT  trim;
              if (srcp->sflags & (SFLAT|SDISTANT)) {
                     d = 1.12837917;             /* correct setflatss() */
                     trim[SU] = d*sqrt(1.0 - 0.5*vpos[SV]*vpos[SV]);
                     trim[SV] = d*sqrt(1.0 - 0.5*vpos[SU]*vpos[SU]);
                     trim[SW] = 0.0;
              } else {
                     trim[SW] = trim[SU] = vpos[SU]*vpos[SU];
                     d = vpos[SV]*vpos[SV];
                     if (d > trim[SW]) trim[SW] = d;
                     trim[SU] += d;
                     d = vpos[SW]*vpos[SW];
                     if (d > trim[SW]) trim[SW] = d;
                     trim[SU] += d;
                     if (trim[SU] > FTINY*FTINY) {
                            d = 1.0/0.7236;      /* correct sphsetsrc() */
                            trim[SW] = trim[SV] = trim[SU] =
                                          d*sqrt(trim[SW]/trim[SU]);
                     } else
                            trim[SW] = trim[SV] = trim[SU] = 0.0;
              }
              for (i = 0; i < 3; i++)
                     vpos[i] *= trim[i];
       }
                                   /* compute direction */
       for (i = 0; i < 3; i++)
              r->rdir[i] = srcp->sloc[i] +
                            vpos[SU]*srcp->ss[SU][i] +
                            vpos[SV]*srcp->ss[SV][i] +
                            vpos[SW]*srcp->ss[SW][i];

       if (!(srcp->sflags & SDISTANT))
              for (i = 0; i < 3; i++)
                     r->rdir[i] -= r->rorg[i];
                                   /* compute distance */
       if ((d = normalize(r->rdir)) == 0.0)
              goto nextsample;            /* at source! */

                                   /* compute sample size */
       if (srcp->sflags & SFLAT) {
              si->dom = sflatform(si->sn, r->rdir);
              si->dom *= size[SU]*size[SV]/(MAXSPART*(double)MAXSPART);
       } else if (srcp->sflags & SCYL) {
              si->dom = scylform(si->sn, r->rdir);
              si->dom *= size[SU]/(double)MAXSPART;
       } else {
              si->dom = size[SU]*size[SV]*(double)size[SW] /
                            (MAXSPART*MAXSPART*(double)MAXSPART) ;
       }
       if (srcp->sflags & SDISTANT) {
              si->dom *= srcp->ss2;
              return(FHUGE);
       }
       if (si->dom <= 1e-4)
              goto nextsample;            /* behind source? */
       si->dom *= srcp->ss2/(d*d);
       return(d);           /* sample OK, return distance */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nopart ( SRCINDEX si,
RAY r 
)

Definition at line 169 of file srcsamp.c.

{
       clrpart(si->spt);
       setpart(si->spt, 0, S0);
       si->np = 1;
}

Here is the caller graph for this function:

double rgetmaxdisk ( FVECT  ocent,
OBJREC op 
)

Definition at line 333 of file srcsupp.c.

{
       register CONE  *co;
       
       co = getcone(op, 0);
       VCOPY(ocent, CO_P0(co));
       return(CO_R1(co)*CO_R1(co));
}

Here is the call graph for this function:

Here is the caller graph for this function:

double rgetplaneq ( FVECT  nvec,
OBJREC op 
)

Definition at line 359 of file srcsupp.c.

{
       register CONE  *co;

       co = getcone(op, 0);
       VCOPY(nvec, co->ad);
       return(DOT(nvec, CO_P0(co)));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void rsetsrc ( SRCREC src,
OBJREC so 
)

Definition at line 189 of file srcsupp.c.

{
       register CONE  *co;
       
       src->sa.success = 2*AIMREQT-1;            /* bitch on second failure */
       src->so = so;
                                          /* get the ring */
       co = getcone(so, 0);
       if (CO_R1(co) <= FTINY)
              objerror(so, USER, "illegal source radius");
       VCOPY(src->sloc, CO_P0(co));
       if (CO_R0(co) > 0.0)
              objerror(so, USER, "cannot hit source center");
       src->sflags |= (SFLAT|SCIR);
       VCOPY(src->snorm, co->ad);
       src->srad = CO_R1(co);
       src->ss2 = PI * src->srad * src->srad;
       setflatss(src);
}

Here is the call graph for this function:

Here is the caller graph for this function:

double scylform ( int  sn,
FVECT  dir 
)

Definition at line 341 of file srcsamp.c.

{
       register RREAL  *dv;
       double  d;

       dv = source[sn].ss[SU];
       d = DOT(dir, dv);
       d *= d / DOT(dv,dv);
       return(sqrt(1. - d));
}

Here is the caller graph for this function:

void setflatss ( SRCREC src)

Definition at line 72 of file srcsupp.c.

{
       double  mult;
       register int  i;

       src->ss[SV][0] = src->ss[SV][1] = src->ss[SV][2] = 0.0;
       for (i = 0; i < 3; i++)
              if (src->snorm[i] < 0.6 && src->snorm[i] > -0.6)
                     break;
       src->ss[SV][i] = 1.0;
       fcross(src->ss[SU], src->ss[SV], src->snorm);
       mult = .5 * sqrt( src->ss2 / DOT(src->ss[SU],src->ss[SU]) );
       for (i = 0; i < 3; i++)
              src->ss[SU][i] *= mult;
       fcross(src->ss[SV], src->snorm, src->ss[SU]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int skipparts ( int  ct[3],
int  sz[3],
int  pp[2],
unsigned char *  pt 
)

Here is the caller graph for this function:

int sourcehit ( RAY r)
void sphsetsrc ( SRCREC src,
OBJREC so 
)

Definition at line 165 of file srcsupp.c.

{
       register int  i;

       src->sa.success = 2*AIMREQT-1;            /* bitch on second failure */
       src->so = so;
       if (so->oargs.nfargs != 4)
              objerror(so, USER, "bad # arguments");
       if (so->oargs.farg[3] <= FTINY)
              objerror(so, USER, "illegal source radius");
       src->sflags |= SCIR;
       VCOPY(src->sloc, so->oargs.farg);
       src->srad = so->oargs.farg[3];
       src->ss2 = PI * src->srad * src->srad;
       for (i = 0; i < 3; i++)
              src->ss[SU][i] = src->ss[SV][i] = src->ss[SW][i] = 0.0;
       for (i = 0; i < 3; i++)
              src->ss[i][i] = 0.7236 * so->oargs.farg[3];
}

Here is the call graph for this function:

Here is the caller graph for this function:

double spotdisk ( FVECT  oc,
OBJREC op,
SPOT sp,
FVECT  pos 
)

Definition at line 437 of file srcsupp.c.

{
       FVECT  onorm;
       double  offs, d, dist;
       register int  i;

       offs = getplaneq(onorm, op);
       d = -DOT(onorm, sp->aim);
       if (d >= -FTINY && d <= FTINY)
              return(0.);
       dist = (DOT(pos, onorm) - offs)/d;
       if (dist < 0.)
              return(0.);
       for (i = 0; i < 3; i++)
              oc[i] = pos[i] + dist*sp->aim[i];
       return(sp->siz*dist*dist/PI/(d*d));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int spotout ( RAY r,
SPOT s 
)

Definition at line 271 of file srcsupp.c.

{
       double  d;
       FVECT  vd;
       
       if (s == NULL)
              return(0);
       if (s->flen < -FTINY) {            /* distant source */
              vd[0] = s->aim[0] - r->rorg[0];
              vd[1] = s->aim[1] - r->rorg[1];
              vd[2] = s->aim[2] - r->rorg[2];
              d = DOT(r->rdir,vd);
              /*                   wrong side?
              if (d <= FTINY)
                     return(1);    */
              d = DOT(vd,vd) - d*d;
              if (PI*d > s->siz)
                     return(1);    /* out */
              return(0);    /* OK */
       }
                                   /* local source */
       if (s->siz < 2.0*PI * (1.0 + DOT(s->aim,r->rdir)))
              return(1);    /* out */
       return(0);    /* OK */
}

Here is the caller graph for this function:

int srcblocked ( RAY r)

Definition at line 313 of file srcobstr.c.

{
       OBJECT  obs = *srcobstructp(r);
       OBJREC  *op;

       if (obs == OVOID)
              return(0);
       op = objptr(obs);           /* check blocker intersection */
       if (!(*ofun[op->otype].funp)(op, r))
              return(0);
       if (source[r->rsrc].sflags & SDISTANT)
              return(1);
       op = source[r->rsrc].so;    /* check source intersection */
       if (!(*ofun[op->otype].funp)(op, r))
              return(1);
       rayclear(r);
       return(0);                  /* source in front */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int srcblocker ( RAY r)

Here is the caller graph for this function:

int srcray ( RAY sr,
RAY r,
SRCINDEX si 
)
void srcscatter ( RAY r)
void srcvalue ( RAY r)
void ssetsrc ( SRCREC src,
OBJREC so 
)

Definition at line 138 of file srcsupp.c.

{
       double  theta;
       
       src->sa.success = 2*AIMREQT-1;            /* bitch on second failure */
       src->so = so;
       if (so->oargs.nfargs != 4)
              objerror(so, USER, "bad arguments");
       src->sflags |= (SDISTANT|SCIR);
       VCOPY(src->sloc, so->oargs.farg);
       if (normalize(src->sloc) == 0.0)
              objerror(so, USER, "zero direction");
       theta = PI/180.0/2.0 * so->oargs.farg[3];
       if (theta <= FTINY)
              objerror(so, USER, "zero size");
       src->ss2 = 2.0*PI * (1.0 - cos(theta));
                                   /* the following is approximate */
       src->srad = sqrt(src->ss2/PI);
       VCOPY(src->snorm, src->sloc);
       setflatss(src);                    /* hey, whatever works */
       src->ss[SW][0] = src->ss[SW][1] = src->ss[SW][2] = 0.0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void virtverb ( int  sn,
FILE *  fp 
)

Here is the caller graph for this function:

void vproject ( OBJREC o,
int  sn,
int  n 
)

Definition at line 92 of file virtuals.c.

{
       register int  i;
       register VSMATERIAL  *vsmat;
       MAT4  proj;
       int  ns;

       if (o == source[sn].so)     /* objects cannot project themselves */
              return;
                            /* get virtual source material */
       vsmat = sfun[vsmaterial(o)->otype].mf;
                            /* project virtual sources */
       for (i = 0; i < vsmat->nproj; i++)
              if ((*vsmat->vproj)(proj, o, &source[sn], i))
                     if ((ns = makevsrc(o, sn, proj)) >= 0) {
                            source[ns].sa.sv.pn = i;
#ifdef DEBUG
                            virtverb(ns, stderr);
#endif
                            addvirtuals(ns, n);
                     }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 121 of file virtuals.c.

{
       register int  i;
       register OBJREC  *m;

       i = o->omod;
       m = findmaterial(objptr(i));
       if (m == NULL)
              return(objptr(i));
       if (m->otype != MAT_ILLUM || m->oargs.nsargs < 1 ||
                     !strcmp(m->oargs.sarg[0], VOIDID) ||
                     (i = lastmod(objndx(m), m->oargs.sarg[0])) == OVOID)
              return(m);           /* direct modifier */
       return(objptr(i));          /* illum alternate */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int vstestvis ( int  f,
OBJREC o,
FVECT  oc,
double  or2,
int  sn 
)

Here is the caller graph for this function:


Variable Documentation

int nsources

Definition at line 25 of file srcsupp.c.

Definition at line 27 of file srcsupp.c.

Definition at line 24 of file srcsupp.c.