Esempio n. 1
0
			/* initialize by finding sources smaller than rad */
extern void
init_drawsources(
	int	rad				/* source sample size */
)
{
	RREAL	spoly[MAXVERT][2];
	int	nsv;
	register SPLIST	*sp;
	register int	i;
					/* free old source list if one */
	for (sp = sphead; sp != NULL; sp = sphead) {
		sphead = sp->next;
		free((void *)sp);
	}
					/* loop through all sources */
	for (i = nsources; i--; ) {
					/* skip illum's */
		if (findmaterial(source[i].so)->otype == MAT_ILLUM)
			continue;
					/* compute image polygon for source */
		if (!(nsv = sourcepoly(i, spoly)))
			continue;
					/* clip to image boundaries */
		if (!(nsv = box_clip_poly(spoly, nsv, 0., 1., 0., 1., spoly)))
			continue;
					/* big enough for standard sampling? */
		if (minw2(spoly, nsv, ourview.vn2/ourview.hn2) >
				(double)rad*rad/hres/hres)
			continue;
					/* OK, add to our list */
		spinsert(i, spoly, nsv);
	}
}
Esempio n. 2
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));
}
Esempio n. 3
0
int OOC_FilterPhoton (void *p, void *fd)
/* Filter callback for photon kNN search, used by OOC_FindNearest() */
{
   const Photon         *photon = p;
   const OOC_FilterData *filtData = fd; 
   const PhotonMap      *pmap = filtData -> pmap;

   /* Reject photon if normal faces away (ignored for volume photons) with
    * tolerance to account for perturbation; note photon normal is coded
    * in range [-127,127], hence we factor this in */
   if (filtData -> norm && 
       DOT(filtData->norm, photon->norm) <= PMAP_NORM_TOL * 127 * frandom())
      return 0;
      
   if (isContribPmap(pmap)) {
      /* Lookup in contribution photon map; filter according to emitting
       * light source if contrib list set, else accept all */
       
      if (pmap -> srcContrib) {
         OBJREC *srcMod; 
         const int srcIdx = photonSrcIdx(pmap, photon);
      
         if (srcIdx < 0 || srcIdx >= nsources)
            error(INTERNAL, "invalid light source index in photon map");
      
         srcMod = findmaterial(source [srcIdx].so);

         /* Reject photon if contributions from light source which emitted
          * it are not sought */
         if (!lu_find(pmap -> srcContrib, srcMod -> oname) -> data)
            return 0;
      }

      /* Reject non-caustic photon if lookup for caustic contribs */
      if (pmap -> lookupCaustic && !photon -> caustic)
         return 0;
   }
   
   /* Accept photon */
   return 1;   
}
Esempio n. 4
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);
}
Esempio n. 5
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");
}
Esempio n. 6
0
File: rv2.c Progetto: 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);
}
Esempio n. 7
0
void loadprojectfile(unsigned char *file)
{
	unsigned char *f=file;
	scenelist=NULL;
	vector3 xpse;
	float phi;
	char floatbytes=readbyte(&file);
	material *pt;
	texture  *t;

	//////////////// TEXTURE LOAD ////////////////////

	unsigned char texnum=readbyte(&file);
	
	int aa;
	for (aa=1; aa<=texnum; aa++)
	{
		texture *t=new texture;
		inittexture(*t);
		t->ID=readbyte(&file); //texture id
		t->next=texturelist;
		texturelist=t;
		char cmdcnt=readbyte(&file); //command count
		
		for (int x=0;x<cmdcnt;x++)
		{
			texturecommand cmd;
			memcpy(&cmd,file,9);
			file+=9; 
			if (cmd.commandnumber==DD_text)
			{				
				byte bb=readbyte(&file);
				memcpy(t->texts[x].text,file,bb);
				file+=bb; //text
			}
			performcommand(*t,cmd);
			//precalc((float)(aa-1)/(float)(texnum-1)+1.0f/float(texnum)*(float)x/(float)cmdcnt);
			precalc((float)(aa-1)/(float)(texnum)+1.0f/(float)(texnum)*(float)x/(float)cmdcnt);
		}		
	}

	/////////////// MATERIAL LOAD ////////////////////

    texnum=readbyte(&file);

	for (aa=1; aa<=texnum; aa++)
	{
		material *m=new material;
		m->next=materiallist;
		materiallist=m;
		m->texture=readbyte(&file);
		m->layer=readbyte(&file);
		m->alphatexture=readbyte(&file);
		m->alphalayer=readbyte(&file);
		m->alphamode=readbyte(&file);
		m->number=readbyte(&file);
		creatematerial(m);
	}

	byte scenenum=readbyte(&file);

	for (int ar=1; ar<=scenenum; ar++)
	{
		scene *Scene=newscene();
		Scene->number=readbyte(&file);

		/////////////////// ENVIRONMENT LOAD ////////////////////

		Scene->fog=readbyte(&file);
		if (Scene->fog)
		{
			Scene->fogcol[0]=(float)readbyte(&file)/255.0f;
			Scene->fogcol[1]=(float)readbyte(&file)/255.0f;
			Scene->fogcol[2]=(float)readbyte(&file)/255.0f;
			Scene->fogdensity=readfloat(&file,floatbytes);
		}

		int lightnum=readbyte(&file);
		for (int x=0; x<lightnum; x++)
		{
			int ID=readbyte(&file);
			int type=readbyte(&file);
			Scene->lights[x].turnedon=true;
			Scene->lights[x].position[3]=0;
			Scene->lights[x].ambient[0]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].ambient[1]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].ambient[2]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].color[0]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].color[1]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].color[2]=(float)readbyte(&file)/255.0f;
			Scene->lights[x].position[0]=readfloat(&file,floatbytes);
			Scene->lights[x].position[1]=readfloat(&file,floatbytes);
			Scene->lights[x].position[2]=readfloat(&file,floatbytes);
			if (type>=1)
			{			
				Scene->lights[x].position[3]=1;
				Scene->lights[x].c_att=readfloat(&file,floatbytes);
				Scene->lights[x].l_att=readfloat(&file,floatbytes);
				Scene->lights[x].q_att=readfloat(&file,floatbytes);
			}
			if (type==2)
			{
				Scene->lights[x].spot_direction[0]=readfloat(&file,floatbytes);
				Scene->lights[x].spot_direction[1]=readfloat(&file,floatbytes);
				Scene->lights[x].spot_direction[2]=readfloat(&file,floatbytes);
				Scene->lights[x].spot_exponent=readfloat(&file,floatbytes);
				Scene->lights[x].spot_cutoff=readfloat(&file,floatbytes);
			}
			else
				Scene->lights[x].spot_cutoff=180.0;
		}

		/////////////////// OBJECT LOAD /////////////////////

		int objnum=readword(&file);

		for (int aa=1;aa<=objnum;aa++)
		{
			addobject(*Scene);
			tminimalobjdata objdata;
			memcpy(&objdata,file,sizeof(objdata));

			int current=Scene->objectnum-1;

			Scene->objects[current].data=objdata;
			file+=4;
			
			Scene->objects[current].number=readword(&file);
			Scene->objects[current].parent=readword(&file);

			if (objdata.textured || objdata.primitive==aDDict_map)     Scene->objects[current].texture=readbyte(&file); 
			if (objdata.red)          Scene->objects[current].color[0]=(float)readbyte(&file)/255.0f;
			if (objdata.green)        Scene->objects[current].color[1]=(float)readbyte(&file)/255.0f;
			if (objdata.blue)         Scene->objects[current].color[2]=(float)readbyte(&file)/255.0f;
			if (objdata.alpha)        Scene->objects[current].color[3]=(float)readbyte(&file)/255.0f;
			if (objdata.alphamap1set) readbyte(&file); 
			if (objdata.material2set) Scene->objects[current].envmap=readbyte(&file); 
			if (objdata.texxset || objdata.primitive==aDDict_map)      Scene->objects[current].texxscale=readbyte(&file); 
			if (objdata.texyset || objdata.primitive==aDDict_map)      Scene->objects[current].texyscale=readbyte(&file); 
			if (objdata.texoffxset || objdata.primitive==aDDict_map)   Scene->objects[current].texxoffset=readbyte(&file); 
			if (objdata.texoffyset || objdata.primitive==aDDict_map)   Scene->objects[current].texyoffset=readbyte(&file); 

			switch (objdata.primitive)
			{
			case aDDict_grid:
			case aDDict_hasab:
			case aDDict_cone:
			case aDDict_sphere:
				{
					Scene->objects[current].params[0]=readbyte(&file);
					Scene->objects[current].params[1]=readbyte(&file);
					break;
				}
			case aDDict_arc: 
				{
					Scene->objects[current].params[0]=readbyte(&file);
					Scene->objects[current].params[1]=readword(&file);
					break;
				}
			case aDDict_line: 
				{
					Scene->objects[current].params[0]=readbyte(&file);
					break;
				}
			case aDDict_loft: 
				{
					Scene->objects[current].params[0]=readword(&file);
					Scene->objects[current].params[1]=readword(&file);
					Scene->objects[current].params[2]=(int)Scene->objects;
					Scene->objects[current].params[3]=Scene->objectnum;
					break;
				}
			case aDDict_map:
				{
					texnum=readbyte(&file);
					Scene->objects[current].envmap=texnum;
					switch (texnum)
					{
					case 0:
						{
							xpse.x=readfloat(&file,floatbytes);
							xpse.y=readfloat(&file,floatbytes);
							xpse.z=readfloat(&file,floatbytes);
							break;
						}
					case 1:
						{
							xpse.x=readfloat(&file,floatbytes);
							xpse.y=readfloat(&file,floatbytes);
							xpse.z=readfloat(&file,floatbytes);
							break;
						}
					case 2:
						{
							xpse.x=readfloat(&file,floatbytes);
							xpse.y=readfloat(&file,floatbytes);
							xpse.z=readfloat(&file,floatbytes);
							phi=readfloat(&file,floatbytes);
							break;
						}
					}
					pt=findmaterial(Scene->objects[current].texture);
					t=findtexture(pt->texture);
					memcpy(maptexture,t->layers[pt->layer],256*256*4);
				}
			case aDDict_blur:
			case aDDict_linearsubdivision:
			case aDDict_butterfly: 
				{
					if (objdata.primitive!=aDDict_map)
						texnum=readbyte(&file);
					
					Scene->objects[current].params[1]=(int)readselection(&file);
					for (selection *s=(selection*)Scene->objects[current].params[1];s;s=s->next)
					{
						switch (Scene->objects[current].data.primitive)
						{
						case aDDict_map:
							{
								object *o=searchobjectbynumber(Scene->objects,Scene->objectnum,s->selected);
								obj_counttexturecoordinates( o,Scene->objects[current].texxscale,Scene->objects[current].texyscale,
									Scene->objects[current].texxoffset,
									Scene->objects[current].texyoffset,
									!Scene->objects[current].data.swaptexturexy,
									Scene->objects[current].data.inverttexx,
									Scene->objects[current].data.inverttexy);

								switch (Scene->objects[current].envmap)
								{
								case 0:
									{
										matrix s;
										for (int a=0; a<o->vertexnum; a++)
										{
											float p=getmappixel(o->vertices[a].t,Scene->objects[current].data.alphachannel,
												Scene->objects[current].data.normalsinverted);
											m_xpose(p*xpse.x,p*xpse.y,p*xpse.z,s);
											m_xformd(s,o->vertices[a].base,o->vertices[a].d);
										}
										break;
									}
								case 1:
									{
										matrix s;
										for (int a=0; a<o->vertexnum; a++)
										{
											float p=getmappixel(o->vertices[a].t,Scene->objects[current].data.alphachannel,
												Scene->objects[current].data.normalsinverted);
											m_scale(p*(xpse.x-1)+1,p*(xpse.y-1)+1,p*(xpse.z-1)+1,s);
											m_xformd(s,o->vertices[a].base,o->vertices[a].d);
										}									
										break;
									}
								case 2:
									{
										matrix s;
										for (int a=0; a<o->vertexnum; a++)
										{
											float p=getmappixel(o->vertices[a].t,Scene->objects[current].data.alphachannel,
												Scene->objects[current].data.normalsinverted);
											m_rotate(xpse.x,xpse.y,xpse.z,p*phi,s);
											m_xformd(s,o->vertices[a].base,o->vertices[a].d);
										}									
										break;
									}
								}
								for (int x=0; x<o->vertexnum; x++)
								{
									o->vertices[x].base=o->vertices[x].d;
									o->vertices[x].t=o->vertices[x].dt;
								}
								obj_counttexturecoordinates(o, o->texxscale, o->texyscale, o->texxoffset, o->texyoffset, o->data.swaptexturexy, o->data.inverttexx, o->data.inverttexy);
								obj_generatenormals(o);
								obj_transform(o,o->xformmatrix);
								break;
							}
						case aDDict_blur:
						case aDDict_linearsubdivision:
						case aDDict_butterfly: 
							{
								for (selection *s=(selection*)Scene->objects[current].params[1];s;s=s->next)
								{
									object *o=searchobjectbynumber(Scene->objects,Scene->objectnum,s->selected);
									for (int x=0; x<texnum; x++)
									{
										if (objdata.primitive==aDDict_blur) meshblur(o);
										else butterflysubdivision(o,objdata.primitive==aDDict_linearsubdivision);
									}
								}
								break;
							}
						}
					}
					
					break;
				}
			case aDDict_boolean: 
				{
					char function=readbyte(&file);
					int baseobj=readword(&file);
					int brush=readword(&file);
					//object *baseobject=searchobjectbynumber(Scene->objects,Scene->objectnum,baseobj);
					//object *brushobject=searchobjectbynumber(Scene->objects,Scene->objectnum,brush);
					matrix difference;//,m;
					readmatrix(&file, floatbytes, difference);

					//memcpy(m,brushobject->xformmatrix,sizeof(matrix));
					//matrix m2;
					//m_mult(baseobject->xformmatrix,difference,m2);
					//obj_transform(brushobject,m2);
					//obj_boolean(baseobject,brushobject,function);
					//memcpy(brushobject->xformmatrix,m,sizeof(matrix));
					//obj_transform(brushobject,brushobject->xformmatrix);
					break;
				}
			}
			
			if (objdata.primitive==aDDict_hasab) Scene->objects[current].params[2]=readbyte(&file);

			switch (objdata.primitive)
			{
			case aDDict_box:
			case aDDict_icosaeder:
			case aDDict_dodecaeder:
			case aDDict_sphere:
			case aDDict_hasab:
			case aDDict_cone:
			case aDDict_arc:
			case aDDict_loft:
			case aDDict_line:
			case aDDict_grid:
			case aDDict_clone:
				{
					readmatrix(&file, floatbytes, Scene->objects[current].xformmatrix);
					
					if (objdata.primitive==aDDict_clone)
					{
						Scene->objects[current].params[0]=(int)readselection(&file);
						Scene->objects[current].params[1]=(int)Scene->objects;
						Scene->objects[current].params[2]=Scene->objectnum;
					}
					
					obj_createprimitive(&Scene->objects[current],Scene->objects[current].data.primitive,Scene->objects[current].params[0],Scene->objects[current].params[1],Scene->objects[current].params[2],Scene->objects[current].params[3]);
					obj_transform(&Scene->objects[current],Scene->objects[current].xformmatrix);
					if (Scene->objects[current].data.primitive!=aDDict_clone)
					obj_counttexturecoordinates(&Scene->objects[current], Scene->objects[current].texxscale, Scene->objects[current].texyscale, Scene->objects[current].texxoffset, Scene->objects[current].texyoffset, Scene->objects[current].data.swaptexturexy, Scene->objects[current].data.inverttexx, Scene->objects[current].data.inverttexy);
					obj_generatenormals(&Scene->objects[current]);

					for (int x=0; x<Scene->objects[current].polygonnum; x++)
					{

						Scene->objects[current].polygons[x].color.x=Scene->objects[current].color[0];
						Scene->objects[current].polygons[x].color.y=Scene->objects[current].color[1];
						Scene->objects[current].polygons[x].color.z=Scene->objects[current].color[2];
						Scene->objects[current].polygons[x].color.w=Scene->objects[current].color[3];
						if (Scene->objects[current].data.shading!=aDDict_default) Scene->objects[current].polygons[x].shading=Scene->objects[current].data.shading;
					}

					if (Scene->objects[current].data.textured && Scene->objects[current].data.primitive!=aDDict_clone)
					{
						material *m=findmaterial(Scene->objects[current].texture);
						if (m!=NULL)
						for (int x=0; x<Scene->objects[current].polygonnum; x++)
						{
							Scene->objects[current].polygons[x].texturehandle=m->handle;
						}
					}

					if (Scene->objects[current].data.material2set && Scene->objects[current].data.primitive!=aDDict_clone)
					{
						material *m=findmaterial(Scene->objects[current].envmap);
						if (m!=NULL)
						for (int x=0; x<Scene->objects[current].polygonnum; x++)
						{
							Scene->objects[current].polygons[x].envmaphandle=m->handle;
						}
					}
					
					break;
				}
			}
		}

		//////////////////////////// CAMERA LOAD ////////////////////////////////
		//MessageBox( 0, "camload", "HelloWorld", MB_OK );
		
		byte camnum=readbyte(&file);
		for (aa=1; aa<=camnum; aa++)
		{
			camera *c=new camera;
			memset(c,0,sizeof(camera));
			c->next=Scene->cameras;
			Scene->cameras=c;
			c->number=readbyte(&file); //camera ID
			c->up.y=-1;
			byte keyframenum=readbyte(&file);
			if (keyframenum)
			{
				//c->eyex.numkey=keyframenum;
				//c->eyex.keys=new KEY[keyframenum];
				c->eyex=new CTrack(keyframenum);
				c->eyey=new CTrack(keyframenum);
				c->eyez=new CTrack(keyframenum);
				c->trgx=new CTrack(keyframenum);
				c->trgy=new CTrack(keyframenum);
				c->trgz=new CTrack(keyframenum);
				c->fovt=new CTrack(keyframenum);
				c->rollt=new CTrack(keyframenum);

				/*c->eyey.numkey=keyframenum;
				c->eyey.keys=new KEY[keyframenum];
				c->eyez.numkey=keyframenum;
				c->eyez.keys=new KEY[keyframenum];
				c->trgx.numkey=keyframenum;
				c->trgx.keys=new KEY[keyframenum];
				c->trgy.numkey=keyframenum;
				c->trgy.keys=new KEY[keyframenum];
				c->trgz.numkey=keyframenum;
				c->trgz.keys=new KEY[keyframenum];
				c->fovt.numkey=keyframenum;
				c->fovt.keys=new KEY[keyframenum];
				c->rollt.numkey=keyframenum;
				c->rollt.keys=new KEY[keyframenum];*/

				int frame=readword(&file); //frame
				int fov=readbyte(&file); //fov
				int roll=readword(&file); //roll
				float eyex=readfloat(&file,floatbytes); //eyex
				float eyey=readfloat(&file,floatbytes); //eyey
				float eyez=readfloat(&file,floatbytes); //eyez
				float trgx=readfloat(&file,floatbytes); //trgx
				float trgy=readfloat(&file,floatbytes); //trgy
				float trgz=readfloat(&file,floatbytes); //trgz
				setkeydata(c->eyex->keys,frame,eyex);
				setkeydata(c->eyey->keys,frame,eyey);
				setkeydata(c->eyez->keys,frame,eyez);
				setkeydata(c->trgx->keys,frame,trgx);
				setkeydata(c->trgy->keys,frame,trgy);
				setkeydata(c->trgz->keys,frame,trgz);
				setkeydata(c->fovt->keys,frame,(float)fov);
				setkeydata(c->rollt->keys,frame,(float)roll);
				/*c->eyex.keys[0].data=eyex;
				c->eyex.keys[0].frame=frame;
				c->eyey.keys[0].data=eyey;
				c->eyey.keys[0].frame=frame;
				c->eyez.keys[0].data=eyez;
				c->eyez.keys[0].frame=frame;
				c->trgx.keys[0].data=trgx;
				c->trgx.keys[0].frame=frame;
				c->trgy.keys[0].data=trgy;
				c->trgy.keys[0].frame=frame;
				c->trgz.keys[0].data=trgz;
				c->trgz.keys[0].frame=frame;
				c->fovt.keys[0].data=(float)fov;
				c->fovt.keys[0].frame=frame;
				c->rollt.keys[0].data=(float)roll;
				c->rollt.keys[0].frame=frame;*/

				for (int x=1; x<keyframenum; x++)
				{
					frame=readword(&file); //frame

					camfield cf;
					memset(&cf,0,sizeof(cf));
					memcpy(&cf,file,1); //mask
					file+=1;

					if (cf.fovwritten) fov=readbyte(&file);
					if (cf.rollwritten) roll=readword(&file);
					if (cf.eyexwritten) eyex=readfloat(&file,floatbytes);
					if (cf.eyeywritten) eyey=readfloat(&file,floatbytes);
					if (cf.eyezwritten) eyez=readfloat(&file,floatbytes);
					if (cf.targetxwritten) trgx=readfloat(&file,floatbytes);
					if (cf.targetywritten) trgy=readfloat(&file,floatbytes);
					if (cf.targetzwritten) trgz=readfloat(&file,floatbytes);

					/*c->eyex.keys[x].data=eyex;
					c->eyex.keys[x].frame=frame;
					c->eyey.keys[x].data=eyey;
					c->eyey.keys[x].frame=frame;
					c->eyez.keys[x].data=eyez;
					c->eyez.keys[x].frame=frame;
					c->trgx.keys[x].data=trgx;
					c->trgx.keys[x].frame=frame;
					c->trgy.keys[x].data=trgy;
					c->trgy.keys[x].frame=frame;
					c->trgz.keys[x].data=trgz;
					c->trgz.keys[x].frame=frame;
					c->fovt.keys[x].data=(float)fov;
					c->fovt.keys[x].frame=frame;
					c->rollt.keys[x].data=(float)roll;
					c->rollt.keys[x].frame=frame;*/
					
					setkeydata(&c->eyex->keys[x],frame,eyex);
					setkeydata(&c->eyey->keys[x],frame,eyey);
					setkeydata(&c->eyez->keys[x],frame,eyez);
					setkeydata(&c->trgx->keys[x],frame,trgx);
					setkeydata(&c->trgy->keys[x],frame,trgy);
					setkeydata(&c->trgz->keys[x],frame,trgz);
					setkeydata(&c->fovt->keys[x],frame,(float)fov);
					setkeydata(&c->rollt->keys[x],frame,(float)roll);

				}
				c->eyex->InitVectors();
				c->eyey->InitVectors();
				c->eyez->InitVectors();
				c->trgx->InitVectors();
				c->trgy->InitVectors();
				c->trgz->InitVectors();
				c->fovt->InitVectors();
				c->rollt->InitVectors();
			}
		}
		//MessageBox( 0, "objload", "HelloWorld", MB_OK );
		///////////////////////// OBJECT ANIM LOAD /////////////////////////////

		byte animnum=readbyte(&file);
		for (aa=1; aa<=animnum; aa++)
		{
			byte animid=readbyte(&file); //anim ID
			int on;
			for (on=0;on<Scene->objectnum;on++)
			{
				objanim *o=new objanim;
				memset(o,0,sizeof(objanim));
				o->next=Scene->objects[on].anims;
				Scene->objects[on].anims=o;
				o->number=animid;
			}
			for (on=0;on<Scene->objectnum;on++)
				if (Scene->objects[on].data.primitive!=9 && 
					Scene->objects[on].data.primitive!=11 &&
					Scene->objects[on].data.primitive<100)
				{
					byte keyframenum=readbyte(&file);
					Scene->objects[on].anims->posx=new CTrack(keyframenum);
					Scene->objects[on].anims->posy=new CTrack(keyframenum);
					Scene->objects[on].anims->posz=new CTrack(keyframenum);
					Scene->objects[on].anims->rotx=new CTrack(keyframenum);
					Scene->objects[on].anims->roty=new CTrack(keyframenum);
					Scene->objects[on].anims->rotz=new CTrack(keyframenum);
					Scene->objects[on].anims->rota=new CTrack(keyframenum);
					Scene->objects[on].anims->strx=new CTrack(keyframenum);
					Scene->objects[on].anims->stry=new CTrack(keyframenum);
					Scene->objects[on].anims->strz=new CTrack(keyframenum);
					Scene->objects[on].anims->colr=new CTrack(keyframenum);
					Scene->objects[on].anims->colg=new CTrack(keyframenum);
					Scene->objects[on].anims->colb=new CTrack(keyframenum);
					Scene->objects[on].anims->cola=new CTrack(keyframenum);
					if (keyframenum)
					{
						int frame=(unsigned short)readword(&file); //frame

						float posx=readfloat(&file,floatbytes); //posx
						float posy=readfloat(&file,floatbytes); //posy
						float posz=readfloat(&file,floatbytes); //posz

						float rotx=readfloat(&file,floatbytes); //rotx
						float roty=readfloat(&file,floatbytes); //roty
						float rotz=readfloat(&file,floatbytes); //rotz
						int rota=readword(&file); //rota

						float strx=readfloat(&file,floatbytes); //strx
						float stry=readfloat(&file,floatbytes); //stry
						float strz=readfloat(&file,floatbytes); //strz

						float colr=(float)readbyte(&file)/255.0f; //colr
						float colg=(float)readbyte(&file)/255.0f; //colg
						float colb=(float)readbyte(&file)/255.0f; //colb
						float cola=(float)readbyte(&file)/255.0f; //cola

						setkeydata(Scene->objects[on].anims->posx->keys,frame,posx);
						setkeydata(Scene->objects[on].anims->posy->keys,frame,posy);
						setkeydata(Scene->objects[on].anims->posz->keys,frame,posz);
						setkeydata(Scene->objects[on].anims->rotx->keys,frame,rotx);
						setkeydata(Scene->objects[on].anims->roty->keys,frame,roty);
						setkeydata(Scene->objects[on].anims->rotz->keys,frame,rotz);
						setkeydata(Scene->objects[on].anims->rota->keys,frame,(float)rota);
						setkeydata(Scene->objects[on].anims->strx->keys,frame,strx);
						setkeydata(Scene->objects[on].anims->stry->keys,frame,stry);
						setkeydata(Scene->objects[on].anims->strz->keys,frame,strz);
						setkeydata(Scene->objects[on].anims->colr->keys,frame,colr);
						setkeydata(Scene->objects[on].anims->colg->keys,frame,colg);
						setkeydata(Scene->objects[on].anims->colb->keys,frame,colb);
						setkeydata(Scene->objects[on].anims->cola->keys,frame,cola);

						/*Scene->objects[on].anims->posx.keys[0].frame=frame;
						Scene->objects[on].anims->posx.keys[0].data=posx;
						Scene->objects[on].anims->posy.keys[0].frame=frame;
						Scene->objects[on].anims->posy.keys[0].data=posy;
						Scene->objects[on].anims->posz.keys[0].frame=frame;
						Scene->objects[on].anims->posz.keys[0].data=posz;
						Scene->objects[on].anims->rotx.keys[0].frame=frame;
						Scene->objects[on].anims->rotx.keys[0].data=rotx;
						Scene->objects[on].anims->roty.keys[0].frame=frame;
						Scene->objects[on].anims->roty.keys[0].data=roty;
						Scene->objects[on].anims->rotz.keys[0].frame=frame;
						Scene->objects[on].anims->rotz.keys[0].data=rotz;
						Scene->objects[on].anims->rota.keys[0].frame=frame;
						Scene->objects[on].anims->rota.keys[0].data=(float)rota;
						Scene->objects[on].anims->strx.keys[0].frame=frame;
						Scene->objects[on].anims->strx.keys[0].data=strx;
						Scene->objects[on].anims->stry.keys[0].frame=frame;
						Scene->objects[on].anims->stry.keys[0].data=stry;
						Scene->objects[on].anims->strz.keys[0].frame=frame;
						Scene->objects[on].anims->strz.keys[0].data=strz;
						Scene->objects[on].anims->colr.keys[0].frame=frame;
						Scene->objects[on].anims->colr.keys[0].data=colr;
						Scene->objects[on].anims->colg.keys[0].frame=frame;
						Scene->objects[on].anims->colg.keys[0].data=colg;
						Scene->objects[on].anims->colb.keys[0].frame=frame;
						Scene->objects[on].anims->colb.keys[0].data=colb;
						Scene->objects[on].anims->cola.keys[0].frame=frame;
						Scene->objects[on].anims->cola.keys[0].data=cola;*/

						for (int x=1; x<keyframenum; x++)
						{
							frame=readword(&file); //frame

							objfield c;
							memset(&c,0,sizeof(c));
							memcpy(&c,file,2); //mask
							file+=2;

							if (c.posx) posx=readfloat(&file,floatbytes);
							if (c.posy) posy=readfloat(&file,floatbytes);
							if (c.posz) posz=readfloat(&file,floatbytes);

							if (c.rotx) rotx=readfloat(&file,floatbytes);
							if (c.roty) roty=readfloat(&file,floatbytes);
							if (c.rotz) rotz=readfloat(&file,floatbytes);
							if (c.rota) rota=readword(&file);

							if (c.strx) strx=readfloat(&file,floatbytes);
							if (c.stry) stry=readfloat(&file,floatbytes);
							if (c.strz) strz=readfloat(&file,floatbytes);

							if (c.colr) colr=(float)readbyte(&file)/255.f;
							if (c.colg) colg=(float)readbyte(&file)/255.f;
							if (c.colb) colb=(float)readbyte(&file)/255.f;
							if (c.cola) cola=(float)readbyte(&file)/255.f;

							/*Scene->objects[on].anims->posx.keys[x].frame=frame;
							Scene->objects[on].anims->posx.keys[x].data=posx;
							Scene->objects[on].anims->posy.keys[x].frame=frame;
							Scene->objects[on].anims->posy.keys[x].data=posy;
							Scene->objects[on].anims->posz.keys[x].frame=frame;
							Scene->objects[on].anims->posz.keys[x].data=posz;
							Scene->objects[on].anims->rotx.keys[x].frame=frame;
							Scene->objects[on].anims->rotx.keys[x].data=rotx;
							Scene->objects[on].anims->roty.keys[x].frame=frame;
							Scene->objects[on].anims->roty.keys[x].data=roty;
							Scene->objects[on].anims->rotz.keys[x].frame=frame;
							Scene->objects[on].anims->rotz.keys[x].data=rotz;
							Scene->objects[on].anims->rota.keys[x].frame=frame;
							Scene->objects[on].anims->rota.keys[x].data=(float)rota;
							Scene->objects[on].anims->strx.keys[x].frame=frame;
							Scene->objects[on].anims->strx.keys[x].data=strx;
							Scene->objects[on].anims->stry.keys[x].frame=frame;
							Scene->objects[on].anims->stry.keys[x].data=stry;
							Scene->objects[on].anims->strz.keys[x].frame=frame;
							Scene->objects[on].anims->strz.keys[x].data=strz;
							Scene->objects[on].anims->colr.keys[x].frame=frame;
							Scene->objects[on].anims->colr.keys[x].data=colr;
							Scene->objects[on].anims->colg.keys[x].frame=frame;
							Scene->objects[on].anims->colg.keys[x].data=colg;
							Scene->objects[on].anims->colb.keys[x].frame=frame;
							Scene->objects[on].anims->colb.keys[x].data=colb;
							Scene->objects[on].anims->cola.keys[x].frame=frame;
							Scene->objects[on].anims->cola.keys[x].data=cola;*/
						
							setkeydata(&Scene->objects[on].anims->posx->keys[x],frame,posx);
							setkeydata(&Scene->objects[on].anims->posy->keys[x],frame,posy);
							setkeydata(&Scene->objects[on].anims->posz->keys[x],frame,posz);
							setkeydata(&Scene->objects[on].anims->rotx->keys[x],frame,rotx);
							setkeydata(&Scene->objects[on].anims->roty->keys[x],frame,roty);
							setkeydata(&Scene->objects[on].anims->rotz->keys[x],frame,rotz);
							setkeydata(&Scene->objects[on].anims->rota->keys[x],frame,(float)rota);
							setkeydata(&Scene->objects[on].anims->strx->keys[x],frame,strx);
							setkeydata(&Scene->objects[on].anims->stry->keys[x],frame,stry);
							setkeydata(&Scene->objects[on].anims->strz->keys[x],frame,strz);
							setkeydata(&Scene->objects[on].anims->colr->keys[x],frame,colr);
							setkeydata(&Scene->objects[on].anims->colg->keys[x],frame,colg);
							setkeydata(&Scene->objects[on].anims->colb->keys[x],frame,colb);
							setkeydata(&Scene->objects[on].anims->cola->keys[x],frame,cola);
						}

						Scene->objects[on].anims->posx->InitVectors();
						Scene->objects[on].anims->posy->InitVectors();
						Scene->objects[on].anims->posz->InitVectors();
						Scene->objects[on].anims->rotx->InitVectors();
						Scene->objects[on].anims->roty->InitVectors();
						Scene->objects[on].anims->rotz->InitVectors();
						Scene->objects[on].anims->rota->InitVectors();
						Scene->objects[on].anims->strx->InitVectors();
						Scene->objects[on].anims->stry->InitVectors();
						Scene->objects[on].anims->strz->InitVectors();
						Scene->objects[on].anims->colr->InitVectors();
						Scene->objects[on].anims->colg->InitVectors();
						Scene->objects[on].anims->colb->InitVectors();
						Scene->objects[on].anims->cola->InitVectors();
					}
				}
		}

		Scene->next=scenelist;
		scenelist=Scene;
	}

	////////////////////////// EVENT LOAD ///////////////////////////////

	int eventnum=readword(&file);
	for (aa=1; aa<=eventnum; aa++)
	{
		event *e=new event;
		memset(e,0,sizeof(event));
		if (eventlist==NULL)
		{
			eventlist=e;
			lastevent=e;
		}
		else
		{
			lastevent->next=e;
			lastevent=e;
		}

		e->eventtype=readbyte(&file);
		e->startframe=(unsigned short)readword(&file)*10; //startframe
		e->endframe=(unsigned short)readword(&file)*10+9; //endframe
		e->pass=readbyte(&file); //pass
		if (e->eventtype==layer2d || e->eventtype==layer3d || e->eventtype==rendertotext || e->eventtype==feedback || e->eventtype==grideffect)
		{
			e->startrectx1=readword(&file);
			e->startrecty1=readword(&file);
			e->startrectx2=readword(&file);
			e->startrecty2=readword(&file);

			e->endrectx1=readword(&file);
			e->endrecty1=readword(&file);
			e->endrectx2=readword(&file);
			e->endrecty2=readword(&file);
		}
		if (e->eventtype==layer2d || e->eventtype==feedback || e->eventtype==grideffect)
		{
			e->startcol[0]=(float)readbyte(&file)/255.0f;
			e->startcol[1]=(float)readbyte(&file)/255.0f;
			e->startcol[2]=(float)readbyte(&file)/255.0f;
			e->startcol[3]=(float)readbyte(&file)/255.0f;

			e->endcol[0]=(float)readbyte(&file)/255.0f;
			e->endcol[1]=(float)readbyte(&file)/255.0f;
			e->endcol[2]=(float)readbyte(&file)/255.0f;
			e->endcol[3]=(float)readbyte(&file)/255.0f;

			switch (readbyte(&file))
			{
				case  0:e->blendfunc1=GL_ZERO; break;
				case  1:e->blendfunc1=GL_ONE; break;
				case  2:e->blendfunc1=GL_SRC_COLOR; break;
				case  3:e->blendfunc1=GL_ONE_MINUS_SRC_COLOR; break;
				case  4:e->blendfunc1=GL_SRC_ALPHA; break;
				case  5:e->blendfunc1=GL_ONE_MINUS_SRC_ALPHA; break;
				case  6:e->blendfunc1=GL_DST_ALPHA; break;
				case  7:e->blendfunc1=GL_ONE_MINUS_DST_ALPHA; break;
				case  8:e->blendfunc1=GL_DST_COLOR; break;
				case  9:e->blendfunc1=GL_ONE_MINUS_DST_COLOR; break;
				case 10:e->blendfunc1=GL_SRC_ALPHA_SATURATE; break;
			}
			switch (readbyte(&file))
			{
				case  0:e->blendfunc2=GL_ZERO; break;
				case  1:e->blendfunc2=GL_ONE; break;
				case  2:e->blendfunc2=GL_SRC_COLOR; break;
				case  3:e->blendfunc2=GL_ONE_MINUS_SRC_COLOR; break;
				case  4:e->blendfunc2=GL_SRC_ALPHA; break;
				case  5:e->blendfunc2=GL_ONE_MINUS_SRC_ALPHA; break;
				case  6:e->blendfunc2=GL_DST_ALPHA; break;
				case  7:e->blendfunc2=GL_ONE_MINUS_DST_ALPHA; break;
				case  8:e->blendfunc2=GL_DST_COLOR; break;
				case  9:e->blendfunc2=GL_ONE_MINUS_DST_COLOR; break;
				case 10:e->blendfunc2=GL_SRC_ALPHA_SATURATE; break;
			}
		}
		
		switch (e->eventtype)
		{
		case layer2d:
			{
				e->textured=readbyte(&file);
				e->texture=readbyte(&file);
				e->mattexture=findmaterial(e->texture)->handle;
				break;
			}
		case layer3d:
			{
				e->sceneid=readbyte(&file);
				e->camid=readbyte(&file);
				e->animid=readbyte(&file);
				e->camstart=readword(&file);
				e->camend=readword(&file);
				e->animstart=readword(&file);
				e->animend=readword(&file);
				e->iscene=findscene(e->sceneid);
				e->icam=findcam(e->iscene,e->camid);
				e->ianim=e->animid;
				break;
			}
		case cleargl:
			{
				e->clearscreen=readbyte(&file);
				e->clearzbuffer=readbyte(&file);
				break;
			}
		case rendertotext:
			{
				e->texture=readbyte(&file);
				break;
			}
		case feedback:
			{
				e->texture=readbyte(&file);
				e->param1=readbyte(&file);
				e->param4=readfloat(&file,floatbytes);
				break;
			}
		case grideffect:
			{
				e->texture=readbyte(&file);
				e->effect=readbyte(&file);
				e->gridstart=readfloat(&file,floatbytes);
				e->gridend=readfloat(&file,floatbytes);
				break;
			}
		}
	}
}
void distribPhotonContrib (PhotonMap* pm, unsigned numProc)
{
   EmissionMap       emap;
   char              errmsg2 [128], shmFname [PMAP_TMPFNLEN];
   unsigned          srcIdx, proc;
   int               shmFile, stat, pid;
   double            *srcFlux,         /* Emitted flux per light source */
                     srcDistribTarget; /* Target photon count per source */
   PhotonContribCnt  *photonCnt;       /* Photon emission counter array */
   unsigned          photonCntSize = sizeof(PhotonContribCnt) * 
                                     PHOTONCNT_NUMEMIT(nsources);
   FILE              **primaryHeap = NULL;
   char              **primaryHeapFname = NULL;
   PhotonPrimaryIdx  *primaryOfs = NULL;
                                    
   if (!pm)
      error(USER, "no photon map defined in distribPhotonContrib");
      
   if (!nsources)
      error(USER, "no light sources in distribPhotonContrib");

   if (nsources > MAXMODLIST)
      error(USER, "too many light sources in distribPhotonContrib");
      
   /* Allocate photon flux per light source; this differs for every 
    * source as all sources contribute the same number of distributed
    * photons (srcDistribTarget), hence the number of photons emitted per
    * source does not correlate with its emitted flux. The resulting flux
    * per photon is therefore adjusted individually for each source. */
   if (!(srcFlux = calloc(nsources, sizeof(double))))
      error(SYSTEM, "can't allocate source flux in distribPhotonContrib");

   /* ===================================================================
    * INITIALISATION - Set up emission and scattering funcs
    * =================================================================== */
   emap.samples = NULL;
   emap.src = NULL;
   emap.maxPartitions = MAXSPART;
   emap.partitions = (unsigned char*)malloc(emap.maxPartitions >> 1);
   if (!emap.partitions)
      error(USER, "can't allocate source partitions in distribPhotonContrib");

   /* Initialise contrib photon map */   
   initPhotonMap(pm, PMAP_TYPE_CONTRIB);
   initPhotonHeap(pm);
   initPhotonEmissionFuncs();
   initPhotonScatterFuncs();
   
   /* Per-subprocess / per-source target counts */
   pm -> distribTarget /= numProc;
   srcDistribTarget = nsources ? (double)pm -> distribTarget / nsources : 0;   
   
   if (!pm -> distribTarget)
      error(INTERNAL, "no photons to distribute in distribPhotonContrib");
   
   /* Get photon ports from modifier list */
   getPhotonPorts(photonPortList);
      
   /* Get photon sensor modifiers */
   getPhotonSensors(photonSensorList);      

#if NIX   
   /* Set up shared mem for photon counters (zeroed by ftruncate) */
   strcpy(shmFname, PMAP_TMPFNAME);
   shmFile = mkstemp(shmFname);
   
   if (shmFile < 0 || ftruncate(shmFile, photonCntSize) < 0)
      error(SYSTEM, "failed shared mem init in distribPhotonContrib");

   photonCnt = mmap(NULL, photonCntSize, PROT_READ | PROT_WRITE, 
                    MAP_SHARED, shmFile, 0);
                     
   if (photonCnt == MAP_FAILED)
      error(SYSTEM, "failed shared mem mapping in distribPhotonContrib");
#else
   /* Allocate photon counters statically on Windoze */
   if (!(photonCnt = malloc(photonCntSize)))
      error(SYSTEM, "failed trivial malloc in distribPhotonContrib");
   
   for (srcIdx = 0; srcIdx < PHOTONCNT_NUMEMIT(nsources); srcIdx++)
      photonCnt [srcIdx] = 0;
#endif /* NIX */

   if (verbose) {
      sprintf(errmsg, "\nIntegrating flux from %d sources", nsources);

      if (photonPorts) {
         sprintf(errmsg2, " via %d ports", numPhotonPorts);
         strcat(errmsg, errmsg2);
      }

      strcat(errmsg, "\n");
      eputs(errmsg);
   }

   /* =============================================================
    * FLUX INTEGRATION - Get total flux emitted from sources/ports
    * ============================================================= */   
   for (srcIdx = 0; srcIdx < nsources; srcIdx++) {
      unsigned portCnt = 0;      
      srcFlux [srcIdx] = 0;
      emap.src = source + srcIdx;
      
      do {  /* Need at least one iteration if no ports! */      
         emap.port = emap.src -> sflags & SDISTANT ? photonPorts + portCnt 
                                                   : NULL;
         photonPartition [emap.src -> so -> otype] (&emap);

         if (verbose) {
            sprintf(errmsg, "\tIntegrating flux from source %s ",
                    source [srcIdx].so -> oname);

            if (emap.port) {
               sprintf(errmsg2, "via port %s ", 
                       photonPorts [portCnt].so -> oname);
               strcat(errmsg, errmsg2);
            }

            sprintf(errmsg2, "(%lu partitions)\n", emap.numPartitions);
            strcat(errmsg, errmsg2);
            eputs(errmsg);
#if NIX            
            fflush(stderr);
#endif            
         }                    
         
         for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions;
              emap.partitionCnt++) {
            initPhotonEmission(&emap, pdfSamples);
            srcFlux [srcIdx] += colorAvg(emap.partFlux);
         }
         
         portCnt++;
      } while (portCnt < numPhotonPorts);         
      
      if (srcFlux [srcIdx] < FTINY) {
         sprintf(errmsg, "source %s has zero emission", 
                 source [srcIdx].so -> oname);
         error(WARNING, errmsg);
      }
   }   
   
   /* Allocate & init per-subprocess primary heap files */
   primaryHeap = calloc(numProc, sizeof(FILE*));
   primaryHeapFname = calloc(numProc, sizeof(char*));
   primaryOfs = calloc(numProc, sizeof(PhotonPrimaryIdx));
   if (!primaryHeap || !primaryHeapFname || !primaryOfs)
      error(SYSTEM, "failed primary heap allocation in "
            "distribPhotonContrib");
      
   for (proc = 0; proc < numProc; proc++) {
      primaryHeapFname [proc] = malloc(PMAP_TMPFNLEN);
      if (!primaryHeapFname [proc])
         error(SYSTEM, "failed primary heap file allocation in "
               "distribPhotonContrib");
               
      mktemp(strcpy(primaryHeapFname [proc], PMAP_TMPFNAME));
      if (!(primaryHeap [proc] = fopen(primaryHeapFname [proc], "w+b")))
         error(SYSTEM, "failed opening primary heap file in "
               "distribPhotonContrib");
   }               

   /* Record start time for progress reports */
   repStartTime = time(NULL);

   if (verbose) {
      sprintf(errmsg, "\nPhoton distribution @ %d procs\n", numProc);
      eputs(errmsg);
   }
               
   /* MAIN LOOP */
   for (proc = 0; proc < numProc; proc++) {
#if NIX          
      if (!(pid = fork())) {
         /* SUBPROCESS ENTERS HERE; opened and mmapped files inherited */
#else
      if (1) {
         /* No subprocess under Windoze */
#endif   
         /* Local photon counters for this subprocess */
         unsigned long  lastNumPhotons = 0, localNumEmitted = 0;
         double         photonFluxSum = 0;   /* Accum. photon flux */

         /* Seed RNGs from PID for decorellated photon distribution */
         pmapSeed(randSeed + proc, partState);
         pmapSeed(randSeed + (proc + 1) % numProc, emitState);
         pmapSeed(randSeed + (proc + 2) % numProc, cntState);
         pmapSeed(randSeed + (proc + 3) % numProc, mediumState);
         pmapSeed(randSeed + (proc + 4) % numProc, scatterState);
         pmapSeed(randSeed + (proc + 5) % numProc, rouletteState);

#ifdef PMAP_SIGUSR                       
   double partNumEmit;
   unsigned long partEmitCnt;
   double srcPhotonFlux, avgPhotonFlux;
   unsigned       portCnt, passCnt, prePassCnt;
   float          srcPreDistrib;
   double         srcNumEmit;     /* # to emit from source */
   unsigned long  srcNumDistrib;  /* # stored */

   void sigUsrDiags()
   /* Loop diags via SIGUSR1 */
   {
      sprintf(errmsg, 
              "********************* Proc %d Diags *********************\n"
              "srcIdx = %d (%s)\nportCnt = %d (%s)\npassCnt = %d\n"
              "srcFlux = %f\nsrcPhotonFlux = %f\navgPhotonFlux = %f\n"
              "partNumEmit = %f\npartEmitCnt = %lu\n\n",
              proc, srcIdx, findmaterial(source [srcIdx].so) -> oname, 
              portCnt, photonPorts [portCnt].so -> oname,
              passCnt, srcFlux [srcIdx], srcPhotonFlux, avgPhotonFlux,
              partNumEmit, partEmitCnt);
      eputs(errmsg);
      fflush(stderr);
   }
#endif
         
#ifdef PMAP_SIGUSR
         signal(SIGUSR1, sigUsrDiags);
#endif         

#ifdef DEBUG_PMAP          
         /* Output child process PID after random delay to prevent corrupted
          * console output due to race condition */
         usleep(1e6 * pmapRandom(rouletteState));
         fprintf(stderr, "Proc %d: PID = %d "
                 "(waiting 10 sec to attach debugger...)\n", 
                 proc, getpid());
         /* Allow time for debugger to attach to child process */
         sleep(10);
#endif

         /* =============================================================
          * 2-PASS PHOTON DISTRIBUTION
          * Pass 1 (pre):  emit fraction of target photon count
          * Pass 2 (main): based on outcome of pass 1, estimate remaining 
          *                number of photons to emit to approximate target 
          *                count
          * ============================================================= */
         for (srcIdx = 0; srcIdx < nsources; srcIdx++) {
#ifndef PMAP_SIGUSR         
            unsigned       portCnt, passCnt = 0, prePassCnt = 0;
            float          srcPreDistrib = preDistrib;
            double         srcNumEmit = 0;       /* # to emit from source */
            unsigned long  srcNumDistrib = pm -> numPhotons;  /* # stored */
#else
            passCnt = prePassCnt = 0;
            srcPreDistrib = preDistrib;
            srcNumEmit = 0;       /* # to emit from source */
            srcNumDistrib = pm -> numPhotons;  /* # stored */
#endif            

            if (srcFlux [srcIdx] < FTINY)
               continue;
                        
            while (passCnt < 2) {
               if (!passCnt) {   
                  /* INIT PASS 1 */
                  if (++prePassCnt > maxPreDistrib) {
                     /* Warn if no photons contributed after sufficient
                      * iterations; only output from subprocess 0 to reduce
                      * console clutter */
                     if (!proc) {
                        sprintf(errmsg, 
                                "source %s: too many prepasses, skipped",
                                source [srcIdx].so -> oname);
                        error(WARNING, errmsg);
                     }

                     break;
                  }
                  
                  /* Num to emit is fraction of target count */
                  srcNumEmit = srcPreDistrib * srcDistribTarget;
               }
               else {
                  /* INIT PASS 2 */
#ifndef PMAP_SIGUSR
                  double srcPhotonFlux, avgPhotonFlux;
#endif
                  
                  /* Based on the outcome of the predistribution we can now
                   * figure out how many more photons we have to emit from
                   * the current source to meet the target count,
                   * srcDistribTarget. This value is clamped to 0 in case
                   * the target has already been exceeded in pass 1.
                   * srcNumEmit and srcNumDistrib is the number of photons
                   * emitted and distributed (stored) from the current
                   * source in pass 1, respectively. */
                  srcNumDistrib = pm -> numPhotons - srcNumDistrib;
                  srcNumEmit *= srcNumDistrib 
                                ? max(srcDistribTarget/srcNumDistrib, 1) - 1
                                : 0;

                  if (!srcNumEmit)
                     /* No photons left to distribute in main pass */
                     break;
                     
                  srcPhotonFlux = srcFlux [srcIdx] / srcNumEmit;
                  avgPhotonFlux = photonFluxSum / (srcIdx + 1);
                  
                  if (avgPhotonFlux > FTINY && 
                      srcPhotonFlux / avgPhotonFlux < FTINY) {
                     /* Skip source if its photon flux is grossly below the
                      * running average, indicating negligible contributions
                      * at the expense of excessive distribution time; only
                      * output from subproc 0 to reduce console clutter */
                     if (!proc) {
                        sprintf(errmsg, 
                                "source %s: itsy bitsy photon flux, skipped",
                                source [srcIdx].so -> oname);                     
                        error(WARNING, errmsg);
                     }

                     srcNumEmit = 0;   /* Or just break??? */
                  }
                        
                  /* Update sum of photon flux per light source */
                  photonFluxSum += srcPhotonFlux;
               }
                              
               portCnt = 0;
               do {    /* Need at least one iteration if no ports! */
                  emap.src = source + srcIdx;
                  emap.port = emap.src -> sflags & SDISTANT 
                              ? photonPorts + portCnt : NULL;
                  photonPartition [emap.src -> so -> otype] (&emap);

                  if (verbose && !proc) {
                     /* Output from subproc 0 only to avoid race condition
                      * on console I/O */
                     if (!passCnt)
                        sprintf(errmsg, "\tPREPASS %d on source %s ",
                                prePassCnt, source [srcIdx].so -> oname);
                     else 
                        sprintf(errmsg, "\tMAIN PASS on source %s ",
                                source [srcIdx].so -> oname);

                     if (emap.port) {
                        sprintf(errmsg2, "via port %s ", 
                                photonPorts [portCnt].so -> oname);
                        strcat(errmsg, errmsg2);
                     }

                     sprintf(errmsg2, "(%lu partitions)\n",
                             emap.numPartitions);
                     strcat(errmsg, errmsg2);                     
                     eputs(errmsg);
#if NIX                     
                     fflush(stderr);
#endif                     
                  }                
                  
                  for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions; 
                       emap.partitionCnt++) {
#ifndef PMAP_SIGUSR                       
                     double partNumEmit;
                     unsigned long partEmitCnt;
#endif
                     
                     /* Get photon origin within current source partishunn
                      * and build emission map */
                     photonOrigin [emap.src -> so -> otype] (&emap);
                     initPhotonEmission(&emap, pdfSamples);
                     
                     /* Number of photons to emit from ziss partishunn;
                      * scale according to its normalised contribushunn to
                      * the emitted source flux */                     
                     partNumEmit = srcNumEmit * colorAvg(emap.partFlux) /
                                   srcFlux [srcIdx];                    
                     partEmitCnt = (unsigned long)partNumEmit;
                                                               
                     /* Probabilistically account for fractional photons */
                     if (pmapRandom(cntState) < partNumEmit - partEmitCnt)
                        partEmitCnt++;
                        
                     /* Update local and shared global emission counter */
                     photonCnt [PHOTONCNT_NUMEMIT(srcIdx)] += partEmitCnt;
                     localNumEmitted += partEmitCnt;                                    
                     
                     /* Integer counter avoids FP rounding errors during
                      * iteration */
                     while (partEmitCnt--) {
                        RAY photonRay;
                     
                        /* Emit photon according to PDF (if any), allocate
                         * associated primary ray, and trace through scene
                         * until absorbed/leaked; emitPhoton() sets the
                         * emitting light source index in photonRay */
                        emitPhoton(&emap, &photonRay);
#if 1
                        if (emap.port)
                           /* !!!  PHOTON PORT REJECTION SAMPLING HACK: set
                            * !!!  photon port as fake hit object for
                            * !!!  primary ray to check for intersection in
                            * !!!  tracePhoton() */                        
                           photonRay.ro = emap.port -> so;
#endif
                        newPhotonPrimary(pm, &photonRay, primaryHeap[proc]);
                        /* Set subprocess index in photonRay for post-
                         * distrib primary index linearisation; this is
                         * propagated with the primary index in photonRay
                         * and set for photon hits by newPhoton() */
                        PMAP_SETRAYPROC(&photonRay, proc);
                        tracePhoton(&photonRay);
                     }
                     
                     /* Update shared global photon count */                     
                     photonCnt [PHOTONCNT_NUMPHOT] += pm -> numPhotons - 
                                                      lastNumPhotons;
                     lastNumPhotons = pm -> numPhotons;
#if !NIX
                     /* Synchronous progress report on Windoze */
                     if (!proc && photonRepTime > 0 && 
                           time(NULL) >= repLastTime + photonRepTime) {
                        unsigned s;                        
                        repComplete = pm -> distribTarget * numProc;
                        repProgress = photonCnt [PHOTONCNT_NUMPHOT];
                        
                        for (repEmitted = 0, s = 0; s < nsources; s++)
                           repEmitted += photonCnt [PHOTONCNT_NUMEMIT(s)];

                        pmapDistribReport();
                     }
#endif
                  }

                  portCnt++;
               } while (portCnt < numPhotonPorts);                  

               if (pm -> numPhotons == srcNumDistrib) {
                  /* Double predistrib factor in case no photons were stored
                   * for this source and redo pass 1 */
                  srcPreDistrib *= 2;
               }
               else {
                  /* Now do pass 2 */
                  passCnt++;
               }
            }
         }
                        
         /* Flush heap buffa one final time to prevent data corruption */
         flushPhotonHeap(pm);         
         /* Flush final photon primary to primary heap file */
         newPhotonPrimary(pm, NULL, primaryHeap [proc]);
         /* Heap files closed automatically on exit
            fclose(pm -> heap);
            fclose(primaryHeap [proc]); */
                  
#ifdef DEBUG_PMAP
         sprintf(errmsg, "Proc %d total %ld photons\n", proc, 
                 pm -> numPhotons);
         eputs(errmsg);
         fflush(stderr);
#endif

#ifdef PMAP_SIGUSR
         signal(SIGUSR1, SIG_DFL);
#endif

#if NIX
         /* Terminate subprocess */
         exit(0);
#endif
      }
      else if (pid < 0)
Esempio n. 9
0
bool Buffer3DS(model_3ds* model){
  printf("Buffering 3ds-file: %s\n",model->name);
	glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
	glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
	glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
  glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
	// Generate And Bind The Vertex Buffer
  GLuint  buffernum=0;
  GLfloat verticesunpacked[9*model->num_polygons];
  unsigned char colorunpacked[12*model->num_polygons];
 // GLfloat       normalsunpacked[3*model->num_polygons];
 // GLfloat       mapcoordsunpacked[6*model->num_polygons];
  printf("Generating vertexbuffer\n");
	glGenBuffersARB( 1, &buffernum );					// Get A Valid Name
  model->VBOvertex = buffernum;
  int cnt=0;
  for(int x=0;x<model->num_polygons;x++){
    for(int triside=0;triside<3;triside++){
      for(int sideloc=0;sideloc<3;sideloc++){
        int vertexnum = model->polygon[x].v[triside];
        if(vertexnum >= model->num_vertices){printf("Model %s contains incomplete polygon at %d\n",model->name,x);vertexnum=0;}
        verticesunpacked[cnt] = model->vertex[vertexnum].l[sideloc];
        cnt++;
      }
    }
  }
  glBindBufferARB( GL_ARRAY_BUFFER_ARB, model->VBOvertex );			// Bind The Buffer
	glBufferDataARB( GL_ARRAY_BUFFER_ARB, model->num_polygons*9*sizeof(GLfloat), verticesunpacked, GL_DYNAMIC_DRAW_ARB );
  free((void*)verticesunpacked);
  
  printf("Generating colorbuffer\n");
  glGenBuffersARB(1, &buffernum); 
  model->VBOcolor = buffernum;
  cnt=0;
  for(int x=0;x<model->num_polygons;x++){
    int matnum = findmaterial(*model,model->polygon[x].materialname);   //Find material for this edge
    for(int triside=0;triside<3;triside++){
      for(int color=0;color<4;color++){
        colorunpacked[cnt] = (unsigned char)model->materials[matnum].ambient[color];   //Set color
        cnt++;
      }
    }
  }
  printf("Done colors %d\n",model->VBOcolor);
  glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->VBOcolor);
  glBufferDataARB(GL_ARRAY_BUFFER_ARB, model->num_polygons*12*sizeof(unsigned char), colorunpacked, GL_DYNAMIC_DRAW_ARB);
  
/*
	glGenBuffersARB( 1, &buffernum );					                            //Generate And Bind The Texture Coordinate Buffer Get A Valid Name
  model->VBOmapcoord = buffernum;
  cnt=0;  
  for(int x=0;x<model->num_polygons;x++){
    for(int triside=0;triside<3;triside++){
      mapcoordsunpacked[cnt] =   model->mapcoord[model->polygon[x].v[triside]].u;
      mapcoordsunpacked[cnt+1] = model->mapcoord[model->polygon[x].v[triside]].v;
      cnt=cnt+2;
    }
  }
	glBindBufferARB( GL_ARRAY_BUFFER_ARB, model->VBOmapcoord );		         // Bind The Buffer
	// Load The Data
	glBufferDataARB( GL_ARRAY_BUFFER_ARB, model->num_vertices*6*sizeof(float), mapcoordsunpacked, GL_STATIC_DRAW_ARB );
  */
  model->buffered=true;
  
  return model->buffered;
}