Back to index

radiance  4R0+20100331
Defines | Functions | Variables
srcsupp.c File Reference
#include "copyright.h"
#include "ray.h"
#include "otypes.h"
#include "source.h"
#include "cone.h"
#include "face.h"

Go to the source code of this file.

Defines

#define SRCINC   8 /* realloc increment for array */

Functions

void initstypes ()
int newsource ()
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 dir)
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)

Variables

static const char RCSid [] = "$Id: srcsupp.c,v 2.17 2008/12/06 01:08:53 greg Exp $"
SRCRECsource = NULL
int nsources = 0
SRCFUNC sfun [NUMOTYPE]

Define Documentation

#define SRCINC   8 /* realloc increment for array */

Definition at line 22 of file srcsupp.c.


Function Documentation

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  dir 
)

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 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:

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 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:

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:

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 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 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:

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:

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:

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:


Variable Documentation

int nsources = 0

Definition at line 25 of file srcsupp.c.

const char RCSid[] = "$Id: srcsupp.c,v 2.17 2008/12/06 01:08:53 greg Exp $" [static]

Definition at line 2 of file srcsupp.c.

Definition at line 27 of file srcsupp.c.

SRCREC* source = NULL

Definition at line 24 of file srcsupp.c.