Example #1
0
File: rv2.c Project: NREL/Radiance
void
getfocus(				/* set focus distance */
	char *s
)
{
	char  buf[64];
	double	dist;

	if (sscanf(s, "%lf", &dist) < 1) {
		int	x, y;
		RAY	thisray;
		if (dev->getcur == NULL)
			return;
		(*dev->comout)("Pick focus point\n");
		if ((*dev->getcur)(&x, &y) == ABORT)
			return;
		if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
			&ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
			error(COMMAND, "not on image");
			return;
		}
		rayorigin(&thisray, PRIMARY, NULL, NULL);
		if (!localhit(&thisray, &thescene)) {
			error(COMMAND, "not a local object");
			return;
		}
		dist = thisray.rot;
	} else if (dist <= .0) {
		error(COMMAND, "focus distance must be positive");
		return;
	}
	ourview.vdist = dist;
	sprintf(buf, "Focus distance set to %f\n", dist);
	(*dev->comout)(buf);
}
Example #2
0
static int				/* cast source ray to first blocker */
castshadow(int sn, FVECT rorg, FVECT rdir)
{
	RAY     rt;
	
	VCOPY(rt.rorg, rorg);
	VCOPY(rt.rdir, rdir);
	rt.rmax = 0;
	rayorigin(&rt, PRIMARY, NULL, NULL);
					/* check for intersection */
	while (localhit(&rt, &thescene)) {
		RAY	rt1 = rt;	/* pretend we were aimed at source */
		rt1.crtype |= rt1.rtype = SHADOW;
		rt1.rdir[0] = -rt.rdir[0];
		rt1.rdir[1] = -rt.rdir[1];
		rt1.rdir[2] = -rt.rdir[2];
		rt1.rod = -rt.rod;
		VSUB(rt1.rorg, rt.rop, rt.rdir);
		rt1.rot = 1.;
		rt1.rsrc = sn;
					/* record blocker */
		if (srcblocker(&rt1))
			return(1);
					/* move past failed blocker */
		VSUM(rt.rorg, rt.rop, rt.rdir, FTINY);
		rayclear(&rt);		/* & try again... */
	}
	return(0);			/* found no blockers */
}
Example #3
0
extern int
o_instance(		/* compute ray intersection with octree */
	OBJREC  *o,
	register RAY  *r
)
{
	RAY  rcont;
	double  d;
	register INSTANCE  *ins;
	register int  i;
					/* get the octree */
	ins = getinstance(o, IO_ALL);
					/* copy and transform ray */
	rcont = *r;
	multp3(rcont.rorg, r->rorg, ins->x.b.xfm);
	multv3(rcont.rdir, r->rdir, ins->x.b.xfm);
	for (i = 0; i < 3; i++)
		rcont.rdir[i] /= ins->x.b.sca;
	rcont.rmax *= ins->x.b.sca;
					/* clear and trace it */
	rayclear(&rcont);
	if (!localhit(&rcont, &ins->obj->scube))
		return(0);			/* missed */
	if (rcont.rot * ins->x.f.sca >= r->rot)
		return(0);			/* not close enough */

	if (o->omod != OVOID) {		/* if we have modifier, use it */
		r->ro = o;
		r->rox = NULL;
	} else {			/* else use theirs */
		r->ro = rcont.ro;
		if (rcont.rox != NULL) {
			newrayxf(r);		/* allocate transformation */
					/* NOTE: r->rox may equal rcont.rox! */
			multmat4(r->rox->f.xfm, rcont.rox->f.xfm, ins->x.f.xfm);
			r->rox->f.sca = rcont.rox->f.sca * ins->x.f.sca;
			multmat4(r->rox->b.xfm, ins->x.b.xfm, rcont.rox->b.xfm);
			r->rox->b.sca = ins->x.b.sca * rcont.rox->b.sca;
		} else
			r->rox = &ins->x;
	}
					/* transform it back */
	r->rot = rcont.rot * ins->x.f.sca;
	multp3(r->rop, rcont.rop, ins->x.f.xfm);
	multv3(r->ron, rcont.ron, ins->x.f.xfm);
	multv3(r->pert, rcont.pert, ins->x.f.xfm);
	d = 1./ins->x.f.sca;
	for (i = 0; i < 3; i++) {
		r->ron[i] *= d;
		r->pert[i] *= d;
	}
	r->rod = rcont.rod;
	r->uv[0] = rcont.uv[0];
	r->uv[1] = rcont.uv[1];
					/* return hit */
	return(1);
}
Example #4
0
int
getinterest(		/* get area of interest */
	char  *s,
	int  direc,
	FVECT  vec,
	double  *mp
)
{
	int  x, y;
	RAY  thisray;
	int  i;

	if (sscanf(s, "%lf", mp) != 1)
		*mp = 1.0;
	else if (*mp < -FTINY)		/* negative zoom is reduction */
		*mp = -1.0 / *mp;
	else if (*mp <= FTINY) {	/* too small */
		error(COMMAND, "illegal magnification");
		return(-1);
	}
	if (!sscanvec(sskip(s), vec)) {
		if (dev->getcur == NULL)
			return(-1);
		(*dev->comout)("Pick view center\n");
		if ((*dev->getcur)(&x, &y) == ABORT)
			return(-1);
		if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
			&ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
			error(COMMAND, "not on image");
			return(-1);
		}
		if (!direc || ourview.type == VT_PAR) {
			rayorigin(&thisray, PRIMARY, NULL, NULL);
			if (!localhit(&thisray, &thescene)) {
				error(COMMAND, "not a local object");
				return(-1);
			}
		}
		if (direc)
			if (ourview.type == VT_PAR)
				for (i = 0; i < 3; i++)
					vec[i] = thisray.rop[i] - ourview.vp[i];
			else
				VCOPY(vec, thisray.rdir);
		else
			VCOPY(vec, thisray.rop);
	} else if (direc) {
		for (i = 0; i < 3; i++)
			vec[i] -= ourview.vp[i];
		if (normalize(vec) == 0.0) {
			error(COMMAND, "point at view origin");
			return(-1);
		}
	}
	return(0);
}
Example #5
0
File: rv2.c Project: NREL/Radiance
void
getorigin(				/* origin viewpoint */
	char  *s
)
{
	VIEW	nv = ourview;
	double	d;
					/* get new view origin */
	if (sscanf(s, "%lf %lf", &d, &d) == 1) {
					/* just moving some distance */
		VSUM(nv.vp, nv.vp, nv.vdir, d);
	} else if (!sscanvec(s, nv.vp)) {
		int	x, y;		/* need to pick origin */
		RAY	thisray;
		if (dev->getcur == NULL)
			return;
		(*dev->comout)("Pick point on surface for new origin\n");
		if ((*dev->getcur)(&x, &y) == ABORT)
			return;
		if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
			&ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
			error(COMMAND, "not on image");
			return;
		}
		rayorigin(&thisray, PRIMARY, NULL, NULL);
		if (!localhit(&thisray, &thescene)) {
			error(COMMAND, "not a local object");
			return;
		}
		if (thisray.rod < 0.0)	/* don't look through other side */
			flipsurface(&thisray);
		VSUM(nv.vp, thisray.rop, thisray.ron, 20.0*FTINY);
		VCOPY(nv.vdir, thisray.ron);
	} else if (!sscanvec(sskip2(s,3), nv.vdir) || normalize(nv.vdir) == 0.0)
		VCOPY(nv.vdir, ourview.vdir);

	d = DOT(nv.vdir, nv.vup);	/* need different up vector? */
	if (d*d >= 1.-2.*FTINY) {
		int	i;
		nv.vup[0] = nv.vup[1] = nv.vup[2] = 0.0;
		for (i = 3; i--; )
			if (nv.vdir[i]*nv.vdir[i] < 0.34)
				break;
		nv.vup[i] = 1.;
	}
	newview(&nv);
}
Example #6
0
extern void
raytrace(			/* trace a ray and compute its value */
	RAY  *r
)
{
	if (localhit(r, &thescene))
		raycont(r);		/* hit local surface, evaluate */
	else if (r->ro == &Aftplane) {
		r->ro = NULL;		/* hit aft clipping plane */
		r->rot = FHUGE;
	} else if (sourcehit(r))
		rayshade(r, r->ro->omod);	/* distant source */

	if (trace != NULL)
		(*trace)(r);		/* trace execution */

	rayparticipate(r);		/* for participating medium */
}
Example #7
0
extern void
direct(					/* add direct component */
	RAY  *r,			/* ray that hit surface */
	srcdirf_t *f,			/* direct component coefficient function */
	void  *p			/* data for f */
)
{
	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++;
	}