示例#1
0
extern void
ambnotify(			/* record new modifier */
	OBJECT	obj
)
{
	static int  hitlimit = 0;
	OBJREC	 *o;
	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;
		}
}
示例#2
0
extern int
rayshade(		/* shade ray r with material mod */
	RAY  *r,
	int  mod
)
{
	OBJREC  *m;

	r->rt = r->rot;			/* set effective ray length */
	for ( ; mod != OVOID; mod = m->omod) {
		m = objptr(mod);
		/****** unnecessary test since modifier() is always called
		if (!ismodifier(m->otype)) {
			sprintf(errmsg, "illegal modifier \"%s\"", m->oname);
			error(USER, errmsg);
		}
		******/
					/* hack for irradiance calculation */
		if (do_irrad && !(r->crtype & ~(PRIMARY|TRANS)) &&
				m->otype != MAT_CLIP &&
				(ofun[m->otype].flags & (T_M|T_X))) {
			if (irr_ignore(m->otype)) {
				raytrans(r);
				return(1);
			}
			if (!islight(m->otype))
				m = &Lamb;
		}
		if ((*ofun[m->otype].funp)(m, r))
			return(1);	/* materials call raytexture() */
	}
	return(0);			/* no material! */
}
示例#3
0
static void
addface(			/* add a face to a cube */
	register CUBE  *cu,
	OBJECT	obj
)
{

	if (o_face(objptr(obj), cu) == O_MISS)
		return;

	if (istree(cu->cutree)) {
		CUBE  cukid;			/* do children */
		int  i, j;
		cukid.cusize = cu->cusize * 0.5;
		for (i = 0; i < 8; i++) {
			cukid.cutree = octkid(cu->cutree, i);
			for (j = 0; j < 3; j++) {
				cukid.cuorg[j] = cu->cuorg[j];
				if ((1<<j) & i)
					cukid.cuorg[j] += cukid.cusize;
			}
			addface(&cukid, obj);
			octkid(cu->cutree, i) = cukid.cutree;
		}
		return;
	}
	if (isempty(cu->cutree)) {
		OBJECT	oset[2];		/* singular set */
		oset[0] = 1; oset[1] = obj;
		cu->cutree = fullnode(oset);
		return;
	}
					/* add to full node */
	add2full(cu, obj);
}
示例#4
0
extern void
preload_objs(void)		/* preload object data structures */
{
	register OBJECT on;
				/* note that nobjects may change during loop */
	for (on = 0; on < nobjects; on++)
		load_os(objptr(on));
}
示例#5
0
ObjectUidT Service::insertConnection(
	const SocketDevice &_rsd,
	frame::aio::openssl::Context *_pctx,
	bool _secure
){
	//create a new connection with the given channel
	DynamicPointer<Connection>			conptr(new Connection(_rsd));
	ObjectUidT rv = registerObject(*conptr);
	DynamicPointer<frame::aio::Object>	objptr(conptr);
	Manager::the().scheduleAioObject(objptr);
	return rv;
}
示例#6
0
static int
transillum(			/* check if material is transparent illum */
	OBJECT	obj
)
{
	OBJREC *m = findmaterial(objptr(obj));
	
	if (m == NULL)
		return(1);
	if (m->otype != MAT_ILLUM)
		return(0);
	return(!m->oargs.nsargs || !strcmp(m->oargs.sarg[0], VOIDID));
}
示例#7
0
static void
addobject(			/* add an object to a cube */
	register CUBE  *cu,
	OBJECT	obj
)
{
	int  inc;

	inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);

	if (inc == O_MISS)
		return;				/* no intersection */

	if (istree(cu->cutree)) {
		CUBE  cukid;			/* do children */
		int  i, j;
		cukid.cusize = cu->cusize * 0.5;
		for (i = 0; i < 8; i++) {
			cukid.cutree = octkid(cu->cutree, i);
			for (j = 0; j < 3; j++) {
				cukid.cuorg[j] = cu->cuorg[j];
				if ((1<<j) & i)
					cukid.cuorg[j] += cukid.cusize;
			}
			addobject(&cukid, obj);
			octkid(cu->cutree, i) = cukid.cutree;
		}
		return;
	}
	if (isempty(cu->cutree)) {
		OBJECT  oset[2];		/* singular set */
		oset[0] = 1; oset[1] = obj;
		cu->cutree = fullnode(oset);
		return;
	}
					/* add to full node */
	add2full(cu, obj, inc);
}
示例#8
0
void photonPreCompDensity (PhotonMap *pmap, RAY *r, COLOR irrad)
/* Returns precomputed photon density estimate at ray -> rop. */
{
   Photon p;
   
   setcolor(irrad, 0, 0, 0);

   /* Ignore sources */
   if (r -> ro && islight(objptr(r -> ro -> omod) -> otype)) 
      return;
      
   find1Photon(preCompPmap, r, &p);
   getPhotonFlux(&p, irrad);
}
示例#9
0
extern OBJREC *			/* find an object's actual material */
findmaterial(register OBJREC *o)
{
	while (!ismaterial(o->otype)) {
		if (o->otype == MOD_ALIAS && o->oargs.nsargs) {
			OBJECT  aobj;
			OBJREC  *ao;
			aobj = lastmod(objndx(o), o->oargs.sarg[0]);
			if (aobj < 0)
				objerror(o, USER, "bad reference");
			ao = objptr(aobj);
			if (ismaterial(ao->otype))
				return(ao);
			if (ao->otype == MOD_ALIAS) {
				o = ao;
				continue;
			}
		}
		if (o->omod == OVOID)
			return(NULL);
		o = objptr(o->omod);
	}
	return(o);		/* mixtures will return NULL */
}
示例#10
0
OBJREC *	
findmaterial(OBJREC *o)			/* find an object's actual material */
{
	while (!ismaterial(o->otype)) {
		if (o->otype == MOD_ALIAS && o->oargs.nsargs) {
			OBJECT  aobj;
			OBJREC  *ao;
			aobj = lastmod(objndx(o), o->oargs.sarg[0]);
			if (aobj < 0)
				objerror(o, USER, "bad reference");
					/* recursive check on alias branch */
			if ((ao = findmaterial(objptr(aobj))) != NULL)
				return(ao);
		}
		if (o->omod == OVOID) {
					/* void mixture de facto material? */
			if (ismixture(o->otype))
				break;
			return(NULL);	/* else no material found */
		}
		o = objptr(o->omod);
	}
	return(o);
}
示例#11
0
extern void
rayhit(			/* standard ray hit test */
	OBJECT  *oset,
	RAY  *r
)
{
	OBJREC  *o;
	int	i;

	for (i = oset[0]; i > 0; i--) {
		o = objptr(oset[i]);
		if ((*ofun[o->otype].funp)(o, r))
			r->robj = oset[i];
	}
}
示例#12
0
static void
add2full(			/* add object to full node */
	register CUBE  *cu,
	OBJECT	obj
)
{
	OCTREE	ot;
	OBJECT	oset[MAXSET+1];
	CUBE  cukid;
	register int  i, j;

	objset(oset, cu->cutree);
	cukid.cusize = cu->cusize * 0.5;

	if (oset[0] < objlim || cukid.cusize <
			(oset[0] < MAXSET ? mincusize : mincusize/256.0)) {
						/* add to set */
		if (oset[0] >= MAXSET) {
			sprintf(errmsg, "set overflow in addobject (%s)",
					objptr(obj)->oname);
			error(INTERNAL, errmsg);
		}
		insertelem(oset, obj);
		cu->cutree = fullnode(oset);
		return;
	}
					/* subdivide cube */
	if ((ot = octalloc()) == EMPTY)
		error(SYSTEM, "out of octree space");
					/* assign subcubes */
	for (i = 0; i < 8; i++) {
		cukid.cutree = EMPTY;
		for (j = 0; j < 3; j++) {
			cukid.cuorg[j] = cu->cuorg[j];
			if ((1<<j) & i)
				cukid.cuorg[j] += cukid.cusize;
		}
		for (j = 1; j <= oset[0]; j++)
			addface(&cukid, oset[j]);
		addface(&cukid, obj);
					/* returned node */
		octkid(ot, i) = cukid.cutree;
	}
	cu->cutree = ot;
}
示例#13
0
static int
nonsurfintree(OCTREE ot)		/* check tree for modifiers */
{
	OBJECT  set[MAXSET+1];
	register int  i;

	if (isempty(ot))
		return(0);
	if (istree(ot)) {
		for (i = 0; i < 8; i++)
			if (nonsurfintree(octkid(ot, i)))
				return(1);
		return(0);
	}
	objset(set, ot);
	for (i = set[0]; i > 0; i-- )
		if (ismodifier(objptr(set[i])->otype))
			return(1);
	return(0);
}
示例#14
0
extern void
raytexture(			/* get material modifiers */
	RAY  *r,
	OBJECT  mod
)
{
	OBJREC  *m;
					/* execute textures and patterns */
	for ( ; mod != OVOID; mod = m->omod) {
		m = objptr(mod);
		/****** unnecessary test since modifier() is always called
		if (!ismodifier(m->otype)) {
			sprintf(errmsg, "illegal modifier \"%s\"", m->oname);
			error(USER, errmsg);
		}
		******/
		if ((*ofun[m->otype].funp)(m, r)) {
			sprintf(errmsg, "conflicting material \"%s\"",
					m->oname);
			objerror(r->ro, USER, errmsg);
		}
	}
}
示例#15
0
static OBJECT
cvmeshtri(			/* add an extended triangle to our mesh */
	OBJECT	obj
)
{
	OBJREC		*o = objptr(obj);
	TRIDATA		*ts;
	MESHVERT	vert[3];
	int		i, j;
	
	if (o->otype != OBJ_FACE)
		error(CONSISTENCY, "non-face in mesh");
	if (o->oargs.nfargs != 9)
		error(CONSISTENCY, "non-triangle in mesh");
	if (o->os == NULL)
		error(CONSISTENCY, "missing face record in cvmeshtri");
	ts = (TRIDATA *)((FACE *)o->os + 1);
	if (ts->obj != OVOID)	/* already added? */
		return(ts->obj);
	vert[0].fl = vert[1].fl = vert[2].fl = ts->fl;
	for (i = 3; i--; )
		for (j = 3; j--; )
			vert[i].v[j] = o->oargs.farg[3*i+j];
	if (ts->fl & MT_N)
		for (i = 3; i--; )
			for (j = 3; j--; )
				vert[i].n[j] = ts->vn[i][j];
	if (ts->fl & MT_UV)
		for (i = 3; i--; )
			for (j = 2; j--; )
				vert[i].uv[j] = ts->vc[i][j];
	ts->obj = addmeshtri(ourmesh, vert, o->omod);
	if (ts->obj == OVOID)
		error(INTERNAL, "addmeshtri failed");
	return(ts->obj);
}
示例#16
0
int
main(		/* convert object files to an octree */
	int  argc,
	char  *argv[]
)
{
	FVECT  bbmin, bbmax;
	char  *infile = NULL;
	int  inpfrozen = 0;
	int  outflags = IO_ALL;
	OBJECT	startobj;
	int  i;

	progname = argv[0] = fixargv0(argv[0]);

	ot_initotypes();

	for (i = 1; i < argc && argv[i][0] == '-'; i++)
		switch (argv[i][1]) {
		case '\0':				/* scene from stdin */
			goto breakopt;
		case 'i':				/* input octree */
			infile = argv[++i];
			break;
		case 'b':				/* bounding cube */
			thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
			thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
			thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
			thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
			break;
		case 'n':				/* set limit */
			objlim = atoi(argv[++i]);
			break;
		case 'r':				/* resolution limit */
			resolu = atoi(argv[++i]);
			break;
		case 'f':				/* freeze octree */
			outflags &= ~IO_FILES;
			break;
		case 'w':				/* supress warnings */
			nowarn = 1;
			break;
		default:
			sprintf(errmsg, "unknown option: '%s'", argv[i]);
			error(USER, errmsg);
			break;
		}
breakopt:
	SET_FILE_BINARY(stdout);
	if (infile != NULL) {		/* get old octree & objects */
		if (thescene.cusize > FTINY)
			error(USER, "only one of '-b' or '-i'");
		nfiles = readoct(infile, IO_ALL, &thescene, ofname);
		if (nfiles == 0)
			inpfrozen++;
	} else
		newheader("RADIANCE", stdout);	/* new binary file header */
	printargs(argc, argv, stdout);
	fputformat(OCTFMT, stdout);
	printf("\n");

	startobj = nobjects;		/* previous objects already converted */

	for ( ; i < argc; i++)		/* read new scene descriptions */
		if (!strcmp(argv[i], "-")) {	/* from stdin */
			readobj(NULL);
			outflags &= ~IO_FILES;
		} else {			/* from file */
			if (nfiles >= MAXOBJFIL)
				error(INTERNAL, "too many scene files");
			readobj(ofname[nfiles++] = argv[i]);
		}

	ofname[nfiles] = NULL;

	if (inpfrozen && outflags & IO_FILES) {
		error(WARNING, "frozen octree");
		outflags &= ~IO_FILES;
	}
						/* find bounding box */
	bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
	bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
	for (i = startobj; i < nobjects; i++)
		add2bbox(objptr(i), bbmin, bbmax);
						/* set/check cube */
	if (thescene.cusize == 0.0) {
		if (bbmin[0] <= bbmax[0]) {
			for (i = 0; i < 3; i++) {
				bbmin[i] -= OMARGIN;
				bbmax[i] += OMARGIN;
			}
			for (i = 0; i < 3; i++)
				if (bbmax[i] - bbmin[i] > thescene.cusize)
					thescene.cusize = bbmax[i] - bbmin[i];
			for (i = 0; i < 3; i++)
				thescene.cuorg[i] =
					(bbmax[i]+bbmin[i]-thescene.cusize)*.5;
		}
	} else {
		for (i = 0; i < 3; i++)
			if (bbmin[i] < thescene.cuorg[i] ||
				bbmax[i] > thescene.cuorg[i] + thescene.cusize)
				error(USER, "boundary does not encompass scene");
	}

	mincusize = thescene.cusize / resolu - FTINY;

	for (i = startobj; i < nobjects; i++)		/* add new objects */
		addobject(&thescene, i);

	thescene.cutree = combine(thescene.cutree);	/* optimize */

	writeoct(outflags, &thescene, ofname);	/* write structures to stdout */

	quit(0);
	return 0; /* pro forma return */
}
示例#17
0
static void
add2full(			/* add object to full node */
	register CUBE  *cu,
	OBJECT	obj,
	int  inc
)
{
	OCTREE	ot;
	OBJECT	oset[MAXSET+1];
	CUBE  cukid;
	unsigned char  inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
	register int  i, j;

	objset(oset, cu->cutree);
	cukid.cusize = cu->cusize * 0.5;

	if (inc==O_IN || oset[0] < objlim || cukid.cusize <
			(oset[0] < MAXSET ? mincusize : mincusize/256.0)) {
						/* add to set */
		if (oset[0] >= MAXSET) {
			sprintf(errmsg, "set overflow in addobject (%s)",
					objptr(obj)->oname);
			error(INTERNAL, errmsg);
		}
		insertelem(oset, obj);
		cu->cutree = fullnode(oset);
		return;
	}
					/* subdivide cube */
	if ((ot = octalloc()) == EMPTY)
		error(SYSTEM, "out of octree space");
					/* mark volumes */
	j = (oset[0]+7)>>3;
	while (j--)
		volflg[j] = inflg[j] = 0;
	for (j = 1; j <= oset[0]; j++)
		if (isvolume(objptr(oset[j])->otype)) {
			setbit(volflg,j-1);
			if ((*ofun[objptr(oset[j])->otype].funp)
					(objptr(oset[j]), cu) == O_IN)
				setbit(inflg,j-1);
		}
					/* assign subcubes */
	for (i = 0; i < 8; i++) {
		cukid.cutree = EMPTY;
		for (j = 0; j < 3; j++) {
			cukid.cuorg[j] = cu->cuorg[j];
			if ((1<<j) & i)
				cukid.cuorg[j] += cukid.cusize;
		}
					/* surfaces first */
		for (j = 1; j <= oset[0]; j++)
			if (!tstbit(volflg,j-1))
				addobject(&cukid, oset[j]);
					/* then this object */
		addobject(&cukid, obj);
					/* then partial volumes */
		for (j = 1; j <= oset[0]; j++)
			if (tstbit(volflg,j-1) &&
					!tstbit(inflg,j-1))
				addobject(&cukid, oset[j]);
					/* full volumes last */
		for (j = 1; j <= oset[0]; j++)
			if (tstbit(inflg,j-1))
				addobject(&cukid, oset[j]);
					/* returned node */
		octkid(ot, i) = cukid.cutree;
	}
	cu->cutree = ot;
}
示例#18
0
char *
checkmesh(MESH *mp)			/* validate mesh data */
{
	static char	embuf[128];
	int		nouvbounds = 1;
	int	i;
					/* basic checks */
	if (mp == NULL)
		return("NULL mesh pointer");
	if (!mp->ldflags)
		return("unassigned mesh");
	if (mp->name == NULL)
		return("missing mesh name");
	if (mp->nref <= 0)
		return("unreferenced mesh");
					/* check boundaries */
	if (mp->ldflags & IO_BOUNDS) {
		if (mp->mcube.cusize <= FTINY)
			return("illegal octree bounds in mesh");
		nouvbounds = (mp->uvlim[1][0] - mp->uvlim[0][0] <= FTINY ||
				mp->uvlim[1][1] - mp->uvlim[0][1] <= FTINY);
	}
					/* check octree */
	if (mp->ldflags & IO_TREE) {
		if (isempty(mp->mcube.cutree))
			error(WARNING, "empty mesh octree");
	}
					/* check scene data */
	if (mp->ldflags & IO_SCENE) {
		if (!(mp->ldflags & IO_BOUNDS))
			return("unbounded scene in mesh");
		if (mp->mat0 < 0 || mp->mat0+mp->nmats > nobjects)
			return("bad mesh modifier range");
		for (i = mp->mat0+mp->nmats; i-- > mp->mat0; ) {
			int	otyp = objptr(i)->otype;
			if (!ismodifier(otyp)) {
				sprintf(embuf,
					"non-modifier in mesh (%s \"%s\")",
					ofun[otyp].funame, objptr(i)->oname);
				return(embuf);
			}
		}
		if (mp->npatches <= 0)
			error(WARNING, "no patches in mesh");
		for (i = 0; i < mp->npatches; i++) {
			MESHPATCH	*pp = &mp->patch[i];
			if (pp->nverts <= 0)
				error(WARNING, "no vertices in patch");
			else {
				if (pp->xyz == NULL)
					return("missing patch vertex list");
				if (nouvbounds && pp->uv != NULL)
					return("unreferenced uv coordinates");
			}
			if (pp->ntris > 0 && pp->tri == NULL)
				return("missing patch triangle list");
			if (pp->nj1tris > 0 && pp->j1tri == NULL)
				return("missing patch joiner triangle list");
			if (pp->nj2tris > 0 && pp->j2tri == NULL)
				return("missing patch double-joiner list");
		}
	}
	return(NULL);			/* seems OK */
}
示例#19
0
extern void
marksources(void)			/* find and mark source objects */
{
	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->oargs.farg[0] <= FTINY && m->oargs.farg[1] <= FTINY &&
				m->oargs.farg[2] <= FTINY)
			continue;			/* don't bother */
		if (m->otype == MAT_GLOW &&
				o->otype != OBJ_SOURCE &&
				m->oargs.farg[3] <= FTINY) {
			foundsource += (ambounce > 0);
			continue;			/* don't track these */
		}
		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;
				foundsource += (ambounce > 0);
			}
		} 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
		foundsource += !(source[ns].sflags & SSKIP);
	}
	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");
}
示例#20
0
void photonDensity (PhotonMap *pmap, RAY *ray, COLOR irrad)
/* Photon density estimate. Returns irradiance at ray -> rop. */
{
   unsigned                      i;
   float                         r2;
   COLOR                         flux;
   Photon                        *photon;
   const PhotonSearchQueueNode   *sqn;
 
   setcolor(irrad, 0, 0, 0);

   if (!pmap -> maxGather) 
      return;
      
   /* Ignore sources */
   if (ray -> ro && islight(objptr(ray -> ro -> omod) -> otype)) 
      return;
         
   findPhotons(pmap, ray);
   
   /* Need at least 2 photons */
   if (pmap -> squeue.tail < 2) {
#ifdef PMAP_NONEFOUND   
      sprintf(errmsg, "no photons found on %s at (%.3f, %.3f, %.3f)", 
              ray -> ro ? ray -> ro -> oname : "<null>",
              ray -> rop [0], ray -> rop [1], ray -> rop [2]);
      error(WARNING, errmsg);
#endif      

      return;
   }

   if (pmap -> minGather == pmap -> maxGather) {
      /* No bias compensation. Just do a plain vanilla estimate */
      sqn = pmap -> squeue.node + 1;
      
      /* Average radius^2 between furthest two photons to improve accuracy */
      r2 = max(sqn -> dist2, (sqn + 1) -> dist2);
      r2 = 0.25 * (pmap -> maxDist2 + r2 + 2 * sqrt(pmap -> maxDist2 * r2));
      
      /* Skip the extra photon */
      for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) {
         photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
         getPhotonFlux(photon, flux);         
#ifdef PMAP_EPANECHNIKOV
         /* Apply Epanechnikov kernel to photon flux based on photon dist */
         scalecolor(flux, 2 * (1 - sqn -> dist2 / r2));
#endif   
         addcolor(irrad, flux);
      }
      
      /* Divide by search area PI * r^2, 1 / PI required as ambient 
         normalisation factor */         
      scalecolor(irrad, 1 / (PI * PI * r2)); 
      
      return;
   }
   else 
      /* Apply bias compensation to density estimate */
      biasComp(pmap, irrad);
}
示例#21
0
int newPhoton (PhotonMap* pmap, const RAY* ray)
{
   unsigned i;
   Photon photon;
   COLOR photonFlux;
   
   /* Account for distribution ratio */
   if (!pmap || pmapRandom(pmap -> randState) > pmap -> distribRatio) 
      return -1;
      
   /* Don't store on sources */
   if (ray -> robj > -1 && islight(objptr(ray -> ro -> omod) -> otype)) 
      return -1;

   /*  if modifier in include/exclude set */
   if (ambincl != -1 && ray -> ro && 
       ambincl != inset(ambset, ray -> ro -> omod))
      return -1;

   if (pmapNumROI && pmapROI) {      
      unsigned inROI = 0;
      
      /* Store photon if within a region of interest (for ze Ecksperts!) */
      for (i = 0; !inROI && i < pmapNumROI; i++)
         inROI = (ray -> rop [0] >= pmapROI [i].min [0] && 
                  ray -> rop [0] <= pmapROI [i].max [0] &&
                  ray -> rop [1] >= pmapROI [i].min [1] && 
                  ray -> rop [1] <= pmapROI [i].max [1] &&
                  ray -> rop [2] >= pmapROI [i].min [2] && 
                  ray -> rop [2] <= pmapROI [i].max [2]);
      if (!inROI)
         return -1;
   }
    
   /* Adjust flux according to distribution ratio and ray weight */
   copycolor(photonFlux, ray -> rcol);   
   scalecolor(photonFlux, 
              ray -> rweight / (pmap -> distribRatio ? pmap -> distribRatio
                                                     : 1));
   setPhotonFlux(&photon, photonFlux);
            
   /* Set photon position and flags */
   VCOPY(photon.pos, ray -> rop);
   photon.flags = 0;
   photon.caustic = PMAP_CAUSTICRAY(ray);

   /* Set contrib photon's primary ray and subprocess index (the latter
    * to linearise the primary ray indices after photon distribution is
    * complete). Also set primary ray's source index, thereby marking it
    * as used. */
   if (isContribPmap(pmap)) {
      photon.primary = pmap -> numPrimary;
      photon.proc = PMAP_GETRAYPROC(ray);
      pmap -> lastPrimary.srcIdx = ray -> rsrc;
   }
   else photon.primary = 0;
   
   /* Set normal */
   for (i = 0; i <= 2; i++)
      photon.norm [i] = 127.0 * (isVolumePmap(pmap) ? ray -> rdir [i] 
                                                    : ray -> ron [i]);

   if (!pmap -> heapBuf) {
      /* Lazily allocate heap buffa */
#if NIX
      /* Randomise buffa size to temporally decorellate flushes in
       * multiprocessing mode */
      srandom(randSeed + getpid());
      pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
#else
      /* Randomisation disabled for single processes on WIN; also useful
       * for reproducability during debugging */         
      pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
#endif         
      if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
         error(SYSTEM, "failed heap buffer allocation in newPhoton");
      pmap -> heapBufLen = 0;      
   }

   /* Photon initialised; now append to heap buffa */
   memcpy(pmap -> heapBuf + pmap -> heapBufLen, &photon, sizeof(Photon));
               
   if (++pmap -> heapBufLen >= pmap -> heapBufSize)
      /* Heap buffa full, flush to heap file */
      flushPhotonHeap(pmap);

   pmap -> numPhotons++;
            
   return 0;
}
示例#22
0
int
main(		/* compile a .OBJ file into a mesh */
	int  argc,
	char  *argv[]
)
{
	int  nmatf = 0;
	char  pathnames[12800];
	char  *pns = pathnames;
	char  *matinp[128];
	char  *cp;
	int  i, j;

	progname = argv[0];
	ofun[OBJ_FACE].funp = o_face;

	for (i = 1; i < argc && argv[i][0] == '-'; i++)
		switch (argv[i][1]) {
		case 'n':				/* set limit */
			objlim = atoi(argv[++i]);
			break;
		case 'r':				/* resolution limit */
			resolu = atoi(argv[++i]);
			break;
		case 'a':				/* material file */
			matinp[nmatf++] = argv[++i];
			break;
		case 'l':				/* library material */
			cp = getpath(argv[++i], getrlibpath(), R_OK);
			if (cp == NULL) {
				sprintf(errmsg,
					"cannot find library material: '%s'",
						argv[i]);
				error(USER, errmsg);
			}
			matinp[nmatf++] = strcpy(pns, cp);
			while (*pns++)
				;
			break;
		case 'w':				/* supress warnings */
			nowarn = 1;
			break;
		default:
			sprintf(errmsg, "unknown option: '%s'", argv[i]);
			error(USER, errmsg);
			break;
		}

	if (i < argc-2)
		error(USER, "too many file arguments");
					/* initialize mesh */
	cvinit(i==argc-2 ? argv[i+1] : "<stdout>");
					/* load material input */
	for (j = 0; j < nmatf; j++)
		readobj(matinp[j]);
					/* read .OBJ file into triangles */
	if (i == argc)
		wfreadobj(NULL);
	else
		wfreadobj(argv[i]);
	
	cvmeshbounds();			/* set octree boundaries */

	if (i == argc-2)		/* open output file */
		if (freopen(argv[i+1], "w", stdout) == NULL)
			error(SYSTEM, "cannot open output file");
	SET_FILE_BINARY(stdout);
	newheader("RADIANCE", stdout);	/* new binary file header */
	printargs(i<argc ? i+1 : argc, argv, stdout);
	fputformat(MESHFMT, stdout);
	fputc('\n', stdout);

	mincusize = ourmesh->mcube.cusize / resolu - FTINY;

	for (i = 0; i < nobjects; i++)	/* add triangles to octree */
		if (objptr(i)->otype == OBJ_FACE)
			addface(&ourmesh->mcube, i);

					/* optimize octree */
	ourmesh->mcube.cutree = combine(ourmesh->mcube.cutree);

	if (ourmesh->mcube.cutree == EMPTY)
		error(WARNING, "mesh is empty");
	
	cvmesh();			/* convert mesh and leaf nodes */

	writemesh(ourmesh, stdout);	/* write mesh to output */
	
	/* printmeshstats(ourmesh, stderr); */

	quit(0);
	return 0; /* pro forma return */
}
示例#23
0
文件: rv2.c 项目: NREL/Radiance
void
traceray(				/* trace a single ray */
	char  *s
)
{
	RAY	thisray;
	char	buf[512];

	thisray.rmax = 0.0;

	if (!sscanvec(s, thisray.rorg) ||
			!sscanvec(sskip2(s,3), thisray.rdir)) {
		int  x, y;

		if (dev->getcur == NULL)
			return;
		(*dev->comout)("Pick ray\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;
		}

	} else if (normalize(thisray.rdir) == 0.0) {
		error(COMMAND, "zero ray direction");
		return;
	}

	ray_trace(&thisray);

	if (thisray.ro == NULL)
		(*dev->comout)("ray hit nothing");
	else {
		OBJREC	*mat = NULL;
		OBJREC	*mod = NULL;
		char	matspec[256];
		OBJREC	*ino;

		matspec[0] = '\0';
		if (thisray.ro->omod != OVOID) {
			mod = objptr(thisray.ro->omod);
			mat = findmaterial(mod);
		}
		if (thisray.rod < 0.0)
			strcpy(matspec, "back of ");
		if (mod != NULL) {
			strcat(matspec, mod->oname);
			if (mat != mod && mat != NULL)
				sprintf(matspec+strlen(matspec),
					" (%s)", mat->oname);
		} else
			strcat(matspec, VOIDID);
		sprintf(buf, "ray hit %s %s \"%s\"", matspec,
				ofun[thisray.ro->otype].funame,
				thisray.ro->oname);
		if ((ino = objptr(thisray.robj)) != thisray.ro)
			sprintf(buf+strlen(buf), " in %s \"%s\"",
					ofun[ino->otype].funame, ino->oname);
		(*dev->comout)(buf);
		(*dev->comin)(buf, NULL);
		if (thisray.rot >= FHUGE)
			(*dev->comout)("at infinity");
		else {
			sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)",
					thisray.rop[0], thisray.rop[1],
					thisray.rop[2], raydistance(&thisray));
			(*dev->comout)(buf);
		}
		(*dev->comin)(buf, NULL);
		sprintf(buf, "value (%.5g %.5g %.5g) (%.3gL)",
				colval(thisray.rcol,RED),
				colval(thisray.rcol,GRN),
				colval(thisray.rcol,BLU),
				luminance(thisray.rcol));
		(*dev->comout)(buf);
	}
	(*dev->comin)(buf, NULL);
}
示例#24
0
int				/* create an extended triangle */
cvtri(
	OBJECT	mo,
	FVECT	vp1,
	FVECT	vp2,
	FVECT	vp3,
	FVECT	vn1,
	FVECT	vn2,
	FVECT	vn3,
	RREAL	vc1[2],
	RREAL	vc2[2],
	RREAL	vc3[2]
)
{
	static OBJECT	fobj = OVOID;
	char		buf[32];
	int		flags;
	TRIDATA		*ts;
	FACE		*f;
	OBJREC		*fop;
	int		j;
	
	flags = MT_V;		/* check what we have */
	if (vn1 != NULL && vn2 != NULL && vn3 != NULL) {
		RREAL	*rp;
		switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) {
		case ISBENT:
			flags |= MT_N;
			/* fall through */
		case ISFLAT:
			break;
		case RVBENT:
			flags |= MT_N;
			rp = vn1; vn1 = vn3; vn3 = rp;
			/* fall through */
		case RVFLAT:
			rp = vp1; vp1 = vp3; vp3 = rp;
			rp = vc1; vc1 = vc3; vc3 = rp;
			break;
		case DEGEN:
			error(WARNING, "degenerate triangle");
			return(0);
		default:
			error(INTERNAL, "bad return from flat_tri()");
		}
	}
	if (vc1 != NULL && vc2 != NULL && vc3 != NULL)
		flags |= MT_UV;
	if (fobj == OVOID) {	/* create new triangle object */
		fobj = newobject();
		if (fobj == OVOID)
			goto nomem;
		fop = objptr(fobj);
		fop->omod = mo;
		fop->otype = OBJ_FACE;
		sprintf(buf, "t%ld", (long)fobj);
		fop->oname = savqstr(buf);
		fop->oargs.nfargs = 9;
		fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL));
		if (fop->oargs.farg == NULL)
			goto nomem;
	} else {		/* else reuse failed one */
		fop = objptr(fobj);
		if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9)
			error(CONSISTENCY, "code error 1 in cvtri");
	}
	for (j = 3; j--; ) {
		fop->oargs.farg[j] = vp1[j];
		fop->oargs.farg[3+j] = vp2[j];
		fop->oargs.farg[6+j] = vp3[j];
	}
				/* create face record */
	f = getface(fop);
	if (f->area == 0.) {
		free_os(fop);
		return(0);
	}
	if (fop->os != (char *)f)
		error(CONSISTENCY, "code error 2 in cvtri");
				/* follow with auxliary data */
	f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags));
	if (f == NULL)
		goto nomem;
	fop->os = (char *)f;
	ts = (TRIDATA *)(f+1);
	ts->fl = flags;
	ts->obj = OVOID;
	if (flags & MT_N)
		for (j = 3; j--; ) {
			ts->vn[0][j] = vn1[j];
			ts->vn[1][j] = vn2[j];
			ts->vn[2][j] = vn3[j];
		}
	if (flags & MT_UV)
		for (j = 2; j--; ) {
			ts->vc[0][j] = vc1[j];
			ts->vc[1][j] = vc2[j];
			ts->vc[2][j] = vc3[j];
		}
	else
		vc1 = vc2 = vc3 = NULL;
				/* update bounds */
	add2bounds(vp1, vc1);
	add2bounds(vp2, vc2);
	add2bounds(vp3, vc3);
	fobj = OVOID;		/* we used this one */
	return(1);
