示例#1
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 */
}
示例#2
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);
}
static void
ray_pchild(	/* process rays (never returns) */
	int	fd_in,
	int	fd_out
)
{
	int	n;
	register int	i;
					/* flag child process for quit() */
	ray_pnprocs = -1;
					/* read each ray request set */
	while ((n = read(fd_in, (char *)r_queue, sizeof(r_queue))) > 0) {
		int	n2;
		if (n < sizeof(RAY))
			break;
					/* get smuggled set length */
		n2 = sizeof(RAY)*r_queue[0].crtype - n;
		if (n2 < 0)
			error(INTERNAL, "buffer over-read in ray_pchild()");
		if (n2 > 0) {		/* read the rest of the set */
			i = readbuf(fd_in, (char *)r_queue + n, n2);
			if (i != n2)
				break;
			n += n2;
		}
		n /= sizeof(RAY);
					/* evaluate rays */
		for (i = 0; i < n; i++) {
			r_queue[i].crtype = r_queue[i].rtype;
			r_queue[i].parent = NULL;
			r_queue[i].clipset = NULL;
			r_queue[i].slights = NULL;
			r_queue[i].rlvl = 0;
			samplendx += samplestep;
			rayclear(&r_queue[i]);
			rayvalue(&r_queue[i]);
		}
					/* write back our results */
		i = writebuf(fd_out, (char *)r_queue, sizeof(RAY)*n);
		if (i != sizeof(RAY)*n)
			error(SYSTEM, "write error in ray_pchild()");
	}
	if (n)
		error(SYSTEM, "read error in ray_pchild()");
	ambsync();
	quit(0);			/* normal exit */
}
示例#4
0
extern int
rayorigin(		/* start new ray from old one */
	RAY  *r,
	int  rt,
	const RAY  *ro,
	const COLOR rc
)
{
	double	rw, re;
						/* assign coefficient/weight */
	if (rc == NULL) {
		rw = 1.0;
		setcolor(r->rcoef, 1., 1., 1.);
	} else {
		rw = intens(rc);
		if (rc != r->rcoef)
			copycolor(r->rcoef, rc);
	}
	if ((r->parent = ro) == NULL) {		/* primary ray */
		r->rlvl = 0;
		r->rweight = rw;
		r->crtype = r->rtype = rt;
		r->rsrc = -1;
		r->clipset = NULL;
		r->revf = raytrace;
		copycolor(r->cext, cextinction);
		copycolor(r->albedo, salbedo);
		r->gecc = seccg;
		r->slights = NULL;
	} else {				/* spawned ray */
		if (ro->rot >= FHUGE) {
			memset(r, 0, sizeof(RAY));
			return(-1);		/* illegal continuation */
		}
		r->rlvl = ro->rlvl;
		if (rt & RAYREFL) {
			r->rlvl++;
			r->rsrc = -1;
			r->clipset = ro->clipset;
			r->rmax = 0.0;
		} else {
			r->rsrc = ro->rsrc;
			r->clipset = ro->newcset;
			r->rmax = ro->rmax <= FTINY ? 0.0 : ro->rmax - ro->rot;
		}
		r->revf = ro->revf;
		copycolor(r->cext, ro->cext);
		copycolor(r->albedo, ro->albedo);
		r->gecc = ro->gecc;
		r->slights = ro->slights;
		r->crtype = ro->crtype | (r->rtype = rt);
		VCOPY(r->rorg, ro->rop);
		r->rweight = ro->rweight * rw;
						/* estimate extinction */
		re = colval(ro->cext,RED) < colval(ro->cext,GRN) ?
				colval(ro->cext,RED) : colval(ro->cext,GRN);
		if (colval(ro->cext,BLU) < re) re = colval(ro->cext,BLU);
		re *= ro->rot;
		if (re > 0.1) {
			if (re > 92.) {
				r->rweight = 0.0;
			} else {
				r->rweight *= exp(-re);
			}
		}
	}
	rayclear(r);
	if (r->rweight <= 0.0)			/* check for expiration */
		return(-1);
	if (r->crtype & SHADOW)			/* shadow commitment */
		return(0);
	if (maxdepth <= 0 && rc != NULL) {	/* Russian roulette */
		if (minweight <= 0.0)
			error(USER, "zero ray weight in Russian roulette");
		if (maxdepth < 0 && r->rlvl > -maxdepth)
			return(-1);		/* upper reflection limit */
		if (r->rweight >= minweight)
			return(0);
		if (frandom() > r->rweight/minweight)
			return(-1);
		rw = minweight/r->rweight;	/* promote survivor */
		scalecolor(r->rcoef, rw);
		r->rweight = minweight;
		return(0);
	}
	return(r->rweight >= minweight && r->rlvl <= abs(maxdepth) ? 0 : -1);
}
示例#5
0
static void
ashiksamp(		/* sample anisotropic Ashikhmin-Shirley specular */
	ASHIKDAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2], dtmp;
	double  cosph, sinph, costh, sinth;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;

	if (np->specfl & SPA_BADU ||
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) < 0)
		return;

	nstarget = 1;
	if (specjitter > 1.5) {			/* multiple samples? */
		nstarget = specjitter*np->rp->rweight + .5;
		if (sr.rweight <= minweight*nstarget)
			nstarget = sr.rweight/minweight;
		if (nstarget > 1) {
			dtmp = 1./nstarget;
			scalecolor(sr.rcoef, dtmp);
			sr.rweight *= dtmp;
		} else
			nstarget = 1;
	}
	dimlist[ndims++] = (int)(size_t)np->mp;
	maxiter = MAXITER*nstarget;
	for (nstaken = ntrials = 0; nstaken < nstarget &&
					ntrials < maxiter; ntrials++) {
		if (ntrials)
			dtmp = frandom();
		else
			dtmp = urand(ilhash(dimlist,ndims)+647+samplendx);
		multisamp(rv, 2, dtmp);
		dtmp = 2.*PI * rv[0];
		cosph = sqrt(np->v_power + 1.) * tcos(dtmp);
		sinph = sqrt(np->u_power + 1.) * tsin(dtmp);
		dtmp = 1./sqrt(cosph*cosph + sinph*sinph);
		cosph *= dtmp;
		sinph *= dtmp;
		costh = pow(rv[1], 1./(np->u_power*cosph*cosph+np->v_power*sinph*sinph+1.));
		if (costh <= FTINY)
			continue;
		sinth = sqrt(1. - costh*costh);
		for (i = 0; i < 3; i++)
			h[i] = cosph*sinth*np->u[i] + sinph*sinth*np->v[i] + costh*np->pnorm[i];

		if (nstaken)
			rayclear(&sr);
		dtmp = -2.*DOT(h, np->rp->rdir);
		VSUM(sr.rdir, np->rp->rdir, h, dtmp);				
						/* sample rejection test */
		if (DOT(sr.rdir, np->rp->ron) <= FTINY)
			continue;
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(np->rp->rcol, sr.rcol);
		++nstaken;
	}
	ndims--;
}
示例#6
0
static void
agaussamp(		/* sample anisotropic Gaussian specular */
	ANISODAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2];
	double  d, sinp, cosp;
	COLOR	scol;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;
					/* compute reflection */
	if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		setcolor(scol, 0., 0., 0.);
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				h[i] = np->pnorm[i] +
					d*(cosp*np->u[i] + sinp*np->v[i]);
			d = -2.0 * DOT(h, np->rp->rdir) / (1.0 + d*d);
			VSUM(sr.rdir, np->rp->rdir, h, d);
						/* sample rejection test */
			if ((d = DOT(sr.rdir, np->rp->ron)) <= FTINY)
				continue;
			checknorm(sr.rdir);
			if (nstarget > 1) {	/* W-G-M-D adjustment */
				if (nstaken) rayclear(&sr);
				rayvalue(&sr);
				d = 2./(1. + np->rp->rod/d);
				scalecolor(sr.rcol, d);
				addcolor(scol, sr.rcol);
			} else {
				rayvalue(&sr);
				multcolor(sr.rcol, sr.rcoef);
				addcolor(np->rp->rcol, sr.rcol);
			}
			++nstaken;
		}
		if (nstarget > 1) {		/* final W-G-M-D weighting */
			multcolor(scol, sr.rcoef);
			d = (double)nstarget/ntrials;
			scalecolor(scol, d);
			addcolor(np->rp->rcol, scol);
		}
		ndims--;
	}
					/* compute transmission */
	copycolor(sr.rcoef, np->mcolor);		/* modify by material color */
	scalecolor(sr.rcoef, np->tspec);
	if ((np->specfl & (SP_TRAN|SP_TBLT)) == SP_TRAN &&
			rayorigin(&sr, SPECULAR, np->rp, sr.rcoef) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+1823+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				sr.rdir[i] = np->prdir[i] +
						d*(cosp*np->u[i] + sinp*np->v[i]);
			if (DOT(sr.rdir, np->rp->ron) >= -FTINY)
				continue;
			normalize(sr.rdir);	/* OK, normalize */
			if (nstaken)		/* multi-sampling */
				rayclear(&sr);
			rayvalue(&sr);
			multcolor(sr.rcol, sr.rcoef);
			addcolor(np->rp->rcol, sr.rcol);
			++nstaken;
		}
		ndims--;
	}
}