/* 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); } }
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)); }
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; }
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); }
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"); }
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); }
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)
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; }