nomem:
	error(SYSTEM, "out of memory in cvtri");
	return(0);
}
示例#25
0
文件: readobj.c 项目: NREL/Radiance
void
getobject(				/* read the next object */
	char  *name,
	FILE  *fp
)
{
#define	OALIAS	-2
	OBJECT  obj;
	char  sbuf[MAXSTR];
	int  rval;
	OBJREC  *objp;

	if ((obj = newobject()) == OVOID)
		error(SYSTEM, "out of object space");
	objp = objptr(obj);
					/* get modifier */
	strcpy(sbuf, "EOF");
	fgetword(sbuf, MAXSTR, fp);
	if (strchr(sbuf, '\t')) {
		sprintf(errmsg, "(%s): illegal tab in modifier \"%s\"",
					name, sbuf);
		error(USER, errmsg);
	}
	if (!strcmp(sbuf, VOIDID))
		objp->omod = OVOID;
	else if (!strcmp(sbuf, ALIASMOD))
		objp->omod = OALIAS;
	else if ((objp->omod = modifier(sbuf)) == OVOID) {
		sprintf(errmsg, "(%s): undefined modifier \"%s\"", name, sbuf);
		error(USER, errmsg);
	}
					/* get type */
	strcpy(sbuf, "EOF");
	fgetword(sbuf, MAXSTR, fp);
	if ((objp->otype = otype(sbuf)) < 0) {
		sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf);
		error(USER, errmsg);
	}
					/* get identifier */
	sbuf[0] = '\0';
	fgetword(sbuf, MAXSTR, fp);
	if (strchr(sbuf, '\t')) {
		sprintf(errmsg, "(%s): illegal tab in identifier \"%s\"",
					name, sbuf);
		error(USER, errmsg);
	}
	objp->oname = savqstr(sbuf);
					/* get arguments */
	if (objp->otype == MOD_ALIAS) {
		OBJECT  alias;
		strcpy(sbuf, "EOF");
		fgetword(sbuf, MAXSTR, fp);
		if ((alias = modifier(sbuf)) == OVOID) {
			sprintf(errmsg, "(%s): bad reference \"%s\"",
					name, sbuf);
			objerror(objp, USER, errmsg);
		}
		if (objp->omod == OALIAS || 
				objp->omod == objptr(alias)->omod) {
			objp->omod = alias;
		} else {
			objp->oargs.sarg = (char **)malloc(sizeof(char *));
			if (objp->oargs.sarg == NULL)
				error(SYSTEM, "out of memory in getobject");
			objp->oargs.nsargs = 1;
			objp->oargs.sarg[0] = savestr(sbuf);
		}
	} else if ((rval = readfargs(&objp->oargs, fp)) == 0) {
		sprintf(errmsg, "(%s): bad arguments", name);
		objerror(objp, USER, errmsg);
	} else if (rval < 0) {
		sprintf(errmsg, "(%s): error reading scene", name);
		error(SYSTEM, errmsg);
	}
	if (objp->omod == OALIAS) {
		sprintf(errmsg, "(%s): inappropriate use of '%s' modifier",
				name, ALIASMOD);
		objerror(objp, USER, errmsg);
	}
					/* initialize */
	objp->os = NULL;

	insertobject(obj);		/* add to global structure */
#undef OALIAS
}