// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 static void MTcolor_a_hairRS( BASEHAIR * h, GLOBS * gs ); void MAYAmake_a_curveRS( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret ); int MTmake_spline_hairRS( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo, GLOBS * gs ); void MTdraw_lotsWFRS( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * gs ); void MTdraw_lotsWFROOTRS( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * gs ); void MAYAmake_a_curveROOTRS( int current_samp, int slg, int hairnum, WFTYPE * ret, CURVEINFO * cret ); int make_spline_hairROOTRS( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); static void MTcolor_a_hairROOTRS( BASEHAIR * h, GLOBS * gs ); extern void MTMAYAmake_a_curveRS( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret, GLOBS * gs ); static int draw_a_curve2RS( WFTYPE * wf, CURVEINFO * h, int cs, int curtile, GLOBS *gs ); static void shade_a_curveRS( CURVEINFO * hp, WFTYPE * wf , GLOBS *gs); static void precalc_shadow_curveRS( WFTYPE * h, WFTYPE * bh, CURVEINFO * hp,GLOBS *gs ); static float calculate_light_coneRS( VERT in, int lgt, float hambient, VERT * rawcone,GLOBS *gs ); static void mk_polymatRS( Matrix m, int n,GLOBS *gs ); static void mk_polymatRS2( Matrix m, int n,VERT h,GLOBS *gs ); static void Smk_polymatRS( Matrix m, int n, GLOBS *gs ); static void mkmatrix( Matrix m, VERT xx, VERT yy, VERT zz, VERT b ); static int camspace_clipitLINERS( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */,GLOBS *gs ); int cache_polylineRS(POLYDAT tri, int xx,GLOBS *gs); static int draw_polylineRS( POLYDAT pp, int layer, unsigned char lum,GLOBS *gs ); static int draw_polyline2RS( POLYDAT pp, int layer, unsigned char lum, GLOBS *gs ); int draw_polyline2newRS(POLYDAT pp,int layer,unsigned char lum,GLOBS *gs); int draw_polyline2newZRS(POLYDAT pp,int layer,unsigned char lum,GLOBS *gs); void MTcolor_clumpy( BASEHAIR *,BASEHAIR *, GLOBS * ); void randomize_clump_handles(BASEHAIR *h,GLOBS *gs); int radius_killRS(float,VERT ,GLOBS *); void MTdraw_lotsWFRSROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp,GLOBS * gs ); void find_closest_clump(ROOTPT *pt); #include "kdtree.h" void MTdraw_lotsWFRSROOT( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp, GLOBS * gs ); int MTcheckfaceRS( int i, GLOBS * gs ); static void Gilluminate_strandRS( WFTYPE * pos, int ll, float hambient,GLOBS *gs ); void generate_clump_centerRS(BASEHAIR *ret,CURVEINFO *cinfo2,VERT p,int slg,GLOBS *gs) { CURVEINFO cinfo; int clid=-1; ROOTPT *id; float closest=500000.0f; float bound,rad; struct kdres *presults; int trys=0; double pp[3],pos[3]; float dx,dy,dz; int x; int old_cursamp; int oldGpass; VERT offs; presults=NULL; //presults->size=0; offs.x=0.0f; offs.y=0.0f; offs.z=0.0f; //SHAVEmutex_lock(&Gtile_render_mutex); pp[0]=p.x;pp[1]=p.y;pp[2]=p.z; //presults=kd_nearest(gs->rs.Gkd,pp); if (gs->rs.Gkd) { presults=kd_nearest(gs->rs.Gkd,pp); //bound=restBOUNDLENGTH/2.0f; //rad=bound/80.0f; // starting radius //if (!kd_res_end( presults )) { float dist; id= (ROOTPT *) kd_res_item(presults,pos); dx=pp[0]-pos[0]; dy=pp[1]-pos[1]; dz=pp[2]-pos[2]; dist=( dx*dx + dy*dy + dz*dz ); // if (distid; // fprintf (stdout,"clid = %d dist = %f\n",clid,dist);fflush(stdout); } // kd_res_next ( presults ); } // ok we have the closest point //clid=0; { BASEHAIR genhair; int old_cursamp; int oldGpass; VERT offs; offs.x=0; offs.y=0; offs.z=0; //old_cursamp=gs->cursamp; //gs->cursamp=0; //oldGpass=Gpass; //Gpass=0; //SHAVEmutex_lock(&Gtile_render_mutex); //SHAVEmutex_unlock(&Gtile_render_mutex); gs->density_correct=0; MTdraw_lotsWFRSROOTREST( slg, clid, offs, 0, &genhair, &cinfo, 0,gs ); gs->density_correct=1; //gs->cursamp=old_cursamp; //Gpass=oldGpass; genhair.randomize=ret->randomize; //MAYAmake_a_curveROOT( gs->cursamp , gs->Gslg, clid, &wff, &cinfo ); not thread safe ret->index=clid; //MTgen_resthair_ROOTRS(clid,slg,&cinfo,gs); // we already have the position, but we need the barys //fprintf (stdout,"clid = %d slg=%d pnt id %d %d %d wgt %f %f %f\n",clid,slg,cinfo.pntid[0],cinfo.pntid[1],cinfo.pntid[2],cinfo.wgt[0],cinfo.wgt[1],cinfo.wgt[2]); //fflush(stdout); //if (cinfo.killme==0) { if (slg==0) for (x=0;x<15;x++) { int a,b,c; float ma,mb,mc; ma=cinfo.wgt[0]; mb=cinfo.wgt[1]; mc=cinfo.wgt[2]; // ma=id->bary.x; // mb=id->bary.y; // mc=id->bary.z; a=cinfo.pntid[0]; b=cinfo.pntid[1]; c=cinfo.pntid[2]; // a=id->pntid1; // b=id->pntid2; // c=id->pntid3; a=gs->rs.Dlink[a]; b=gs->rs.Dlink[b]; c=gs->rs.Dlink[c]; ret->resthv[x].x=gs->rs.hair[a].resthv[x].x*ma+gs->rs.hair[b].resthv[x].x*mb+gs->rs.hair[c].resthv[x].x*mc; ret->resthv[x].y=gs->rs.hair[a].resthv[x].y*ma+gs->rs.hair[b].resthv[x].y*mb+gs->rs.hair[c].resthv[x].y*mc; ret->resthv[x].z=gs->rs.hair[a].resthv[x].z*ma+gs->rs.hair[b].resthv[x].z*mb+gs->rs.hair[c].resthv[x].z*mc; ret->hv[x].x=gs->rs.hair[a].hv[x].x*ma+gs->rs.hair[b].hv[x].x*mb+gs->rs.hair[c].hv[x].x*mc; ret->hv[x].y=gs->rs.hair[a].hv[x].y*ma+gs->rs.hair[b].hv[x].y*mb+gs->rs.hair[c].hv[x].y*mc; ret->hv[x].z=gs->rs.hair[a].hv[x].z*ma+gs->rs.hair[b].hv[x].z*mb+gs->rs.hair[c].hv[x].z*mc; ret->handle.x=gs->rs.hair[a].handle.x*ma+gs->rs.hair[b].handle.x*mb+gs->rs.hair[c].handle.x*mc; ret->handle.y=gs->rs.hair[a].handle.y*ma+gs->rs.hair[b].handle.y*mb+gs->rs.hair[c].handle.y*mc; ret->handle.z=gs->rs.hair[a].handle.z*ma+gs->rs.hair[b].handle.z*mb+gs->rs.hair[c].handle.z*mc; ret->norm.x=gs->rs.hair[a].norm.x*ma+gs->rs.hair[b].norm.x*mb+gs->rs.hair[c].norm.x*mc; ret->norm.y=gs->rs.hair[a].norm.y*ma+gs->rs.hair[b].norm.y*mb+gs->rs.hair[c].norm.y*mc; ret->norm.z=gs->rs.hair[a].norm.z*ma+gs->rs.hair[b].norm.z*mb+gs->rs.hair[c].norm.z*mc; ret->color[x]=genhair.color[x]; } else for (x=0;x<15;x++) { int a,b,c; float ma,mb,mc; // ma=id->bary.x; // mb=id->bary.y; // mc=id->bary.z; // a=id->pntid1; // b=id->pntid2; // c=id->pntid3; ma=cinfo.wgt[0]; mb=cinfo.wgt[1]; mc=cinfo.wgt[2]; a=cinfo.pntid[0]; b=cinfo.pntid[1]; c=cinfo.pntid[2]; ret->resthv[x].x=gs->rs.Shair[a].resthv[x].x*ma+gs->rs.Shair[b].resthv[x].x*mb; ret->resthv[x].y=gs->rs.Shair[a].resthv[x].y*ma+gs->rs.Shair[b].resthv[x].y*mb; ret->resthv[x].z=gs->rs.Shair[a].resthv[x].z*ma+gs->rs.Shair[b].resthv[x].z*mb; ret->hv[x].x=gs->rs.Shair[a].hv[x].x*ma+gs->rs.Shair[b].hv[x].x*mb; ret->hv[x].y=gs->rs.Shair[a].hv[x].y*ma+gs->rs.Shair[b].hv[x].y*mb; ret->hv[x].z=gs->rs.Shair[a].hv[x].z*ma+gs->rs.Shair[b].hv[x].z*mb; ret->handle.x=gs->rs.Shair[a].handle.x*ma+gs->rs.Shair[b].handle.x; ret->handle.y=gs->rs.Shair[a].handle.y*ma+gs->rs.Shair[b].handle.y; ret->handle.z=gs->rs.Shair[a].handle.z*ma+gs->rs.Shair[b].handle.z; ret->norm.x=gs->rs.Shair[a].norm.x*ma+gs->rs.Shair[b].norm.x*mb; ret->norm.y=gs->rs.Shair[a].norm.y*ma+gs->rs.Shair[b].norm.y*mb; ret->norm.z=gs->rs.Shair[a].norm.z*ma+gs->rs.Shair[b].norm.z*mb; ret->color[x]=genhair.color[x]; } } } kd_res_free( presults); } //SHAVEmutex_unlock(&Gtile_render_mutex); } void mkmatrix2( Matrix m, VERT xx, VERT yy, VERT zz, VERT b ); float VdistanceK(VERT a, VERT b); void MTdraw_lotsWFROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp,GLOBS * gs ); void find_closest_clump(ROOTPT *pt) { struct kdres *presults; double pp[3],pos[3]; ROOTPT *cl; presults=NULL; if (Gclumps>0) { pp[0]=pt->resthv.x;pp[1]=pt->resthv.y;pp[2]=pt->resthv.z; presults=kd_nearest(Gkd,pp); cl= (ROOTPT *) kd_res_item(presults,pos); pt->distance=VdistanceK(cl->resthv,pt->resthv); pt->closest_clump=cl->id; kd_res_free( presults); } } void generate_clump_center(BASEHAIR *ret,CURVEINFO *cinfo2,VERT p,int slg,GLOBS *gs) { CURVEINFO cinfo; ROOTPT *id; int clid=-1; float closest=500000.0f; float bound,rad; struct kdres *presults; int trys=0; double pp[3],pos[3]; float dx,dy,dz; int x; presults=NULL; //presults->size=0; pp[0]=p.x;pp[1]=p.y;pp[2]=p.z; if (Gclumps>0) { presults=kd_nearest(Gkd,pp); //bound=restBOUNDLENGTH/2.0f; //rad=bound/80.0f; // starting radius //if (!kd_res_end( presults )) { float dist; id= (ROOTPT *) kd_res_item(presults,pos); dx=pp[0]-pos[0]; dy=pp[1]-pos[1]; dz=pp[2]-pos[2]; dist=( dx*dx + dy*dy + dz*dz ); // if (distid; // fprintf (stdout,"clid = %d dist = %f\n",clid,dist);fflush(stdout); } // kd_res_next ( presults ); } // ok we have the closest point ret->index=clid; //clid=0; { BASEHAIR genhair; WFTYPE wff; VERT offs; int old_cursamp; int oldGpass; offs.x=0; offs.y=0; offs.z=0; //init_geomWF(&wff); //old_cursamp=gs->cursamp; //oldGpass=Gpass; //gs->cursamp=0; //Gpass=0; //gs->Gslg=Gslg; //gs->cursamp=old_cursamp; //Gpass=oldGpass; //gs->density_correct=0; MTdraw_lotsWFROOTREST( slg, clid, offs, 0, &genhair, &cinfo, 0,gs ); //gs->density_correct=1; ret->index=clid; genhair.randomize=ret->randomize; //MTMAYAmake_a_curveROOT( cursamp , Gslg, clid, &wff, &cinfo,gs ); //free_geomWF(&wff); //MTgen_resthair_ROOTRS(clid,slg,&cinfo,gs); // we already have the position, but we need the barys if (slg==0) for (x=0;x<15;x++) { int a,b,c; float ma,mb,mc; // ma=cinfo.wgt[0]; // mb=cinfo.wgt[1]; // mc=cinfo.wgt[2]; // a=cinfo.pntid[0]; // b=cinfo.pntid[1]; // c=cinfo.pntid[2]; ma=id->bary.x; mb=id->bary.y; mc=id->bary.z; a=id->pntid1; b=id->pntid2; c=id->pntid3; if (slg==0) { a=Dlink[a]; b=Dlink[b]; c=Dlink[c]; } // fprintf (stdout,"ma = %f mb = %f mc = %f\n",ma,mb,mc);fflush(stdout); ret->resthv[x].x=hair[a].resthv[x].x*ma+hair[b].resthv[x].x*mb+hair[c].resthv[x].x*mc; ret->resthv[x].y=hair[a].resthv[x].y*ma+hair[b].resthv[x].y*mb+hair[c].resthv[x].y*mc; ret->resthv[x].z=hair[a].resthv[x].z*ma+hair[b].resthv[x].z*mb+hair[c].resthv[x].z*mc; ret->hv[x].x=hair[a].hv[x].x*ma+hair[b].hv[x].x*mb+hair[c].hv[x].x*mc; ret->hv[x].y=hair[a].hv[x].y*ma+hair[b].hv[x].y*mb+hair[c].hv[x].y*mc; ret->hv[x].z=hair[a].hv[x].z*ma+hair[b].hv[x].z*mb+hair[c].hv[x].z*mc; ret->handle.x=hair[a].handle.x*ma+hair[b].handle.x*mb+hair[c].handle.x*mc; ret->handle.y=hair[a].handle.y*ma+hair[b].handle.y*mb+hair[c].handle.y*mc; ret->handle.z=hair[a].handle.z*ma+hair[b].handle.z*mb+hair[c].handle.z*mc; ret->norm.x=hair[a].norm.x*ma+hair[b].norm.x*mb+hair[c].norm.x*mc; ret->norm.y=hair[a].norm.y*ma+hair[b].norm.y*mb+hair[c].norm.y*mc; ret->norm.z=hair[a].norm.z*ma+hair[b].norm.z*mb+hair[c].norm.z*mc; ret->color[x]=genhair.color[x]; } if (slg==4) for (x=0;x<15;x++) { int a,b,c; float ma,mb,mc; // ma=cinfo.wgt[0]; // mb=cinfo.wgt[1]; // mc=cinfo.wgt[2]; // a=cinfo.pntid[0]; // b=cinfo.pntid[1]; // c=cinfo.pntid[2]; ma=id->bary.x; mb=id->bary.y; mc=id->bary.z; a=id->pntid1; b=id->pntid2; c=id->pntid3; ret->resthv[x].x=Shair[a].resthv[x].x*ma+Shair[b].resthv[x].x*mb; ret->resthv[x].y=Shair[a].resthv[x].y*ma+Shair[b].resthv[x].y*mb; ret->resthv[x].z=Shair[a].resthv[x].z*ma+Shair[b].resthv[x].z*mb; ret->hv[x].x=Shair[a].hv[x].x*ma+Shair[b].hv[x].x*mb; ret->hv[x].y=Shair[a].hv[x].y*ma+Shair[b].hv[x].y*mb; ret->hv[x].z=Shair[a].hv[x].z*ma+Shair[b].hv[x].z*mb; ret->handle.x=Shair[a].handle.x*ma+Shair[b].handle.x*mb; ret->handle.y=Shair[a].handle.y*ma+Shair[b].handle.y*mb; ret->handle.z=Shair[a].handle.z*ma+Shair[b].handle.z*mb; ret->norm.x=Shair[a].norm.x*ma+Shair[b].norm.x*mb; ret->norm.y=Shair[a].norm.y*ma+Shair[b].norm.y*mb; ret->norm.z=Shair[a].norm.z*ma+Shair[b].norm.z*mb; ret->color[x]=genhair.color[x]; } } kd_res_free( presults); } } void free_clumping () { //if (Gclumps>0) if (Gindex) { free(Gindex); kd_clear(Gkd); kd_free(Gkd); Gclumps=0; Gindex=NULL; } } void MTdraw_lotsWFROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp,GLOBS * gs ); static void init_clumping ( void ) { // dissable clumping WFTYPE wf; BASEHAIR hrest; CURVEINFO cinfo; int x; float cur; int old_cursamp; cur=Gpass; // MTMAYAmake_a_curve( current_samp, slg, hairnum, segs, wf, cret, >hreads[0] ); // Gkd=NULL; // Gindex=NULL; //SHAVEmutex_lock(&Gtile_render_mutex); if (Gindex) //fprintf (stdout,"Potential leak init_clumps();\n");fflush(stdout); if (Gindex) { free(Gindex); kd_clear(Gkd); kd_free(Gkd); //Gclumps=0; Gindex=NULL; } //fprintf (stdout,"init ID = %d clumping %d\n",SHAVEID,Gclumps);fflush(stdout); // Gclumps=Gclumps; //if (0==1) if (hair || Shair) if (!Gindex) if (Gclumps>0) { //GLOBS local_thread; //Gclumps=gs->rs.Gclumps; Gindex=(ROOTPT *) malloc(Gclumps*sizeof(ROOTPT)); for (x=0;xGclumps=Gclumps; for (x=0;xGcurpass; // MTMAYAmake_a_curve( current_samp, slg, hairnum, segs, wf, cret, >hreads[0] ); // Gkd=NULL; // Gindex=NULL; if (gs->rs.hair) gs->Gslg=0; if (gs->rs.Shair) gs->Gslg=4; if (gs->rs.Gindex) { free(gs->rs.Gindex); kd_clear(gs->rs.Gkd); kd_free(gs->rs.Gkd); //gs->rs.Gclumps=0; gs->rs.Gindex=NULL; } if (gs->rs.Gindex) fprintf (stdout,"init clumpingrs = leak!\n");fflush(stdout); if (gs->rs.Gclumps>0) if (!gs->rs.Gindex) if (gs->rs.hair || gs->rs.Shair) { //gs->rs.Gindex=(int *) malloc(gs->rs.Gclumps*sizeof(int)); gs->rs.Gindex=(ROOTPT *) malloc(gs->rs.Gclumps*sizeof(ROOTPT)); for (x=0;xrs.Gclumps;x++) gs->rs.Gindex[x].id=x; //for (x=0;xrs.Gclumps;x++) gs->rs.Gindex[x]=x; //Gkd=kd_create(3); gs->rs.Gkd=kd_create(3); for (x=0;xrs.Gclumps;x++) { CURVEINFO cret; VERT p1p; { VERT ppp; float aa,bb,cc; int a,b,c; ppp.x=0.0f; ppp.y=0.0f; ppp.z=0.0f; // WFTYPE wff; // init_geomWF(&wff); //MAYAmake_a_curveROOT( cursamp , Gslg, x, &wff, &cret ); //draw_lotsWFROOT(Gslg,x,ppp,0,&hrest,&cret,0); { int old_cursamp,oldGpass; gs->density_correct=0; MTdraw_lotsWFRSROOTREST( gs->Gslg, x, ppp, 0, &hrest, &cret,0,gs ); gs->density_correct=1; //MTdraw_lotsWFRS( gs->Gslg, x, ppp, 0, &hr2, &cret,gs ); //MTdraw_lotsWFROOT( gs->Gslg, x, ppp, 0, &hr2, &cret,gs ); //if (hr2.hv[0].x!=hrest.hv[0].x) //{ //fprintf (stdout,"hr2 %f %f %f hrest %f %f %f\n", // hr2.hv[0].x,hr2.hv[0].y,hr2.hv[0].z, // hrest.hv[0].x,hrest.hv[0].y,hrest.hv[0].z);fflush(stdout); //} } //free_geomWF(&wff); p1p=hrest.noisev[0]; gs->rs.Gindex[x].pntid1=cret.pntid[0]; gs->rs.Gindex[x].pntid2=cret.pntid[1]; gs->rs.Gindex[x].pntid3=cret.pntid[2]; gs->rs.Gindex[x].bary.x=cret.wgt[0]; gs->rs.Gindex[x].bary.y=cret.wgt[1]; gs->rs.Gindex[x].bary.z=cret.wgt[2]; } if (cret.killme==0) kd_insert3(gs->rs.Gkd,(double)p1p.x,(double)p1p.y,(double)p1p.z,&gs->rs.Gindex[x]); } } //SHAVEmutex_unlock(&Gtile_render_mutex);//gs->Gcurpass=cur; } int MTmake_spline_hairRS( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo, GLOBS * gs ) { VERT offs; int index = 0; // float rr; // int x; BASEHAIR lowhair; init_a_hair(&lowhair); //static BASEHAIR hh[1]; ////WFTYPE tmpwf; //// init_geomWF(&tmpwf); ////tmpwf.v=NULL; ////tmpwf.totalverts=segs; // offs.x=0.0f; // offs.y=0.0f; // offs.z=0.0f; offs.x = 0.0f; offs.y = 0.0f; offs.z = 0.0f; // geom->totalverts=0; ////if (clone==0) { // int yy; //lowhair[0]= //#ifndef NOLIB cinfo->nodeID=gs->rs.nodeID; // was SHAVEID cinfo->shaveID=gs->rs.SHAVEID; // was SHAVEID gs->segs=segs; MTdraw_lotsWFRS( slg, hairnum, offs, clone, &lowhair, cinfo, gs ); //#endif //#ifdef NOLIB // draw_lotsWFFAST(slg,hairnum,offs,clone,&lowhair,cinfo); //#endif } // lowhair[0]=draw_lotsWFNEW(0,0,offs,1,junkh); /// resample(lowhair[0],&hh[0]); // hh[0]=cut_single_hair(hh[0]); // hh[0]=cut_single_base_hair(hh[0]); index = 1; free_geomWF( geom ); // if (lowhair.killme==0) if( cinfo->killme == 0 ) //// if (lowhair.restlength>0) { int xx; //geom will get allocated in here? //fprintf (stdout,"d lowhair.index = %d\n",lowhair.index);fflush(stdout); resize_base_hair( &lowhair, geom, cinfo, segs ); //fprintf (stdout,"b geom.index[0] = %d\n",geom->index[0]);fflush(stdout); //geom->totalverts=segs; // printf ("b geom->index = %d\n",geom->index);fflush(stdout); geom->totalfaces = 1; //geom->totalfverts=segs; //alloc_geomWF(geom); for( xx = 0; xx < geom->totalverts; xx++ ) geom->facelist[xx] = xx; geom->face_start[0] = 0; geom->face_end[0] = geom->totalverts; if( lowhair.cutlength == 0 ) cinfo->killme = 1; //mk_spline_geom(&hh[0], geom, segs); } // if( cinfo->killme ) // { // lowhair.dreadcount = 0; // geom->totalverts = 0; // geom->totalfaces = 0; // geom->totalfverts = 0; // } return ( ( int ) lowhair.dreadcount ); } void MTdraw_lotsWFRSROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo,int samp, GLOBS * gs ); static void MTcolor_a_hairRS( BASEHAIR * h, GLOBS * gs ) { int x; VERT rc; float rh1, rs1, rv1; float var; float vara; float varb; float varc; VERT tint; VERT tint1; int slg; VERT map, dmapp, llnmap; dmapp.x = 1; dmapp.y = 1; dmapp.z = 1; llnmap.x = 1; llnmap.y = 1; llnmap.z = 1; map.x = 1; map.y = 1; map.z = 1; slg = 0; h->killme = 0; if( h->mtl == gs->rs.head ) slg = 0; if( h->mtl == gs->rs.beard ) slg = 1; if( h->mtl == gs->rs.eyebrow ) slg = 2; if( h->mtl == gs->rs.eyelash ) slg = 3; if( h->mtl == gs->rs.splines ) slg = 4; h->slgroup = gs->Gslg; // drand59 dmapp.x *= h->slider[28]; // density dmapp.y *= h->slider[28]; dmapp.z *= h->slider[28]; llnmap.x *= h->slider[29]; llnmap.y *= h->slider[29]; llnmap.z *= h->slider[29]; // if( dmapp.x < drand98( ) ) // h->killme = 1; h->thickness = h->slider[20] * gs->rs.sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * gs->rs.sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = gs->Gslg; h->diffuse = gs->rs.sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = gs->rs.sliders[4][slg].value * h->slider[4]; h->kspec = gs->rs.sliders[5][slg].value * h->slider[5]; h->ambient = gs->rs.sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = gs->rs.sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = gs->rs.sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqX = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqY = gs->rs.sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = gs->rs.sliders[31][slg].value * h->slider[31]; h->frizzanim = gs->rs.sliders[32][slg].value * h->slider[32]; h->animspeed = gs->rs.sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = gs->rs.sliders[27][slg].value * h->slider[27]; h->dreadroot = gs->rs.sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (gs->rs.sliders[25][slg].value * h->slider[25]); h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->kink = gs->rs.sliders[2][slg].value * h->slider[2]; h->kinkroot = gs->rs.sliders[38][slg].value * h->slider[38]; h->kinkfreqX = gs->rs.sliders[3][slg].value * h->slider[3]; h->kinkfreq = gs->rs.sliders[3][slg].value * h->slider[3]; h->kinkfreqY = gs->rs.sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = gs->rs.sliders[35][slg].value * h->slider[35]; h->randscale = gs->rs.sliders[36][slg].value * h->slider[36]; h->multasp = ( float ) (gs->rs.sliders[44][slg].value * h->slider[44]); h->offset = ( float ) (gs->rs.sliders[45][slg].value * h->slider[45]); h->aspect = ( float ) (gs->rs.sliders[46][slg].value * h->slider[46]); // what's this one? h->mess = ( float ) (gs->rs.sliders[47][slg].value * h->slider[47]); h->flyaway = ( float ) (gs->rs.sliders[48][slg].value * h->slider[48]); h->clump_strength = ( float ) (gs->rs.sliders[49][slg].value * h->slider[49]); h->clump_color_strength = ( float ) (gs->rs.sliders[51][slg].value * h->slider[51]); h->clump_rot_strength= (float ) (gs->rs.sliders[50][slg].value * h->slider[50]); h->clump_rot_offset= (float ) (gs->rs.sliders[52][slg].value * h->slider[52]); h->randomize= (float ) (gs->rs.sliders[53][slg].value * h->slider[53]); h->clump_flatness = ( float ) (gs->rs.sliders[54][slg].value * h->slider[54]); h->scruffle= (float ) (gs->rs.sliders[55][slg].value * h->slider[55]); //fprintf (stdout,"mtcolorahairrs gs->rs[44] = %f h->slider[44]=%f\n",gs->rs.sliders[44][slg].value,h->slider[44]);fflush(stdout); //fprintf (stdout,"diagnostic4 gs->rs.sliders[46][0].value = %f h->slider[46] = %f\n",gs->rs.sliders[46][0].value,h->slider[45]);fflush(stdout); var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ tint.x = ( gs->rs.sliders[9][slg].value ) / 255.0f; tint.y = ( gs->rs.sliders[10][slg].value ) / 255.0f; tint.z = ( gs->rs.sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( gs->rs.sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( gs->rs.sliders[18][slg].value ) / 255.0f; tint1.z = ( gs->rs.sliders[19][slg].value ) / 255.0f; tint1.x *= h->slider[17]; // mult by the wieghts tint1.y *= h->slider[18]; tint1.z *= h->slider[19]; // wild hairs if( MTdrand98( gs ) < ( gs->rs.sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = gs->rs.sliders[13][slg].value / 255.0f; tnt.y = gs->rs.sliders[14][slg].value / 255.0f; tnt.z = gs->rs.sliders[15][slg].value / 255.0f; tnt.x *= h->slider[13]; tnt.y *= h->slider[14]; tnt.z *= h->slider[15]; // wild hare tint1 = tnt; tint = tnt; } rv1 = MTdrand98( gs ); // rh1 = MTdrand98( gs ); // rs1 = MTdrand98( gs ); // rv1 -= .5; rv1 = smoothstep(rv1); rv1 = smoothstep(rv1); rc.x = MTdrand98( gs ); rc.y = MTdrand98( gs ); rc.z = MTdrand98( gs ); { float h1, s1, l1; float rv; float rr, gg, bb; float hue1; hue1 = gs->rs.sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .15; rr = rc.x; gg = rc.y; bb = rc.z; // this is a rand hue with same val/sat // blend it into the original color tint1.x = ( tint1.x ) * ( 1.0 - ( hue1 ) ) + ( rr * ( hue1 ) ); tint1.y = ( tint1.y ) * ( 1.0 - ( hue1 ) ) + ( gg * ( hue1 ) ); tint1.z = ( tint1.z ) * ( 1.0 - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = ( gs->rs.sliders[39][slg].value / 100.0f ) * h->slider[39]; tint1.x = tint1.x*(1.0-rv) + tint1.x * rv1 * rv; tint1.y = tint1.y*(1.0-rv) + tint1.y * rv1 * rv; tint1.z = tint1.z*(1.0-rv) + tint1.z * rv1 * rv; } { float h1, s1, l1; float rr, gg, bb; float rv; float hue1, hue2; rr = rc.x; gg = rc.y; bb = rc.z; hue1 = gs->rs.sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .3; // this is a rand hue with same val/sat // blend it into the original color tint.x = ( tint.x ) * ( 1.0 - ( hue1 ) ) + ( rr * ( hue1 ) ); tint.y = ( tint.y ) * ( 1.0 - ( hue1 ) ) + ( gg * ( hue1 ) ); tint.z = ( tint.z ) * ( 1.0 - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = ( gs->rs.sliders[39][slg].value / 100.0f ) * h->slider[39]; //rv*=.5f; tint.x = tint.x*(1.0-rv) + tint.x * rv1 * rv; tint.y = tint.y*(1.0-rv) + tint.y * rv1 * rv; tint.z = tint.z*(1.0-rv) + tint.z * rv1 * rv; } // these are wild hairs if( tint.x > 1 ) tint.x = 1; if( tint.y > 1 ) tint.y = 1; if( tint.z > 1 ) tint.z = 1; if( tint.x < 0 ) tint.x = 0; if( tint.y < 0 ) tint.y = 0; if( tint.z < 0 ) tint.z = 0; if( tint1.x > 1 ) tint1.x = 1; if( tint1.y > 1 ) tint1.y = 1; if( tint1.z > 1 ) tint1.z = 1; if( tint1.x < 0 ) tint1.x = 0; if( tint1.y < 0 ) tint1.y = 0; if( tint1.z < 0 ) tint1.z = 0; if (!gs->rs.Gsquirrel) for( x = 0; x < 15; x++ ) { float u, u1; u = ( float ) x / 14.0f; u1 = 1.0 - u; u = 1.0 - u1; h->color[x].x = tint.x * u + tint1.x * u1; h->color[x].y = tint.y * u + tint1.y * u1; h->color[x].z = tint.z * u + tint1.z * u1; } else // squirrel for( x = 0; x < 15; x++ ) { float u, u1; if (x>8) { h->color[x].x = tint.x; h->color[x].y = tint.y; h->color[x].z = tint.z; } else { h->color[x].x = tint1.x; h->color[x].y = tint1.y; h->color[x].z = tint1.z; } } h->killme = 0; // if (h->slider[25]==0.0f) h->killme = 1; if ((gs->rs.sliders[25][slg].value > 0.0f)&&(h->slider[25]==0.0f)) h->killme=1; MTJsrand( ( unsigned long ) ( h->hairnumber * 11 ), gs ); { int xx; for( xx = 0; xx < 5; xx++ ) MTdrand98( gs ); } if( dmapp.x * dmapp.x < MTdrand98( gs ) ) h->killme = 1; } static int MTdraw_oneHAIRRS( int slg, int xid, int cs, int curtile, GLOBS * gs ) //int cs; { int nokink = 1; int x; int hc2 = 0; float ascalh, ascalr; int pid = 0; int progress = 0; int finish = 0; int smps, killit = 0; CURVEINFO cinfo; BASEHAIR tmpc; VERT vnorm; int clipx1, clipy1, clipx0, clipy0; cinfo.killme = 0; { int th; int prg = 0; if( gs->rs.total_slgfaces[slg] > 0 ) { int q; int cnnt; WFTYPE wf; CURVEINFO cinfo; int dok = 1; init_geomWF( &wf ); gs->Gcurpass = cs; gs->passnumber = cs; gs->Gcurpass=cs; gs->Gslg= slg; gs->GhairID=xid; x = xid; if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) if( gs->rs.LOCAL_PASSES[slg] > 0 ) { float d1, d2; BASEHAIR hrest; BASEHAIR h; hrest.killme = 0; progress++; gs->GhairID = ( x ); gs->Gslg = slg; cinfo.hairID = x; cinfo.groupID = slg; // cinfo.nodeID = gs->rs.SHAVEID; cinfo.nodeID = gs->rs.nodeID; // was SHAVEID cinfo.shaveID = gs->rs.SHAVEID; if( 0 == 1 ) if( progress > 1000 ) if( gs->rs.TILEMODE == 0 ) { progress = 0; global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); } // if (gs->rs.TILEMODE==2) // { // progress=0; // global_progress++; // finish=SHAVEprogress(global_progress,estimated_total); // } ///LOCAL_SEGS[slg]=15; if( finish != 1 ) { // printf ("MTMAYAmake_a_curveRS\n");fflush(stdout); MTMAYAmake_a_curveRS( cs, slg, x, gs->rs.LOCAL_SEGS[slg], &wf, &cinfo, gs ); for( q = 0; q < wf.totalverts; q++ ) { wf.v[q].z = -wf.v[q].z; wf.velocity[q].z = -wf.velocity[q].z; wf.vn[q].z = -wf.vn[q].z; } } if( finish != 1 ) if( cinfo.killme != 1 ) if( wf.totalverts > 0 ) for( q = 0; q < wf.totalfaces; q++ ) if( wf.face_end[q] - wf.face_start[q] > 0 ) { int qqq; WFTYPE onehair; init_geomWF( &onehair ); onehair.totalverts = wf.face_end[q] - wf.face_start[q]; onehair.totalfaces = 1; onehair.totalfverts = wf.face_end[q] - wf.face_start[q]; alloc_geomWF( &onehair ); onehair.face_end[0] = 1; onehair.face_start[0] = 0; onehair.totalverts = 0; for( qqq = wf.face_start[q]; qqq < wf.face_end[q]; qqq++ ) { int g; g = wf.facelist[qqq]; onehair.v[onehair.totalverts] = wf.v[g]; onehair.facelist[onehair.totalverts] = onehair.totalverts; onehair.uv[onehair.totalverts] = wf.uv[g]; onehair.velocity[onehair.totalverts] = wf.velocity[g]; onehair.color[onehair.totalverts] = wf.color[g]; onehair.totalverts++; } // for (q=0;qtotalverts=0; //ret->totalfaces=0; //ret->totalfverts=0; free_geomWF( ret ); init_geomWF( &geom ); //geom.totalverts=0; // free_geom(ret); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; //if (freeze.totalverts==0) if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) if( gs->rs.LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; // gs->Gcurpass = Gcurpass; clones = MTmake_spline_hair( slg, hairnum, 0, segs, &geom, &cinfo, gs ); // //printf("geom.totalverts=%d\n",geom.totalverts); // //printf(" slg->%d\n",slg); // fflush(stderr); if( cinfo.killme == 0 ) { ret->totalverts = geom.totalverts * ( clones + 1 ); ret->totalfverts = geom.totalfverts * ( clones + 1 ); ret->totalfaces = geom.totalfaces * ( clones + 1 ); alloc_geomWF( ret ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; if( clones == 0 ) clones = 1; for( q = 0; q < clones; q++ ) { int off, foff; int jk; if( q != 0 ) jk = MTmake_spline_hair( slg, hairnum, q, segs, &geom, &cinfo, gs ); if( geom.totalverts > 0 ) { for( x = 0; x < geom.totalverts; x++ ) { off = geom.totalverts * q; ret->v[x + off] = geom.v[x]; ret->uv[x + off] = geom.uv[x]; ret->color[x + off] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { foff = geom.totalfverts * q; ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } for( x = 0; x < geom.totalfaces; x++ ) { // off=geom.totalfaces*q; ret->index[ret->totalfaces]=geom.index[x]; ret->face_start[ret->totalfaces] = geom.face_start[x] + foff; ret->face_end[ret->totalfaces] = geom.face_end[x] + foff; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } } static float dither2RS( float in,GLOBS *gs ) { //#ifdef crap float flip; float rem; float base; float out; flip = ( float ) MTdrand98(gs ); base = ( float ) floor( in ); rem = in - base; if( flip > rem ) out = in; else out = in + 1.0f; if( out > 255.0 ) out = 255.0f; return ( out ); //#endif //return(in); } void composite_pixelFASTRS(LIGHTINFO *cam,int add, int addi, GLOBS *gs) { int x; float r=0.0f; float g=0.0f; float b=0.0f; float a=0.0f; float z= 1000000.0f; int tm; float alpha,ia; int addi1,add1; unsigned char *ib; float *zb; int baseadd,baseadd4; int iend,zend,add4; baseadd=0; baseadd4=0; zend=cam->zPage*(Gtransp_depth-1); iend=cam->iPage*(Gtransp_depth-1); for (tm=0;tmibuff[addi1]; zb= &cam->zbuff[add1]; for (x=Gtransp_depth-1;x>=0;x--) { alpha=(float)(*(ib+3)); if (alpha>0.0f) { alpha/=255.0; ia=1.0-alpha; r=((float)(*(ib)))*alpha+r*ia; g=((float)(*(ib+1)))*alpha+g*ia; b=((float)(*(ib+2)))*alpha+b*ia; if (r>255.0f) r=255.0f; if (g>255.0f) g=255.0f; if (b>255.0f) b=255.0f; a=((float)(*(ib+3)))+a*ia; if (a>255.0f) a=255.0f; if ((*zb)iPage; zb-=cam->zPage; } ib= &cam->ibuff[addi+baseadd4]; (*(ib))=(unsigned char)dither2RS( r,gs); (*(ib+1))=(unsigned char) dither2RS(g,gs); (*(ib+2))=(unsigned char) dither2RS(b,gs); (*(ib+3))=(unsigned char) dither2RS(a,gs); cam->zbuff[add+baseadd]=z; baseadd+=cam->timePage; baseadd4=baseadd*4; } r=0;g=0;b=0;a=0;z=1000000.0f; add1=add;//+x*cam->timePage; add4=add1*4; ib= &cam->ibuff[add4]; zb= &cam->zbuff[add1]; if (Gmotion_samp>1) { for (x=0;xtimePage; //add4=add1*4; r+=(float)(*(ib)); g+=(float)(*(ib+1)); b+=(float)(*(ib+2)); a+=(float)(*(ib+3)); if ((*zb)timePage; ib+=cam->timePage; ib+=cam->timePage; ib+=cam->timePage; ib+=cam->timePage; } ib= &cam->ibuff[addi]; (*(ib))=(unsigned char) dither2RS(r/(float)Gmotion_samp,gs); (*(ib+1))=(unsigned char) dither2RS(g/(float)Gmotion_samp,gs); (*(ib+2))=(unsigned char) dither2RS(b/(float)Gmotion_samp,gs); (*(ib+3))=(unsigned char) dither2RS(a/(float)Gmotion_samp,gs); cam->zbuff[add]=z; } } extern void MTMAYAmake_a_curveRS( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret, GLOBS * gs ) { VERT offs; WFTYPE geom; int th = 0; int x; //float rr; int hc = 0; int hc2 = 0; //char tmp[255]; int tv = 0; //int didit; offs.x = 0; offs.y = 0; offs.z = 0; cret->killme = 1; if( ret->totalverts > 0 ) free_geomWF( ret ); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; geom.totalverts = 0; init_geomWF( ret ); init_geomWF( &geom ); // free_geom(ret); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; gs->Gcurpass=current_samp; if( gs->rs.LOCAL_PASSES[slg] > 0 ) gs->Gcurpass = gs->Gcurpass % gs->rs.LOCAL_PASSES[slg]; gs->GhairID = hairnum; cret->depthpass = gs->Gcurpass; cret->hairID = hairnum; // current_samp=gs->cursamp; //if (freeze.totalverts==0) if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) if( gs->rs.LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; clones = MTmake_spline_hairRS( slg, hairnum, 0, segs, &geom, cret, gs ); // //printf("geom.totalverts=%d\n",geom.totalverts); // //printf(" slg->%d\n",slg); // fflush(stderr); // cret->killme=1; if( cret->killme == 0 ) { if( clones == 0 ) clones = 1; ret->totalverts = geom.totalverts * ( clones + 1 ); ret->totalfverts = geom.totalfverts * ( clones + 1 ); ret->totalfaces = geom.totalfaces * ( clones + 1 ); if( ret->totalverts > 0 ) alloc_geomWF( ret ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; // if (clones>0) for( q = 0; q < clones; q++ ) { int off, foff; int jk; if( q != 0 ) jk = MTmake_spline_hairRS( slg, hairnum, q, segs, &geom, cret, gs ); if( geom.totalverts > 0 ) { off = geom.totalverts * q; for( x = 0; x < geom.totalverts; x++ ) { ret->v[ret->totalverts] = geom.v[x]; ret->v[ret->totalverts].z *= -1.0f; // ret->uv[ret->totalverts]=geom.uv[x]; ret->uv[ret->totalverts].x = cret->u; ret->uv[ret->totalverts].y = cret->v; ret->uv[ret->totalverts].z = geom.uv[x].z; ret->velocity[ret->totalverts] = geom.velocity[x]; ret->velocity[ret->totalverts].z *= -1.0f; ret->color[ret->totalverts] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } foff = geom.totalfverts * q; for( x = 0; x < geom.totalfaces; x++ ) { // off=geom.totalfaces*q; // fprintf (stdout,"c ret->index[%d] = %d\n",ret->totalfaces,geom.index[x]);fflush(stdout); ret->index[ret->totalfaces]=geom.index[x]; ret->r1[ret->totalfaces] = cret->baserad; ret->r2[ret->totalfaces] = cret->tiprad; ret->face_start[ret->totalfaces] = geom.face_start[x] + off; ret->face_end[ret->totalfaces] = geom.face_end[x] + off; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } if( 0 == 1 ) if( freeze.totalverts != 0 ) { // freeze is on make_inst( slg, hairnum ); //// if (matrixhair.dreadcount==0) { xforminst( 0 ); ret->totalverts = freeze.totalverts; ret->totalfverts = freeze.totalfverts; ret->totalfaces = freeze.totalfaces; alloc_geomWF( ret ); for( x = 0; x < freeze.totalverts; x++ ) { ret->v[x] = freezetmp.v[x]; ret->v[x].z = -ret->v[x].z; } for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].x = freezetmp.Rrvcolor[x]; for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].y = freezetmp.Rgvcolor[x]; for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].z = freezetmp.Rbvcolor[x]; for( x = 0; x < freeze.totalfverts; x++ ) ret->facelist[x] = freeze.facelist[x]; for( x = 0; x < freeze.totalfaces; x++ ) ret->face_start[x] = freeze.face_start[x]; for( x = 0; x < freeze.totalfaces; x++ ) ret->face_end[x] = freeze.face_end[x]; } // dreadcount==0 } //memcpy(cret,&Gcurv,sizeof(CURVEINFO)); // this shouldn't be necessary .. for( x = 0; x < ret->totalfaces; x++ ) { float tp; int y; tp = ( float ) ( ret->face_end[x] - ret->face_start[x] ); tp -= 1; if( tp < 1 ) tp = 1; for( y = ret->face_start[x]; y < ret->face_end[x]; y++ ) { ret->uv[ret->facelist[y]].z = ( float ) ( y - ret->face_start[x] ) / tp; } } cret->depthpass = current_samp; cret->hairID = hairnum; } static void MTcolor_a_hairSOFTRS( BASEHAIR * h, GLOBS * gs ) { int x; VERT rc; float rh1, rs1, rv1; float var; float vara; float varb; float varc; VERT tint; VERT tint1; int slg; VERT map, dmapp, llnmap; dmapp.x = 1; dmapp.y = 1; dmapp.z = 1; llnmap.x = 1; llnmap.y = 1; llnmap.z = 1; map.x = 1; map.y = 1; map.z = 1; slg = 0; h->killme = 0; if( h->mtl == gs->rs.head ) slg = 0; if( h->mtl == gs->rs.beard ) slg = 1; if( h->mtl == gs->rs.eyebrow ) slg = 2; if( h->mtl == gs->rs.eyelash ) slg = 3; if( h->mtl == gs->rs.splines ) slg = 4; h->slgroup = (short)gs->Gslg; // drand59 dmapp.x *= h->slider[28]; // density dmapp.y *= h->slider[28]; dmapp.z *= h->slider[28]; llnmap.x *= h->slider[29]; llnmap.y *= h->slider[29]; llnmap.z *= h->slider[29]; h->thickness = h->slider[20] * gs->rs.sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * gs->rs.sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = gs->Gslg; h->diffuse = gs->rs.sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = gs->rs.sliders[4][slg].value * h->slider[4]; h->kspec = gs->rs.sliders[5][slg].value * h->slider[5]; h->ambient = gs->rs.sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = gs->rs.sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = gs->rs.sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqX = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqY = gs->rs.sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = gs->rs.sliders[31][slg].value * h->slider[31]; h->frizzanim = gs->rs.sliders[32][slg].value * h->slider[32]; h->animspeed = gs->rs.sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = gs->rs.sliders[27][slg].value * h->slider[27]; h->dreadroot = gs->rs.sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (gs->rs.sliders[25][slg].value * h->slider[25]); h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->kink = gs->rs.sliders[2][slg].value * h->slider[2]; h->kinkroot = gs->rs.sliders[38][slg].value * h->slider[38]; h->kinkfreqX = gs->rs.sliders[3][slg].value * h->slider[3]; h->kinkfreq = gs->rs.sliders[3][slg].value * h->slider[3]; h->multasp = ( float )(gs->rs.sliders[44][slg].value * h->slider[44]); h->offset = ( float ) (gs->rs.sliders[45][slg].value * h->slider[45]); h->aspect = ( float ) (gs->rs.sliders[46][slg].value * h->slider[46]); h->mess = gs->rs.sliders[47][slg].value * h->slider[47]; h->flyaway = gs->rs.sliders[48][slg].value * h->slider[48]; h->clump_strength = gs->rs.sliders[49][slg].value * h->slider[49]; h->clump_color_strength = gs->rs.sliders[51][slg].value * h->slider[51]; h->clump_rot_strength= (float ) (gs->rs.sliders[50][slg].value * h->slider[50]); h->clump_rot_offset= (float ) (gs->rs.sliders[52][slg].value * h->slider[52]); h->randomize= (float ) (gs->rs.sliders[53][slg].value * h->slider[53]); h->clump_flatness = ( float ) (gs->rs.sliders[54][slg].value * h->slider[54]); h->kinkfreqY = gs->rs.sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = gs->rs.sliders[35][slg].value * h->slider[35]; h->randscale = gs->rs.sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->killme = 0; // if (h->slider[25]==0.0f) h->killme = 1; if ((gs->rs.sliders[25][slg].value > 0.0f)&&(h->slider[25]==0.0f)) h->killme=1; MTJsrand( ( unsigned long ) ( h->hairnumber * 11 ), gs ); { int xx; for( xx = 0; xx < 5; xx++ ) MTdrand98( gs ); } if( dmapp.x * dmapp.x < MTdrand98( gs ) ) h->killme = 1; // if (h->slider[25]==0.0f) h->killme = 1; if ((sliders[25][slg].value > 0.0f)&&(h->dreadcount==0.0f)) h->killme=1; for( x = 0; x < 15; x++ ) { h->color[x].x = 1.0f; h->color[x].y = 1.0f; h->color[x].z = 1.0f; } } static POLYDAT tocamRS( LIGHTINFO * cam, POLYDAT pp,GLOBS *gs ) { int x; POLYDAT oldpp; POLYDAT pp1, pp2; // memcpy(&oldpp,&pp,sizeof(POLYDAT)); for( x = 0; x < 3; x++ ) { pp.w[x] = pp.p[x]; pp.wv[x] = pp.v[x]; } if( cam != &LWcam ) if( gs->rs.TILEMODE != 6 ) { for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = world2camRS( cam, tmpv,gs ); pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } for( x = 0; x < 3; x++ ) { VERT2 tmpv; VERT2 zero; zero.x = 0.0f; zero.y = 0.0f; zero.z = 0.0f; tmpv.x = pp.v[x].x; tmpv.y = pp.v[x].y; tmpv.z = pp.v[x].z; tmpv = world2camRS( cam, tmpv,gs ); zero = world2camRS( cam, zero,gs ); pp.v[x].x = tmpv.x - zero.x; pp.v[x].y = tmpv.y - zero.y; pp.v[x].z = tmpv.z - zero.z; } } if( ( cam == &LWcam ) || ( gs->rs.TILEMODE == 6 ) ) { for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = world2camRS( &LWCamOPEN, tmpv,gs ); pp1.p[x].x = tmpv.x; pp1.p[x].y = tmpv.y; pp1.p[x].z = tmpv.z; } for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x + pp.v[x].x; tmpv.y = pp.p[x].y + pp.v[x].y; tmpv.z = pp.p[x].z + pp.v[x].z; tmpv = world2camRS( &LWCamCLOSE, tmpv,gs ); pp2.p[x].x = tmpv.x; pp2.p[x].y = tmpv.y; pp2.p[x].z = tmpv.z; pp.p[x] = pp1.p[x]; } for( x = 0; x < 3; x++ ) { pp.v[x].x = pp2.p[x].x - pp1.p[x].x; pp.v[x].y = pp2.p[x].y - pp1.p[x].y; pp.v[x].z = pp2.p[x].z - pp1.p[x].z; } } return ( pp ); } static VERT2 cam2worldRS( LIGHTINFO * cam, VERT2 in,GLOBS *gs ) { float s; VERT out; VERT2 ott; float t; ott.clip = 0; if (itsalight!=1) { in.x-=gs->rs.calibrateX; in.y-=gs->rs.calibrateY; } s = cam->xres * 0.5f; t = cam->yres * 0.5f; out.x = ( ( in.x - s ) / t ) * cam->aspect; out.y = -( ( in.y / t ) - 1 ); out.z = in.z; ott.x = out.x; ott.y = out.y; ott.z = out.z; ott = vxmp3( cam->iview, out, cam->zoom ); out.x = ott.x; out.y = ott.y; out.z = ott.z; // ott.clip=ott.clip; // ott.clip=0; // out.clip=0; return ( ott ); } static VERT2 world2camRS( LIGHTINFO * cam, VERT2 in,GLOBS *gs ) { float s, t; VERT2 out; VERT vin; vin.x = in.x; vin.y = in.y; vin.z = in.z; out = vxmp3( cam->view, vin, cam->zoom ); s = ( float ) cam->xres / 2.0f; t = ( float ) cam->yres / 2.0f; // out.x = out.x *cam->aspect * s / 2.0f + s ; out.x = ( out.x / cam->aspect ) * t + s; out.y = t - out.y * t; // in.x = (out.x /cam->aspect) * t + s ; // in.x-s = (out.x/cam->aspect) * t // (in.x-s)/t = out.x // out.x=((in.x-s)/t)*cam->aspect // GLOBAL_CLIPIT = 0; // if( out.clip ) // GLOBAL_CLIPIT = 1; if( gs->rs.itsalight == 0 ) { //out.clip=0; //GLOBAL_CLIPIT=0; if( ( out.x < gs->rs.Gclipx0 ) || ( out.x >= gs->rs.Gclipx1 ) || ( out.y < gs->rs.Gclipy0 ) || ( out.y >= gs->rs.Gclipy1 ) ) // if( ( out.x < 0 ) || ( out.x >= cam->xres ) // || ( out.y < 0 ) || ( out.y >= cam->yres ) ) { out.clip = 1; // GLOBAL_CLIPIT = 1; } // else // GLOBAL_CLIPIT = 0; } if (itsalight != 1) { out.x += gs->rs.calibrateX; out.y += gs->rs.calibrateY; } return out; } static void MTcolor_a_hairROOTRS( BASEHAIR * h, GLOBS * gs ) { int x; VERT rc; float rh1, rs1, rv1; float var; float vara; float varb; float varc; VERT tint; VERT tint1; int slg; VERT map, dmapp, llnmap; dmapp.x = 1; dmapp.y = 1; dmapp.z = 1; llnmap.x = 1; llnmap.y = 1; llnmap.z = 1; map.x = 1; map.y = 1; map.z = 1; slg = 0; h->killme = 0; if( h->mtl == gs->rs.head ) slg = 0; if( h->mtl == gs->rs.beard ) slg = 1; if( h->mtl == gs->rs.eyebrow ) slg = 2; if( h->mtl == gs->rs.eyelash ) slg = 3; if( h->mtl == gs->rs.splines ) slg = 4; h->slgroup = gs->Gslg; // drand59 dmapp.x *= h->slider[28]; // density llnmap.x *= h->slider[29]; h->thickness = h->slider[20] * gs->rs.sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * gs->rs.sliders[37][slg].value * 3.0f; h->cutlength = llnmap.x; // h->cutlength*=h->slider[29] h->slgroup = gs->Gslg; h->diffuse = gs->rs.sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = gs->rs.sliders[4][slg].value * h->slider[4]; h->kspec = gs->rs.sliders[5][slg].value * h->slider[5]; h->ambient = gs->rs.sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = gs->rs.sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = gs->rs.sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqX = gs->rs.sliders[1][slg].value * h->slider[1]; h->frizzfreqY = gs->rs.sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = gs->rs.sliders[31][slg].value * h->slider[31]; h->frizzanim = gs->rs.sliders[32][slg].value * h->slider[32]; h->animspeed = gs->rs.sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = gs->rs.sliders[27][slg].value * h->slider[27]; h->dreadroot = gs->rs.sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (gs->rs.sliders[25][slg].value * h->slider[25]); h->clumpfreq = gs->rs.sliders[1][slg].value * h->slider[1]; h->kink = gs->rs.sliders[2][slg].value * h->slider[2]; h->kinkroot = gs->rs.sliders[38][slg].value * h->slider[38]; h->kinkfreqX = gs->rs.sliders[3][slg].value * h->slider[3]; h->kinkfreq = gs->rs.sliders[3][slg].value * h->slider[3]; h->kinkfreqY = gs->rs.sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = gs->rs.sliders[35][slg].value * h->slider[35]; h->randscale = gs->rs.sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->multasp = ( float ) (gs->rs.sliders[44][slg].value * h->slider[44]); h->offset = ( float ) (gs->rs.sliders[45][slg].value * h->slider[45]); h->aspect = ( float ) (gs->rs.sliders[46][slg].value * h->slider[46]); //fprintf (stdout,"colorahairrootrs h.multasp = %f\n",h->multasp);fflush(stdout); h->mess = gs->rs.sliders[47][slg].value * h->slider[47]; h->flyaway = gs->rs.sliders[48][slg].value * h->slider[48]; h->clump_strength = gs->rs.sliders[49][slg].value * h->slider[49]; h->clump_color_strength = gs->rs.sliders[51][slg].value * h->slider[51]; h->clump_rot_strength= (float ) (gs->rs.sliders[50][slg].value * h->slider[50]); h->clump_rot_offset= (float ) (gs->rs.sliders[52][slg].value * h->slider[52]); h->randomize= (float ) (gs->rs.sliders[53][slg].value * h->slider[53]); h->clump_flatness = ( float ) (gs->rs.sliders[54][slg].value * h->slider[54]); tint.x = ( gs->rs.sliders[9][slg].value ) / 255.0f; tint.y = ( gs->rs.sliders[10][slg].value ) / 255.0f; tint.z = ( gs->rs.sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( gs->rs.sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( gs->rs.sliders[18][slg].value ) / 255.0f; tint1.z = ( gs->rs.sliders[19][slg].value ) / 255.0f; tint1.x *= h->slider[17]; // mult by the wieghts tint1.y *= h->slider[18]; tint1.z *= h->slider[19]; // wild hairs if( MTdrand98( gs ) < ( gs->rs.sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = gs->rs.sliders[13][slg].value / 255.0f; tnt.y = gs->rs.sliders[14][slg].value / 255.0f; tnt.z = gs->rs.sliders[15][slg].value / 255.0f; tnt.x *= h->slider[13]; tnt.y *= h->slider[14]; tnt.z *= h->slider[15]; // wild hare tint1 = tnt; tint = tnt; } rv1 = MTdrand98( gs ); // rv1 = smoothstep(rv1); // rv1 = smoothstep(rv1); rv1 = smoothstep(rv1); rv1 = smoothstep(rv1); //rh1=drand98(); //rs1=drand98(); // rv1 -= .5; // rv1 *= 2.0f; rc.x = MTdrand98( gs ); rc.y = MTdrand98( gs ); rc.z = MTdrand98( gs ); { float h1, s1, l1; float rv; float rr, gg, bb; float hue1; hue1 = gs->rs.sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .25; rr = rc.x; gg = rc.y; bb = rc.z; // this is a rand hue with same val/sat // blend it into the original color tint1.x = ( tint1.x ) * ( 1.0 - ( hue1 ) ) + ( rr * ( hue1 ) ); tint1.y = ( tint1.y ) * ( 1.0 - ( hue1 ) ) + ( gg * ( hue1 ) ); tint1.z = ( tint1.z ) * ( 1.0 - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = 1.0 - ( gs->rs.sliders[39][slg].value / 100.0f ) * h->slider[39]; tint1.x = tint1.x * ( 1.0 - rv ) + tint1.x * rv1 * rv; tint1.y = tint1.y * ( 1.0 - rv ) + tint1.y * rv1 * rv; tint1.z = tint1.z * ( 1.0 - rv ) + tint1.z * rv1 * rv; } { float h1, s1, l1; float rr, gg, bb; float rv; float hue1, hue2; rr = rc.x; gg = rc.y; bb = rc.z; hue1 = gs->rs.sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .25; // this is a rand hue with same val/sat // blend it into the original color tint.x = ( tint.x ) * ( 1.0f - ( hue1 ) ) + ( rr * ( hue1 ) ); tint.y = ( tint.y ) * ( 1.0f - ( hue1 ) ) + ( gg * ( hue1 ) ); tint.z = ( tint.z ) * ( 1.0f - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = 1.0 - ( gs->rs.sliders[39][slg].value / 100.0f ) * h->slider[39]; tint.x = tint.x * ( 1.0f - rv ) + tint.x * rv1 * rv; tint.y = tint.y * ( 1.0f - rv ) + tint.y * rv1 * rv; tint.z = tint.z * ( 1.0f - rv ) + tint.z * rv1 * rv; } // these are wild hairs if( tint.x > 1 ) tint.x = 1; if( tint.y > 1 ) tint.y = 1; if( tint.z > 1 ) tint.z = 1; if( tint.x < 0 ) tint.x = 0; if( tint.y < 0 ) tint.y = 0; if( tint.z < 0 ) tint.z = 0; if( tint1.x > 1 ) tint1.x = 1; if( tint1.y > 1 ) tint1.y = 1; if( tint1.z > 1 ) tint1.z = 1; if( tint1.x < 0 ) tint1.x = 0; if( tint1.y < 0 ) tint1.y = 0; if( tint1.z < 0 ) tint1.z = 0; // for( x = 0; x < 1; x++ ) x = 0; { float u, u1; // u = ( float )x / 15.0f; u = 0.0f; u1 = 1.0 - u; u = 1.0 - u1; h->color[x].x = tint.x * u + tint1.x * u1; h->color[x].y = tint.y * u + tint1.y * u1; h->color[x].z = tint.z * u + tint1.z * u1; } h->killme = 0; // MTJsrand( ( unsigned long ) ( h->hairnumber * 11 ), gs ); // { // int xx; // // for( xx = 0; xx < 5; xx++ ) // MTdrand98( gs ); // } // if( dmapp.x * dmapp.x < MTdrand98( gs ) ) // h->killme = 1; } int MTcheckfaceRS( int i, GLOBS * gs ) { int x; int ret = 0; double dr; int tr = 0; int slg = -1; if( ( i >= 0 ) && ( i < gs->rs.totalfaces ) ) if( gs->rs.poly_weight[i] != 0 ) { //if (head>=0) // if (mtlgroup[i]==head) slg=0; //if (beard>=0) // if (mtlgroup[i]==beard) slg=1; //if (eyebrow>=0) // if (mtlgroup[i]==eyebrow) slg=2; //if (eyelash>=0) // if (mtlgroup[i]==eyelash) slg=3; //if (splines>=0) // if (mtlgroup[i]==splines) slg=4; ret = 0; //if (i>=0) // if (slg>=0) { int qq; // for (qq=0;qq<(int)((float)drand98()*15.);qq++) dr=(float)drand98(); // dr=(float)drand98(); // printf ("poly_weight[i] = %f\n",poly_weight[i]); // dr*drrs.poly_weight[i] ) ret = 1; } } //ret=1; //if (gs->density_correct==0) ret=1; return ( ret ); } static int draw_polyRS( POLYDAT pp, int layer, unsigned char lum,GLOBS *gs ) { int x; int ll; int success = 0; POLYDAT pp1; // GLOBAL_CLIPIT = 0; for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = cam2world( gs->rs.current_cam, tmpv ); // if( tmpv.clip ) // GLOBAL_CLIPIT = 1; pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } pp1 = tocamRS( gs->rs.current_cam, pp,gs ); // printf ("pp1 velocity= %f %f %f\n",pp1.v[0].x,pp1.v[0].y,pp1.v[0].z); // if ((itsalight==0)||(itsalight==2)) if( ( gs->rs.itsalight == 0 ) ) if( ( gs->rs.current_cam == &LWcam ) || ( gs->rs.TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; ll = x; gs->cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_poly2RS( pp1, ll, lum,gs ); } if( gs->rs.itsalight == 2 ) if( ( gs->rs.current_cam == &LWcam ) || (gs->rs.TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // current_cam->cursamp=x; // current_cam->lwtime=x; // x = layer; // Was Gcurrent_time ll = x; gs->cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_poly2RS( pp1, ll, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( ( gs->rs.itsalight == 2 ) ) if( gs->rs.current_cam != &LWcam ) for( x = 0; x < GextrasampLIGHT; x++ ) { ll = Gmotion_samp + x; //.. ll=x; gs->cursamp = x; draw_poly2RS( pp1, x, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 0 ) if( ( gs->rs.itsalight == 2 ) ) if( gs->rs.current_cam != &LWcam ) for( x = 0; x < 1; x++ ) { // ll=layer*Gmotion_samp+x; ll = x; gs->cursamp = x; draw_poly2RS( pp1, layer, lum,gs ); } if( gs->rs.itsalight == 3 ) // we're tagging tiles for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; gs->cursamp = x; success += draw_poly2RS( pp1, x, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( gs->rs.itsalight == 1 ) // for (x=0;xrs.itsalight != 1 ) for( x = 0; x < 4; x++ ) { if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[layer * 4].x; pp.p[x].y += campass[layer * 4].y; } if( gs->rs.itsalight == 2 ) { int csmp; csmp = layer; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( gs->rs.itsalight != 1 ) gs->cursamp = layer; tim = ( float ) layer / ( float ) Gmotion_samp; if( gs->rs.itsalight == 1 ) tim = 0.0f; if( gs->rs.itsalight != 1 ) if( !( ( gs->rs.itsalight == 2 ) && ( gs->rs.TILEMODE == 0 ) ) ) for( x = 0; x < 4; x++ ) { //if (cursamp>0) if( gs->rs.itsalight != 1 ) { pp.p[x].x += pp.v[x].x * tim; pp.p[x].y += pp.v[x].y * tim; pp.p[x].z += pp.v[x].z * tim; pp.w[x].x += pp.wv[x].x * tim; pp.w[x].y += pp.wv[x].y * tim; pp.w[x].z += pp.wv[x].z * tim; } //if (cursamp==0) // { // pp.p[x].x+=pp.v[x].x*.55f; // pp.p[x].y+=pp.v[x].y*.55f; // pp.p[x].z+=pp.v[x].z*.55f; // pp.w[x].x+=pp.wv[x].x*.55f; // pp.w[x].y+=pp.wv[x].y*.55f; // pp.w[x].z+=pp.wv[x].z*.55f; // } } // Gclipx0=0;Gclipy0=0; // Gclipx1=current_cam->xres;Gclipy1=current_cam->yres; if( gs->rs.itsalight != 1 ) if( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) { gs->rs.Gclipx0 = 0; gs->rs.Gclipy0 = 0; gs->rs.Gclipx1 = LWcam.xres; gs->rs.Gclipy1 = LWcam.yres; } if( gs->rs.itsalight == 1 ) { gs->rs.Gclipx0 = 0; gs->rs.Gclipy0 = 0; gs->rs.Gclipx1 = current_cam->xres; gs->rs.Gclipy1 = current_cam->yres; } { float xl, yl, xs, ys; //if (0==1) { // yl=Gclipy0-1; ys = gs->rs.Gclipy1 + 1; yl = gs->rs.Gclipy0 - 1; // ys=Gclipy1; xl = gs->rs.Gclipx0 - 1; // wasn't like this before xs = gs->rs.Gclipx1 + 1; // ys = gs->rs.Gclipy1-5;// -5; // yl = gs->rs.Gclipy0+5;// + 5; // ys=Gclipy1; // xl = gs->rs.Gclipx0+5;// + 5; // wasn't like this before // xs = gs->rs.Gclipx1-5;// - 5; if( yl < 0 ) yl = 0; if( xl < 0 ) xl = 0; // xl=Gclipx0-1; // wasn't like this before // xs=Gclipx1+1; // yl+=3;xl+=3; // xl=Gclipx0+4; // xs=Gclipx1-4; } { // flicker .. int xx; int clippit = 0; int reject = 0; int cp = 0; VERT pdir; VERT camdir; VERT eye; camdir.x = gs->rs.current_cam->view[0][2]; camdir.y = gs->rs.current_cam->view[1][2]; camdir.z = gs->rs.current_cam->view[2][2]; camdir.z *= -1.0f; eye = gs->rs.current_cam->wpos; eye.z *= -1.0f; #ifdef trivial_reject for( x = 0; x < 3; x++ ) { int cp = 0; if( pp.p[x].x < xl ) cp = 1; if( pp.p[x].y < yl ) cp = 1; if( pp.p[x].x > xs ) cp = 1; if( pp.p[x].y > ys ) cp = 1; if( cp ) triv++; } #endif //if (GLOBAL_CLIPIT==0) for( x = 0; x < 3; x++ ) { pdir = pp.w[x]; pdir.z *= -1.0f; pdir.x = pdir.x - eye.x; pdir.y = pdir.y - eye.y; pdir.z = pdir.z - eye.z; Vnorm( pdir ); if( VDot( pdir, camdir ) > 0.0f ) cp++; } //GLOBAL_CLIPIT=1; //if (0==1) // if (itsalight==0) if( cp > 0 ) // if( GLOBAL_CLIPIT==0 ) { WFTYPE ret; init_geomWF( &ret ); { camspace_clipitDEANERS( pp, &ret, xl, yl, xs, ys, gs->rs.current_cam->zoom,gs ); if( ret.totalverts >= 3 ) for( xx = 1; xx < ret.totalverts - 1; xx++ ) { pp.p[0] = ret.v[0]; pp.c[0] = ret.color[0]; pp.alpha[0] = ret.alpha[0]; pp.v[0] = ret.velocity[0]; pp.p[1] = ret.v[xx]; pp.c[1] = ret.color[xx]; pp.alpha[1] = ret.alpha[xx]; pp.v[1] = ret.velocity[xx]; pp.p[2] = ret.v[xx + 1]; pp.c[2] = ret.color[xx + 1]; pp.alpha[2] = ret.alpha[xx + 1]; pp.v[2] = ret.velocity[xx + 1]; pp.p[3] = ret.v[0]; pp.c[3] = ret.color[0]; pp.v[3] = ret.velocity[0]; pp.alpha[3] = ret.alpha[0]; // eliminate a linear poly // if( !( ( pp.v[0].x == pp.v[1].x ) && ( pp.v[1].x == pp.v[2].x ) ) || ( ( pp.v[0].y == pp.v[1].y ) && ( pp.v[1].y == pp.v[2].y ) ) ) { if( gs->rs.itsalight == 3 ) success += draw_poly2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 2 ) success += draw_poly2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 1 ) success += draw_poly2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 0 ) { // printf ("draw polygon alpha = %f\n",pp.alpha[0]);fflush(stdout); // success += draw_poly2newHAIRTILERS( pp, layer, lum,gs ); success += draw_poly2newRS( pp, layer, lum,gs ); } } } } free_geomWF( &ret ); } } } return ( success ); } static void draw_geomWFRS( WFTYPE * geom, int cs ,GLOBS *gs) { POLYDAT tri; int ll, x, y; cs = 0; tri.v[0].x = 0; tri.v[0].y = 0; tri.v[0].z = 0; tri.v[1].x = 0; tri.v[1].y = 0; tri.v[1].z = 0; tri.v[2].x = 0; tri.v[2].y = 0; tri.v[2].z = 0; tri.v[3].x = 0; tri.v[3].y = 0; tri.v[3].z = 0; tri.v[4].x = 0; tri.v[4].y = 0; tri.v[4].z = 0; if( gs->rs.itsalight == 2 ) { for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { gs->GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[2] = geom->v[geom->facelist[pp]]; tri.v[2] = geom->velocity[geom->facelist[pp]]; tri.w[2] = geom->v[geom->facelist[pp]]; tri.wv[2] = geom->velocity[geom->facelist[pp]]; draw_poly3dRS( tri, cs, ( unsigned char ) 0,gs ); } } } if( gs->rs.itsalight == 2 ) // for (ll=0;lltotalfaces=%f\n",geom->totalfaces); for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { gs->GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.c[y - geom->face_start[x]].x = 0; tri.c[y - geom->face_start[x]].y = 0; tri.c[y - geom->face_start[x]].z = 0; tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); } //#ifdef RENDERLW draw_poly3dRS( tri, cs, ( unsigned char ) 0,gs ); //#endif #ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); #endif } } if( gs->rs.itsalight == 0 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { gs->GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[t].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[t]); } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[2].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[2]); //#ifdef RENDERLW draw_poly3dRS( tri, cs, ( unsigned char ) 0,gs ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } } //for (cs=0;csrs.itsalight == 0 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { gs->GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); tri.c[y - geom->face_start[x]].x = 255.0f; tri.c[y - geom->face_start[x]].y = 255.0f; tri.c[y - geom->face_start[x]].z = 255.0f; } //#ifdef RENDERLW draw_poly3dRS( tri, cs, ( unsigned char ) 0 ,gs); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } if( gs->rs.itsalight == 3 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { gs->GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[t].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[t]); } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[2] = geom->v[geom->facelist[pp]]; tri.v[2] = geom->velocity[geom->facelist[pp]]; tri.w[2] = geom->v[geom->facelist[pp]]; tri.wv[2] = geom->velocity[geom->facelist[pp]]; // tri.p[2].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[2]); //#ifdef RENDERLW draw_poly3dRS( tri, cs, ( unsigned char ) 0,gs ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } } //for (cs=0;csrs.itsalight == 3 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { gs->GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); tri.c[y - geom->face_start[x]].x = 255.0f; tri.c[y - geom->face_start[x]].y = 255.0f; tri.c[y - geom->face_start[x]].z = 255.0f; } //#ifdef RENDERLW draw_poly3dRS( tri, cs, ( unsigned char ) 0,gs ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom->v[x]); //for (x=0;xtotalverts;x++) geom->v[x].z *= -1.0f; } static int draw_poly3dRS( POLYDAT tri, int cs, unsigned char lum,GLOBS *gs ) { int success = 0; VERT2 aaa, bbb, ccc; VERT aa, bb, cc; float s; int x; // GLOBAL_CLIPIT = 0; for( x = 0; x < 3; x++ ) { tri.p[x].z *= -1.0f; tri.v[x].z *= -1.0f; tri.alpha[x] = 1.0f; SHAVEcoord_convertTOSHAVE( &tri.p[x] ); // hack!! SHAVEcoord_convertTOSHAVE( &tri.v[x] ); // hack!! tri.w[x] = tri.p[x]; tri.wv[x] = tri.v[x]; } s = ( float ) gs->rs.current_cam->yres / 2.0f; aaa.x = tri.p[0].x; aaa.y = tri.p[0].y; aaa.z = tri.p[0].z; /// aaa=vxmp3(current_cam->view,tri.p[0],current_cam->zoom); aaa = world2camRS( gs->rs.current_cam, aaa,gs ); aa.x = aaa.x; aa.y = aaa.y; aa.z = aaa.z; // aa.x=(aa.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // aa.y=((float)current_cam->yres/2.0 - aa.y * s +.5); // aa.z=aaa.z; bbb.x = tri.p[1].x; bbb.y = tri.p[1].y; bbb.z = tri.p[1].z; // bbb=vxmp3(current_cam->view,tri.p[1],current_cam->zoom); bbb = world2camRS( gs->rs.current_cam, bbb,gs ); bb.x = bbb.x; bb.y = bbb.y; bb.z = bbb.z; // bb.x=(bb.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // bb.y=((float)current_cam->yres/2.0 - bb.y * s +.5); // bb.z=bbb.z; ccc.x = tri.p[2].x; ccc.y = tri.p[2].y; ccc.z = tri.p[2].z; // bbb=vxmp3(current_cam->view,tri.p[1],current_cam->zoom); ccc = world2camRS( gs->rs.current_cam, ccc,gs ); cc.x = ccc.x; cc.y = ccc.y; cc.z = ccc.z; // cc.x=(cc.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // cc.y=((float)current_cam->yres/2.0 - cc.y * s +.5); // cc.z=ccc.z; tri.p[0] = aa; tri.p[1] = bb; tri.p[2] = cc; tri.p[3] = aa; success = 0; // gs->rs.GLOBAL_CLIPIT = 0; // if( ( aaa.clip + bbb.clip + ccc.clip ) != 0 ) // gs->rs.GLOBAL_CLIPIT = 1; { int dm; dm = gs->rs.itsalight; if( dm == 1 ) { itsalight=1; gs->rs.itsalight = 1; success = draw_polyRS( tri, cs, lum,gs ); // 0 } if( dm == 3 ) { gs->rs.itsalight = 3; itsalight=3; success = draw_polyRS( tri, cs, lum,gs ); // 0 } if( dm == 0 ) { { int qq; itsalight=0; gs->rs.itsalight = 0; // for (x=0;xrs.itsalight = 2; // current_cam=&LWcam; // printf ("occlusions\n"); draw_polyRS( tri, cs, lum,gs ); // //if (success) // { // int qq; // itsalight=2; // draw_poly(tri,cs,lum); // } } itsalight=dm; gs->rs.itsalight = dm; } return ( success ); } int cache_polyRS(POLYDAT tri, int xx,GLOBS *gs) { draw_polyRS(tri,0,255,gs); return(1); } int cache_polylineRS(POLYDAT tri, int xx,GLOBS *gs) { draw_polylineRS(tri,0,255,gs); return(1); } static int draw_a_curveRS( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ,GLOBS *gs) { int doit = 0; if( gs->rs.TILEMODE != 0 ) { if( gs->rs.TILEMODE == 6 ) { TILEMODE=6; itsalight=0; gs->rs.itsalight = 0; gs->curtile=curtile; draw_a_curve2RS( wf, h, cs, curtile,gs ); } } return ( doit ); } static int draw_poly2newRS( POLYDAT pp, int layer, unsigned char lum, GLOBS *gs ) { int triangles = 0; int x; int success = 0; float y; int a, b; float y1; int same = 0; float alpha; float maxy = -99999, miny = 99999; int imaxy, iminy; VERT vec1, vec2; VERT cvec1, cvec2; float a1, a2; float avec1, avec2; float abas1, abas2; VERT bas1, bas2; VERT cbas1, cbas2; VERT p1, p2, p3, p4, c1, c2, c3, c4; VERT zero; int pageres; float tim = 0.0f; int offscreen = 0; int equal = 0; int Lsclipx0, Lsclipx1, Lsclipy0, Lsclipy1; int GSxres, GSyres; GSxres = gs->rs.current_cam->xres * GLOBALSAMP; GSyres = gs->rs.current_cam->yres * GLOBALSAMP; // if (pleft.xrs.Gclipx0 * GLOBALSAMP; Lsclipy0 = gs->rs.Gclipy0 * GLOBALSAMP; Lsclipx1 = gs->rs.Gclipx1 * GLOBALSAMP; Lsclipy1 = gs->rs.Gclipy1 * GLOBALSAMP; zero.x = 0.0f; zero.y = 0.0f; zero.z = 0.0f; vec1 = zero; vec2 = zero; cvec1 = zero; cvec2 = zero; bas1 = zero; cbas1 = zero; abas1 = 0.0f; abas2 = 0.0f; bas2 = zero; cbas2 = zero; p1 = zero; p2 = zero; c1 = zero; c2 = zero; a1 = 0.0f; a2 = 0.0f; pp.p[3] = pp.p[0]; // wrap pp.c[3] = pp.c[0]; // wrap pp.v[3] = pp.v[0]; // wrap pp.alpha[3] = pp.alpha[0]; // wrap //if (gs->rs.TILEMODE==6) //if (gs->rs.itsalight==0) //printf (" : %f\n",pp.alpha[0]); pageres = gs->rs.current_cam->xres * gs->rs.current_cam->yres; if ( gs->rs.TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( int ) GLOBALSAMP *( int ) GLOBALSAMP; } if ( gs->rs.itsalight != 1 ) for ( x = 0; x < 4; x++ ) { if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[layer * 4].x; pp.p[x].y += campass[layer * 4].y; } if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight == 2 ) { pp.p[x].x += gs->rs.calibrateX; // we're only doing this for occlusion! pp.p[x].y += gs->rs.calibrateY; } } if( gs->rs.TILEMODE != 0 ) for( x = 0; x < 4; x++ ) { pp.p[x].x *= ( float ) GLOBALSAMP; pp.p[x].y *= ( float ) GLOBALSAMP; pp.v[x].x *= ( float ) GLOBALSAMP; pp.v[x].y *= ( float ) GLOBALSAMP; } if( gs->rs.itsalight != 1 ) for( x = 0; x < 4; x++ ) { if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight == 2 ) { pp.p[x].x += .5; // we're only doing this for occlusion! pp.p[x].y -= .5; } } if( gs->rs.itsalight != 1 ) { gs->tilebuff.cursamp = layer; gs->rs.current_cam->cursamp=layer; } gs->tilebuff.cursamp=0; tim = 0.0f; //if (0==1) //if (gs->rs.TILEMODE!=2) if( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) { VERT low, hi; low.x = 99999; low.y = 99999; hi.x = -11111; hi.y = -11111; for( x = 0; x < 4; x++ ) { VERT pd; pd = pp.p[x]; // pd.x*=2.0f; pd.x /= ( float ) GLOBALSAMP; // pd.y*=2.0f; pd.y /= ( float ) GLOBALSAMP; if( pd.x < low.x ) low.x = pd.x; if( pd.y < low.y ) low.y = pd.y; if( pd.x > hi.x ) hi.x = pd.x; if( pd.y > hi.y ) hi.y = pd.y; // same+=tag_tile((int) pd.x,pd.y, Gslg,GhairID, GnodeID); } // same+=tag_tile_rect((int) floor(low.x-1),(int)floor(low.y-1),(int)ceil(hi.x+1),(int)ceil(hi.y+1), Gslg,GhairID, GnodeID); // same+=tag_tile_rect((int) floor(low.x),(int)floor(low.y),(int)ceil(hi.x),(int)ceil(hi.y), Gslg,GhairID, GnodeID); same += tag_tile_rect( ( int ) floor( low.x ) - 1, ( int ) floor( low.y ) - 1, ( int ) ceil( hi.x ) + 1, ( int ) ceil( hi.y ) + 1, Gslg, GhairID, GnodeID, triangles,Gcurpass ); } if( !( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) ) { for( x = 0; x < 4; x++ ) { int off = 0; if( pp.p[x].y < miny ) miny = pp.p[x].y; if( pp.p[x].y > maxy ) maxy = pp.p[x].y; } imaxy = ( int ) ( maxy ); iminy = ( int ) ( miny ); ///if (equal==0) { // if (gs->rs.TILEMODE>2) printf ("I'm here\n"); /////if ((int)iminy!=(int)imaxy) // for (y=(float)iminy+1.0f;y<(float)imaxy+1.0f;y+=1.0f) if( iminy < 0 ) iminy = 0; // if (imaxy>(current_cam->yres)*GLOBALSAMP) imaxy=(current_cam->yres-1)*GLOBALSAMP; if( gs->rs.itsalight == 1 ) if( imaxy > gs->rs.current_cam->yres - 1 ) imaxy = gs->rs.current_cam->yres - 1; for( y = ( float ) iminy; y < ( float ) imaxy + 1.0f; y += 1.0f ) //<-- this was the last one // for( y = ( float )floor(miny); y <= ( float )ceil(maxy) ; y += 1.0f ) //<-- this was the last one // for (y=(float)iminy;y<(float)imaxy;y+=1.0f) // for (y=(float)miny+1.0f;y<(float)maxy+1.0f;y+=1.0f) { int yclip = 1; int baseadd = 0; int gbaseadd = 0; if( gs->rs.TILEMODE == 0 ) { int scanl; scanl = ( int ) y *gs->rs.current_cam->xres; baseadd = scanl ; gbaseadd = scanl ; } if( gs->rs.TILEMODE != 0 ) { int gclpy; int lp; lp = 0; gclpy = ( int ) ( y - Lsclipy0 ) * alltiles.sx * GLOBALSAMP; // printf ("y=%f Gclipy0=%f\n",(float)y,(float)Gclipy0); baseadd = gclpy + lp; // layer*(pageres); gbaseadd = gclpy +layer*gs->rs.current_cam->zPage; // gbaseadd=(int)(y-Gclipy0*GLOBALSAMP)*alltiles.sx*GLOBALSAMP; ; } y1 = y; //+campass[cursamp].y; ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( y >= Lsclipy0 ) && ( y < Lsclipy1 ) ) ) yclip = 0; ////- // if ((gs->rs.TILEMODE==0)&&((y>=Gclipy0)&&(yrs.TILEMODE == 0 ) && ( ( y >= gs->rs.Gclipy0 ) && ( y < gs->rs.Gclipy1 ) ) ) yclip = 0; ////- if( yclip == 0 ) { int aa; int done = 0; // find 2 intersections a = -1; // printf("drawing a poly\n"); for( aa = 0; aa < 3; aa++ ) { if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas1 = pp.p[aa]; cbas1 = pp.c[aa]; abas1 = pp.alpha[aa]; vec1.x = pp.p[aa + 1].x - pp.p[aa].x; vec1.y = pp.p[aa + 1].y - pp.p[aa].y; vec1.z = pp.p[aa + 1].z - pp.p[aa].z; cvec1.x = pp.c[aa + 1].x - pp.c[aa].x; cvec1.y = pp.c[aa + 1].y - pp.c[aa].y; cvec1.z = pp.c[aa + 1].z - pp.c[aa].z; avec1 = pp.alpha[aa + 1] - pp.alpha[aa]; a = aa; done = 1; } if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas1 = pp.p[aa + 1]; cbas1 = pp.c[aa + 1]; abas1 = pp.alpha[aa + 1]; vec1.x = pp.p[aa].x - pp.p[aa + 1].x; vec1.y = pp.p[aa].y - pp.p[aa + 1].y; vec1.z = pp.p[aa].z - pp.p[aa + 1].z; cvec1.x = pp.c[aa].x - pp.c[aa + 1].x; cvec1.y = pp.c[aa].y - pp.c[aa + 1].y; cvec1.z = pp.c[aa].z - pp.c[aa + 1].z; avec1 = pp.alpha[aa] - pp.alpha[aa + 1]; a = aa; done = 1; } } done = 0; for( aa = 0; aa < 3; aa++ ) { if( aa != a ) if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas2 = pp.p[aa]; cbas2 = pp.c[aa]; abas2 = pp.alpha[aa]; vec2.x = pp.p[aa + 1].x - pp.p[aa].x; vec2.y = pp.p[aa + 1].y - pp.p[aa].y; vec2.z = pp.p[aa + 1].z - pp.p[aa].z; cvec2.x = pp.c[aa + 1].x - pp.c[aa].x; cvec2.y = pp.c[aa + 1].y - pp.c[aa].y; cvec2.z = pp.c[aa + 1].z - pp.c[aa].z; avec2 = pp.alpha[aa + 1] - pp.alpha[aa]; b = aa; done = 1; } if( aa != a ) if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas2 = pp.p[aa + 1]; cbas2 = pp.c[aa + 1]; abas2 = pp.alpha[aa + 1]; vec2.x = pp.p[aa].x - pp.p[aa + 1].x; vec2.y = pp.p[aa].y - pp.p[aa + 1].y; vec2.z = pp.p[aa].z - pp.p[aa + 1].z; cvec2.x = pp.c[aa].x - pp.c[aa + 1].x; cvec2.y = pp.c[aa].y - pp.c[aa + 1].y; cvec2.z = pp.c[aa].z - pp.c[aa + 1].z; avec2 = pp.alpha[aa] - pp.alpha[aa + 1]; b = aa; done = 1; } } // ok, we really want to be doing this twice .. once at the top of the scanline and once at the bottom // y1 is really the base of the scaneline, so we also want to do it for y1 + 1 too if( done != 0 ) { float bas = 0; if( vec1.y != 0.0f ) bas = ( ( y1 ) - bas1.y ) / vec1.y; // vertical interp ///// if (vec1.y!=0) { // float av; // av=(vec1.y); // if (av<=0) av=.0000000001; p1.x = bas1.x + ( vec1.x ) * bas; p1.z = bas1.z + ( vec1.z ) * bas; c1.x = cbas1.x + ( cvec1.x ) * bas; c1.y = cbas1.y + ( cvec1.y ) * bas; c1.z = cbas1.z + ( cvec1.z ) * bas; a1 = abas1 + ( avec1 ) * bas; } if( vec2.y != 0.0f ) bas = ( ( y1 ) - bas2.y ) / vec2.y; ///// if (vec2.y!=0) { // float av; // av=(vec2.y); // if (av<=0) av=.000000001; p2.x = bas2.x + ( vec2.x ) * bas; p2.z = bas2.z + ( vec2.z ) * bas; c2.x = cbas2.x + ( cvec2.x ) * bas; c2.y = cbas2.y + ( cvec2.y ) * bas; c2.z = cbas2.z + ( cvec2.z ) * bas; a2 = abas2 + ( avec2 ) * bas; } } #ifdef this_makes_fat_lines if( done != 0 ) { float bas = 0; float upper; upper = y1 + 1; if( upper > ( bas1.y + vec1.y ) ) upper = bas1.y + vec1.y; if( vec1.y != 0.0f ) bas = ( ( upper ) - bas1.y ) / vec1.y; // vertical interp p3.y = y1; p4.y = y1; ///// if (vec1.y!=0) { // float av; // av=(vec1.y); // if (av<=0) av=.0000000001; p3.x = bas1.x + ( vec1.x ) * bas; p3.z = bas1.z + ( vec1.z ) * bas; c3.x = cbas1.x + ( cvec1.x ) * bas; c3.y = cbas1.y + ( cvec1.y ) * bas; c3.z = cbas1.z + ( cvec1.z ) * bas; } upper = y1 + 1; if( upper > ( bas2.y + vec2.y ) ) upper = bas2.y + vec2.y; if( vec2.y != 0.0f ) bas = ( ( upper ) - bas2.y ) / vec2.y; ///// if (vec2.y!=0) { // float av; // av=(vec2.y); // if (av<=0) av=.000000001; p4.x = bas2.x + ( vec2.x ) * bas; p4.z = bas2.z + ( vec2.z ) * bas; c4.x = cbas2.x + ( cvec2.x ) * bas; c4.y = cbas2.y + ( cvec2.y ) * bas; c4.z = cbas2.z + ( cvec2.z ) * bas; } } #endif // ok we have a pair - now scan across // if (((int)vec1.y!=0)&&((int)vec2.y!=0)) //if ((int)p1.x!=(int)p2.x) //// if (vec2.y!=0) //// if (vec1.y!=0) if( done != 0 ) { VERT pleft, cleft, pright, cright; float dx = 0.0f, dz = 0.0f, aleft, aright; float cdx = 0.0f, cdy = 0.0f, cdz = 0.0f, ad; pleft = zero; pright = zero; cleft = zero; cright = zero; aleft = 0.0f; aright = 0.0f; #ifdef this_makes_fat_lines { int lind, rind; int qq; float pax[4], tmpx; pax[0] = p1.x; pax[1] = p2.x; pax[2] = p3.x; pax[3] = p4.x; tmpx = 100000.0f; for( qq = 0; qq < 4; qq++ ) if( pax[qq] < tmpx ) { lind = qq; rind = qq; tmpx = pax[qq]; } // find left extreme index for( qq = 0; qq < 4; qq++ ) if( pax[qq] >= tmpx ) { rind = qq; tmpx = pax[qq]; } // find right extreme index if( lind == 0 ) { pleft = p1; cleft = c1; } if( lind == 1 ) { pleft = p2; cleft = c2; } if( lind == 2 ) { pleft = p3; cleft = c3; } if( lind == 3 ) { pleft = p4; cleft = c4; } if( rind == 0 ) { pright = p1; cright = c1; } if( rind == 1 ) { pright = p2; cright = c2; } if( rind == 2 ) { pright = p3; cright = c3; } if( rind == 3 ) { pright = p4; cright = c4; } } #endif //#ifdef crap // first sort left and right if( p1.x < p2.x ) { pleft = p1; pright = p2; cleft = c1; cright = c2; aleft = a1; aright = a2; } if( p2.x <= p1.x ) { pleft = p2; pright = p1; cleft = c2; cright = c1; aleft = a2; aright = a1; } //#endif dx = pright.x - pleft.x; if( dx != 0.0f ) { dz = ( pright.z - pleft.z ) / ( float ) dx; cdx = ( cright.x - cleft.x ) / ( float ) dx; cdy = ( cright.y - cleft.y ) / ( float ) dx; cdz = ( cright.z - cleft.z ) / ( float ) dx; ad = ( aright - aleft ) / ( float ) dx; } else // if dx==0 { dz = 0.0f; cdx = 0.0f; cdy = 0.0f; cdz = 0.0f; ad = 0.0f; } { float firstpix,lastpix; int clipx = 1; int x1; int qq2; float tt; // was here int pcount=0; int endpix; qq2 = ( int ) floor(pright.x); //if (gs->rs.itsalight==1) baseadd=0; //if (gs->rs.TILEMODE==0) // if ((pright.x-pleft.x)xres) clipx=0; //if (gs->rs.TILEMODE>0) // if ((pright.x-pleft.x)xres*GLOBALSAMP) clipx=0; ////- { firstpix=fabs(pleft.x)-fabs(floor(pleft.x)); firstpix=1.0-firstpix; } { lastpix=fabs(pright.x)-fabs(floor(pright.x)); // lastpix=1.0f-lastpix; } //endpix=qq2-(int)pleft.x; endpix=(int)((qq2-floor(pleft.x))-1); // for( tt = ( float ) floor(pleft.x); tt <= ( float ) ( qq2 ); tt += 1.0f ) for( tt = ( float ) floor(pleft.x); tt < ( float ) ( qq2 ); tt += 1.0f ) // for( tt = ( float ) (pleft.x); tt < ( float ) ( pright.x ); tt += 1.0f ) // this gives better fill but doesn't fade at the tips tt < ( float )( qq2 )+1.0f; tt += 1.0f ) { int clipit = 0; ////- if( gs->rs.itsalight != 2 ) if( gs->rs.itsalight > 0 ) if( !( ( tt >= gs->rs.Gclipx0 ) && ( tt <= gs->rs.Gclipx1 ) ) ) clipit = 1; if( gs->rs.TILEMODE == 0 ) ////- if( gs->rs.current_cam == &LWcam ) ////- if( !( ( tt >= gs->rs.Gclipx0 ) && ( tt <= gs->rs.Gclipx1 ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE != 0 ) ////- if( !( ( tt >= Lsclipx0 ) && ( tt <= Lsclipx1 ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE == 0 ) ////- if( gs->rs.current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < gs->rs.current_cam->xres ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE != 0 ) ////- if( gs->rs.current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < GSxres ) ) ) clipit = 1; //if (pright.x-pleft.x>0.0f) // for (tt=pleft.x;tt<=pright.x;tt+=1.0f) if( clipit == 0 ) { float alpha; int ok = 1; VERT pc, cc; float xx; int x2; int y2; VERT2 wpt; VERT wpt2; x = ( int ) ( tt ); x1 = ( int ) ( x ); x2 = x1; y2 = ( int ) y; pc.x = ( float ) x; pc.y = ( float ) ( ( int ) y ); // round it off if( gs->rs.TILEMODE > 0 ) x2 = x2 - Lsclipx0; if( gs->rs.TILEMODE > 0 ) y2 = y2 - Lsclipy0; xx = ( float ) ( tt - pleft.x ); // +campass[cursamp+layer*minsamps].x)-pleft.x; pc.z = pleft.z + dz * ( float ) xx; // wpt.x=pc.x; // wpt.y=pc.y; // wpt.z=pc.z; // wpt=cam2world(current_cam,wpt); // wpt2.x=wpt.x; // wpt2.y=wpt.y; // wpt2.z=wpt.z; cc.x = cleft.x + cdx * ( float ) xx; cc.y = cleft.y + cdy * ( float ) xx; cc.z = cleft.z + cdz * ( float ) xx; alpha = aleft + ad * ( float ) xx; // plot it ok = 1; // if (gs->rs.TILEMODE==1) ok=1; if( gs->rs.TILEMODE == 0 ) if( ( ( y2 < gs->rs.Gclipy0 ) || ( y2 >= gs->rs.Gclipy1 ) ) ) { ok = 0; } if( gs->rs.TILEMODE == 0 ) if( ( ( x2 < gs->rs.Gclipx0 ) || ( x2 >= gs->rs.Gclipx1 ) ) ) { ok = 0; } // x2 and y2 were >= if( ( gs->rs.TILEMODE != 0 ) && ( ( y2 < 0 ) || ( y2 >= GSyres ) ) ) { ok = 0; } if( ( gs->rs.TILEMODE != 0 ) && ( ( x2 < 0 ) || ( x2 >= GSxres ) ) ) { ok = 0; } if( ok ) { int pixoff = 0; int aa4 = 1; float ftt, fy; float geomz = 1000000.0f; int geomztest = 1; int hairztest = 1; ok = 1; if( gs->rs.TILEMODE == 6 ) gs->rs.current_cam = &gs->tilebuff; if( gs->rs.current_cam->geombuff ) if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( ( int ) gs->rs.current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = gs->rs.current_cam->geombuff[gbaseadd + x2]; if( ( gs->rs.TILEMODE == 0 ) ) aa4 = ( int ) y2 *gs->rs.current_cam->xres + x2; if( ( gs->rs.TILEMODE != 0 ) ) aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; ok = 1; if( gs->rs.itsalight != 1 ) // we don't want to occlude with geom on a light pass if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( pc.z > geomz - .000000001 ) geomztest = 0; aa4 *= 4; if( gs->rs.TILEMODE == 1 ) ok = 1; ////- if( gs->rs.TILEMODE == 0 ) ////- if( ( gs->rs.current_cam == &LWcam ) && ( ( y < gs->rs.Gclipy0 ) || ( y >= gs->rs.Gclipy1 ) ) ) ////- { ok = 0; } ////- if( gs->rs.itsalight != 2 ) if( ( gs->rs.itsalight > 0 ) && ( ( y < gs->rs.Gclipy0 ) || ( y >= gs->rs.Gclipy1 ) ) ) { ok = 0; } if( gs->rs.TILEMODE != 0 ) ////- if( ( gs->rs.current_cam == &LWcam ) && ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) ////- { ok = 0; } ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) ////- { ok = 0; } ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( x1 < Lsclipx0 ) || ( x1 >= Lsclipx1 ) ) ) ////- { ok = 0; } // printf ("gs->rs.TILEMODE=%d\n",gs->rs.TILEMODE); // if ((gs->rs.TILEMODE>0)&&(gs->rs.TILEMODE<6)) ok =0; // if (gs->rs.itsalight==2) ok=1; if( ok ) // this used to include geomz or hairz failiure { success += 1; // if( geomztest ) if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( gs->rs.itsalight != 3 ) { // if( gs->rs.itsalight == 2 ) // we're drawing occludions // if( current_cam->geombuff ) // { // if( gbaseadd + x2 >= 0 ) // if( ( int ) current_cam->gbound > gbaseadd + x2 ) // current_cam->geombuff[gbaseadd + x2] = pc.z; // } //if (geomztest) do we really want/need this test? if( gs->rs.TILEMODE == 6 ) if( gs->rs.itsalight == 0 ) if( gs->rs.current_cam->ibuff ) { unsigned char * cppt; VERT bg; float ia; float ba; if( alpha < 0.0f ) alpha = 0.0f; if( alpha > 255.0f ) alpha = 255.0f; ia = 1.0f - ( alpha / 255.0f ); // printf ("plot\n"); if( aa4 >= 0 ) if( ( int ) gs->rs.current_cam->ibound > aa4 + 4 ) { // if (pcount==0) //push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x, cc.y, cc.z, alpha*firstpix, pc.z,layer); // if (pcount==endpix) //push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x, cc.y, cc.z, alpha*lastpix, pc.z,layer); //if ((pcount!=0)&&(pcount!=endpix)) push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x, cc.y, cc.z, alpha, pc.z,layer); } } } } // ok } // plot } // pair interp pcount++; } // loop } // variable decl } // variable decl } // y>0 yrs.itsalight != 1 ) // layer = 0; GSxres = gs->rs.current_cam->xres * GLOBALSAMP; GSyres = gs->rs.current_cam->yres * GLOBALSAMP; // if (pleft.xrs.Gclipx0 * GLOBALSAMP; Lsclipy0 = gs->rs.Gclipy0 * GLOBALSAMP; Lsclipx1 = gs->rs.Gclipx1 * GLOBALSAMP; Lsclipy1 = gs->rs.Gclipy1 * GLOBALSAMP; zero.x = 0.0f; zero.y = 0.0f; zero.z = 0.0f; vec1 = zero; vec2 = zero; bas1 = zero; bas2 = zero; p1 = zero; p2 = zero; c1 = zero; c2 = zero; pp.p[3] = pp.p[0]; // wrap pp.c[3] = pp.c[0]; // wrap pp.v[3] = pp.v[0]; // wrap pageres = gs->rs.current_cam->xres * gs->rs.current_cam->yres; if ( gs->rs.TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( float ) GLOBALSAMP *( float ) GLOBALSAMP; } if ( gs->rs.itsalight != 1 ) for ( x = 0; x < 4; x++ ) { if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[gs->cursamp * 4].x; pp.p[x].y += campass[gs->cursamp * 4].y; } if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight == 2 ) { pp.p[x].x += gs->rs.calibrateX; pp.p[x].y += gs->rs.calibrateY; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( gs->rs.TILEMODE != 0 ) for( x = 0; x < 4; x++ ) { pp.p[x].x *= ( float ) GLOBALSAMP; pp.p[x].y *= ( float ) GLOBALSAMP; pp.v[x].x *= ( float ) GLOBALSAMP; pp.v[x].y *= ( float ) GLOBALSAMP; } // if( gs->rs.itsalight != 1 ) // for( x = 0; x < 4; x++ ) // { // if( gs->rs.TILEMODE != 3 ) // if( gs->rs.TILEMODE != 4 ) // if( gs->rs.itsalight == 2 ) // { // this is definitely not right, check this later !!! // pp.p[x].x += .5; // we're only doing this for occlusion! // pp.p[x].y -= .5; // } // } if( gs->rs.itsalight != 1 ) gs->cursamp = layer; tim = 0.0f; //if (0==1) //if (gs->rs.TILEMODE!=2) if( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) { VERT low, hi; low.x = 99999; low.y = 99999; hi.x = -11111; hi.y = -11111; for( x = 0; x < 4; x++ ) { VERT pd; pd = pp.p[x]; // pd.x*=2.0f; pd.x /= ( float ) GLOBALSAMP; // pd.y*=2.0f; pd.y /= ( float ) GLOBALSAMP; if( pd.x < low.x ) low.x = pd.x; if( pd.y < low.y ) low.y = pd.y; if( pd.x > hi.x ) hi.x = pd.x; if( pd.y > hi.y ) hi.y = pd.y; // same+=tag_tile((int) pd.x,pd.y, Gslg,GhairID, GnodeID); } // same+=tag_tile_rect((int) floor(low.x-1),(int)floor(low.y-1),(int)ceil(hi.x+1),(int)ceil(hi.y+1), Gslg,GhairID, GnodeID); // same+=tag_tile_rect((int) floor(low.x),(int)floor(low.y),(int)ceil(hi.x),(int)ceil(hi.y), Gslg,GhairID, GnodeID); same += tag_tile_rect( ( int ) floor( low.x ) - 1, ( int ) floor( low.y ) - 1, ( int ) ceil( hi.x ) + 1, ( int ) ceil( hi.y ) + 1, Gslg, GhairID, GnodeID, triangles,Gcurpass ); } if( !( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) ) { for( x = 0; x < 4; x++ ) { int off = 0; if( pp.p[x].y < miny ) miny = pp.p[x].y; if( pp.p[x].y > maxy ) maxy = pp.p[x].y; } imaxy = ( int ) floor( maxy ); iminy = ( int ) floor( miny ); ///if (equal==0) { // if (gs->rs.TILEMODE>2) printf ("I'm here\n"); /////if ((int)iminy!=(int)imaxy) // for (y=(float)iminy+1.0f;y<(float)imaxy+1.0f;y+=1.0f) if( iminy < 0 ) iminy = 0; // if (imaxy>(gs->rs.current_cam->yres)*GLOBALSAMP) imaxy=(gs->rs.current_cam->yres-1)*GLOBALSAMP; if( gs->rs.itsalight == 1 ) if( imaxy > gs->rs.current_cam->yres - 1 ) imaxy = gs->rs.current_cam->yres - 1; for( y = ( float ) iminy; y < ( float ) imaxy + 1.0f; y += 1.0f ) //<-- this was the last one // for (y=(float)iminy;y<(float)imaxy;y+=1.0f) // for (y=(float)miny+1.0f;y<(float)maxy+1.0f;y+=1.0f) { int yclip = 1; int baseadd = 0; int gbaseadd = 0; if( gs->rs.TILEMODE == 0 ) { int scanl; scanl = ( int ) y *gs->rs.current_cam->xres; baseadd = scanl;// + layer * ( pageres ); gbaseadd = scanl;// + layer * ( pageres ); } if( gs->rs.TILEMODE != 0 ) { int gclpy; int lp; lp = layer * pageres; gclpy = ( int ) ( y - Lsclipy0 ) * alltiles.sx * GLOBALSAMP; // printf ("y=%f Gclipy0=%f\n",(float)y,(float)Gclipy0); baseadd = gclpy + lp ; // layer*(pageres); gbaseadd = gclpy + lp; // gbaseadd=(int)(y-Gclipy0*GLOBALSAMP)*alltiles.sx*GLOBALSAMP; ; } y1 = y; //+campass[gs->rs.cursamp].y; ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( y >= Lsclipy0 ) && ( y < Lsclipy1 ) ) ) yclip = 0; ////- // if ((gs->rs.TILEMODE==0)&&((y>=Gclipy0)&&(yrs.TILEMODE == 0 ) && ( ( y >= gs->rs.Gclipy0 ) && ( y < gs->rs.Gclipy1 ) ) ) yclip = 0; ////- if( yclip == 0 ) { int aa; int done = 0; // find 2 intersections a = -1; // printf("drawing a poly\n"); for( aa = 0; aa < 3; aa++ ) { if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas1 = pp.p[aa]; vec1.x = pp.p[aa + 1].x - pp.p[aa].x; vec1.y = pp.p[aa + 1].y - pp.p[aa].y; vec1.z = pp.p[aa + 1].z - pp.p[aa].z; a = aa; done = 1; } if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas1 = pp.p[aa + 1]; vec1.x = pp.p[aa].x - pp.p[aa + 1].x; vec1.y = pp.p[aa].y - pp.p[aa + 1].y; vec1.z = pp.p[aa].z - pp.p[aa + 1].z; a = aa; done = 1; } } done = 0; for( aa = 0; aa < 3; aa++ ) { if( aa != a ) if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas2 = pp.p[aa]; vec2.x = pp.p[aa + 1].x - pp.p[aa].x; vec2.y = pp.p[aa + 1].y - pp.p[aa].y; vec2.z = pp.p[aa + 1].z - pp.p[aa].z; b = aa; done = 1; } if( aa != a ) if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas2 = pp.p[aa + 1]; vec2.x = pp.p[aa].x - pp.p[aa + 1].x; vec2.y = pp.p[aa].y - pp.p[aa + 1].y; vec2.z = pp.p[aa].z - pp.p[aa + 1].z; b = aa; done = 1; } } if( done != 0 ) { float bas = 0; if( vec1.y != 0.0f ) bas = ( y1 - bas1.y ) / vec1.y; // vertical interp ///// if (vec1.y!=0) { // float av; // av=(vec1.y); // if (av<=0) av=.0000000001; p1.x = bas1.x + ( vec1.x ) * bas; p1.z = bas1.z + ( vec1.z ) * bas; } if( vec2.y != 0.0f ) bas = ( y1 - bas2.y ) / vec2.y; ///// if (vec2.y!=0) { // float av; // av=(vec2.y); // if (av<=0) av=.000000001; p2.x = bas2.x + ( vec2.x ) * bas; p2.z = bas2.z + ( vec2.z ) * bas; } } // ok we have a pair - now scan across // if (((int)vec1.y!=0)&&((int)vec2.y!=0)) //if ((int)p1.x!=(int)p2.x) //// if (vec2.y!=0) //// if (vec1.y!=0) if( done != 0 ) { VERT pleft, cleft, pright, cright; float dx = 0.0f, dz = 0.0f; float cdx = 0.0f, cdy = 0.0f, cdz = 0.0f; pleft = zero; pright = zero; cleft = zero; cright = zero; // first sort left and right if( p1.x < p2.x ) { pleft = p1; pright = p2; } if( p2.x <= p1.x ) { pleft = p2; pright = p1; } dx = pright.x - pleft.x; if( dx != 0.0f ) { dz = ( pright.z - pleft.z ) / ( float ) dx; } else // if dx==0 { dz = 0.0f; } { int clipx = 1; int x1; int qq2; float tt; // was here qq2 = ( int ) floor(pright.x); //if (gs->rs.itsalight==1) baseadd=0; //if (gs->rs.TILEMODE==0) // if ((pright.x-pleft.x)rs.current_cam->xres) clipx=0; //if (gs->rs.TILEMODE>0) // if ((pright.x-pleft.x)rs.current_cam->xres*GLOBALSAMP) clipx=0; ////- // for( tt = ( float ) floor(pleft.x); tt <= ( float ) ( qq2 ); tt += 1.0f ) for( tt = ( float ) (pleft.x); tt < ( float ) ( pright.x ); tt += 1.0f ) { int clipit = 0; ////- if( gs->rs.itsalight != 2 ) if( gs->rs.itsalight > 0 ) if( !( ( tt >= gs->rs.Gclipx0 ) && ( tt <= gs->rs.Gclipx1 ) ) ) clipit = 1; if( gs->rs.TILEMODE == 0 ) ////- if( gs->rs.current_cam == &LWcam ) ////- if( !( ( tt >= gs->rs.Gclipx0 ) && ( tt <= gs->rs.Gclipx1 ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE != 0 ) ////- if( !( ( tt >= Lsclipx0 ) && ( tt <= Lsclipx1 ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE == 0 ) ////- if( gs->rs.current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < gs->rs.current_cam->xres ) ) ) clipit = 1; ////- if( gs->rs.TILEMODE != 0 ) ////- if( gs->rs.current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < GSxres ) ) ) clipit = 1; //if (pright.x-pleft.x>0.0f) // for (tt=pleft.x;tt<=pright.x;tt+=1.0f) if( clipit == 0 ) { int ok = 1; VERT pc, cc; float xx; int x2; int y2; VERT2 wpt; VERT wpt2; x = ( int ) ( tt ); x1 = ( int ) ( x ); x2 = x1; y2 = ( int ) y; pc.x = ( float ) x; pc.y = ( float ) ( ( int ) y ); // round it off if( gs->rs.TILEMODE > 0 ) x2 = x2 - Lsclipx0; if( gs->rs.TILEMODE > 0 ) y2 = y2 - Lsclipy0; xx = ( float ) ( tt - pleft.x ); // +campass[cursamp+layer*minsamps].x)-pleft.x; pc.z = pleft.z + dz * ( float ) xx; // wpt.x=pc.x; // wpt.y=pc.y; // wpt.z=pc.z; // wpt=cam2world(gs->rs.current_cam,wpt); // wpt2.x=wpt.x; // wpt2.y=wpt.y; // wpt2.z=wpt.z; // plot it ok = 1; // if (gs->rs.TILEMODE==1) ok=1; if( gs->rs.TILEMODE == 0 ) if( ( ( y2 < gs->rs.Gclipy0 ) || ( y2 >= gs->rs.Gclipy1 ) ) ) { ok = 0; } if( gs->rs.TILEMODE == 0 ) if( ( ( x2 < gs->rs.Gclipx0 ) || ( x2 >= gs->rs.Gclipx1 ) ) ) { ok = 0; } // x2 and y2 were >= if( ( gs->rs.TILEMODE != 0 ) && ( ( y2 < 0 ) || ( y2 >= GSyres ) ) ) { ok = 0; } if( ( gs->rs.TILEMODE != 0 ) && ( ( x2 < 0 ) || ( x2 >= GSxres ) ) ) { ok = 0; } if( ok ) { int pixoff = 0; int aa4 = 1; float ftt, fy; float geomz = 1000000.0f; ok = 1; if( gs->rs.TILEMODE == 6 ) gs->rs.current_cam = &gs->tilebuff; if( gs->rs.current_cam->geombuff ) if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( ( int ) gs->rs.current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = gs->rs.current_cam->geombuff[gbaseadd + x2]; if( ( gs->rs.TILEMODE == 0 ) ) aa4 = ( int ) y2 *gs->rs.current_cam->xres + x2; if( ( gs->rs.TILEMODE != 0 ) ) aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; ok = 1; if( baseadd + x2 >= 0 ) if( ( int ) gs->rs.current_cam->zbound > baseadd + x2 ) { if( gs->rs.current_cam->zbuff ) if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( gs->rs.itsalight != 2 ) if( pc.z > gs->rs.current_cam->zbuff[baseadd + x2] ) ok = 0; } //if (gs->rs.itsalight!=2) if( gs->rs.itsalight != 1 ) // we don't want to occlude with geom on a light pass if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( pc.z > geomz - .000000001 ) ok = 0; aa4 += ( pageres ) * layer; aa4 *= 4; if( gs->rs.TILEMODE == 1 ) ok = 1; ////- if( gs->rs.TILEMODE == 0 ) ////- if( ( gs->rs.current_cam == &LWcam ) && ( ( y < gs->rs.Gclipy0 ) || ( y >= gs->rs.Gclipy1 ) ) ) ////- { ok = 0; } ////- if( gs->rs.itsalight != 2 ) if( ( gs->rs.itsalight > 0 ) && ( ( y < gs->rs.Gclipy0 ) || ( y >= gs->rs.Gclipy1 ) ) ) { ok = 0; } if( gs->rs.TILEMODE != 0 ) ////- if( ( gs->rs.current_cam == &LWcam ) && ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) ////- { ok = 0; } ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) ////- { ok = 0; } ////- if( ( gs->rs.TILEMODE != 0 ) && ( ( x1 < Lsclipx0 ) || ( x1 >= Lsclipx1 ) ) ) ////- { ok = 0; } // printf ("gs->rs.TILEMODE=%d\n",gs->rs.TILEMODE); // if ((gs->rs.TILEMODE>0)&&(gs->rs.TILEMODE<6)) ok =0; // if (gs->rs.itsalight==2) ok=1; if( ok ) { success += 1; if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( gs->rs.itsalight != 3 ) { if( gs->rs.itsalight == 2 ) if( gs->rs.current_cam->geombuff ) { if( gbaseadd + x2 >= 0 ) if( ( int ) gs->rs.current_cam->gbound > gbaseadd + x2 ) gs->rs.current_cam->geombuff[gbaseadd + x2] = pc.z; // if (gs->rs.current_cam== &LWcam) // gs->rs.current_cam->ibuff[aa4]=255; } if( gs->rs.itsalight != 2 ) if( ( int ) gs->rs.current_cam->zbound > baseadd + x2 ) if( gs->rs.current_cam->zbuff ) if( baseadd + x2 >= 0 ) gs->rs.current_cam->zbuff[baseadd + x2] = pc.z; #ifdef showmetheocclusions if( gs->rs.TILEMODE == 6 ) if( gs->rs.itsalight == 2 ) { unsigned char * cppt; // printf ("plot\n"); cc.x = 255; cc.y = 255; cc.z = 255; if( gs->rs.current_cam->ibuff ) if( aa4 >= 0 ) if( gs->rs.current_cam->ibound > aa4 + 4 ) { cppt = &gs->rs.current_cam->ibuff[aa4]; if( cc.x > 255.0f ) cc.x = 255.0f; if( cc.y > 255.0f ) cc.y = 255.0f; if( cc.z > 255.0f ) cc.z = 255.0f; if( cc.x < 0.0f ) cc.x = 0.0f; if( cc.y < 0.0f ) cc.y = 0.0f; if( cc.z < 0.0f ) cc.z = 0.0f; *cppt = ( unsigned char ) cc.x; cppt++; *cppt = ( unsigned char ) cc.y; cppt++; *cppt = ( unsigned char ) 0; cppt++; *cppt = ( unsigned char ) 255; } // gs->rs.current_cam->ibuff[aa4]=(unsigned char)(cc.x); // gs->rs.current_cam->ibuff[aa4+1]=(unsigned char)(cc.y); // gs->rs.current_cam->ibuff[aa4+2]=(unsigned char)(cc.z); // gs->rs.current_cam->ibuff[aa4+3]=(unsigned char) 255; // gs->rs.current_cam->lumbuff[baseadd+x1]=(unsigned char) (lum); // come back } #endif } } // ok } // plot } // pair interp } // loop } // variable decl } // variable decl } // y>0 ytotalverts > 0 ) { clip = ( int * ) malloc( wf->totalverts * sizeof( int ) ); fhwidth = ( float * ) malloc( wf->totalverts * sizeof( float ) ); alphamult = ( float * ) malloc( wf->totalverts * sizeof( float ) ); smallish = ( int * ) malloc( wf->totalverts * sizeof( int ) ); dvert2 = ( VERT * ) malloc( wf->totalverts * sizeof( VERT ) ); init_geomWF( &fh ); init_geomWF( &hh ); fh.totalverts = wf->totalverts; hh.totalverts = wf->totalverts; alloc_geomWF( &fh ); alloc_geomWF( &hh ); //unsigned char lum; lastaa.x = 0; lastaa.y = 0; lastaa.z = 0; gs->Gcurpass=cs; gs->Gcurpass=cs; Gcurpass=cs; // cursamp=cs; if( h->cutlength != 0 ) //if (h->killme==0) { float gss; int itsaline = 0; gss = 1.0f / ( float ) GLOBALSAMP; gss/=2.0f; if (gs->rs.itsalight==1) gss= .75; if( gs->rs.head >= 0 ) if( h->mtl == gs->rs.head ) slg = 0; if( gs->rs.beard >= 0 ) if( h->mtl == gs->rs.beard ) slg = 1; if( gs->rs.eyebrow >= 0 ) if( h->mtl == gs->rs.eyebrow ) slg = 2; if( gs->rs.eyelash >= 0 ) if( h->mtl == gs->rs.eyelash ) slg = 3; if( gs->rs.splines >= 0 ) if( h->mtl == gs->rs.splines ) slg = 4; // h->ambient=sliders[7][slg].value*h->slider[7]; cs = cs % gs->rs.LOCAL_PASSES[slg]; passes=(float)gs->rs.LOCAL_PASSES[slg]; // passes/=2.0f; if (passes<1.0f) passes=1.0f; //passes=1.0/passes; //passes=1.0-passes; //passes*=passes; //passes=1.0-passes; stp = 1; if( global_segs == 5 ) stp = 10; //rad=(float)gs->rs.restBOUNDLENGTH/1500.0f; rad = 1.0f; tm.x = wf->v[0].x; tm.y = wf->v[0].y; tm.z = wf->v[0].z; //tm=vxmp(current_cam->view,tm); tm = world2camRS( gs->rs.current_cam, tm,gs ); tm.x += 1.0f; ///(float)current_cam->xres; //tm.y=0; //tm.z=0; //tm=vxmp(current_cam->iview,tm); tm = cam2world( gs->rs.current_cam, tm ); tm.x -= wf->v[0].x; tm.y -= wf->v[0].y; tm.z -= wf->v[0].z; d = sqrt( tm.x * tm.x + tm.y * tm.y + tm.z * tm.z ); // pixel span if( d != 0 ) rad /= d; else rad = 0; ////rad*=5; //if (itsalight==1) rad*=1.5; last = 0; //hss=(float)LOCAL_SEGS[h->mtl]; hss = ( float ) wf->totalverts; lastrad = 0; too_big=0; for( x = 0; x < wf->totalverts; x++ ) { float alpha; float r1; float r2; int docurve = 1; itsaline = 0; r2 = ( float ) ( ( ( wf->totalverts - 1 ) - ( x ) ) / ( float ) ( wf->totalverts - 1 ) ) * h->baserad; r2 += ( ( float ) ( x ) / ( ( float ) ( wf->totalverts - 1 ) ) ) * h->tiprad; r2 *= rad; { alpha = r2; if (r2>180) too_big=1; if( alpha > 1.0f ) alpha = 1.0f; if( alpha < 0.0f ) alpha = 0.0f; if( gs->rs.itsalight == 0 ) if( r2 < gss ) { if (r2 < gss) itsaline = 1; r2 = gss; } } // if( r2 < .025 ) // r2 = .025; if( gs->rs.itsalight == 1 ) if( r2 < .05 ) { float r3; r3 = 0.05f; itsaline = 1; r2 = r3; } //itsaline=0; // no line draw { // float s; VERT2 aaa; VERT aa; aaa.x = wf->v[x].x; aaa.y = wf->v[x].y; aaa.z = wf->v[x].z; aaa = world2camRS( gs->rs.current_cam, aaa,gs ); aa.x = aaa.x; aa.y = aaa.y; aa.z = aaa.z; //if (r1<.01f) r1=.01f; this optimisation causes problems //if ((sqrt((aa.x-lastaa.x)*(aa.x-lastaa.x)+(aa.y-lastaa.y)*(aa.y-lastaa.y))>.55)||(x==wf->totalverts-1)) { clip[totalhv] = ( int ) aaa.clip; fh.v[totalhv] = wf->v[x]; smallish[totalhv] = itsaline; if( alpha < 0 ) alpha = 0; if( alpha > 255 ) alpha = 255; // alpha*= (1.0/LOCAL_PASSES[slg]); alphamult[totalhv] = alpha; lastaa = aa; fhwidth[totalhv] = r2; fh.color[totalhv] = wf->color[x]; fh.velocity[totalhv] = wf->velocity[x]; fh.uv[totalhv] = wf->uv[x]; dvert2[totalhv] = aa; totalhv++; } } } // // fh.totalverts = totalhv; docurve = 1; if( docurve == 1 ) { for( x = 0; x < totalhv; x++ ) // phase { fh.v[x].x += fh.velocity[x].x * .5; fh.v[x].y += fh.velocity[x].y * .5; fh.v[x].z += fh.velocity[x].z * .5; } if( gs->rs.TILEMODE == 6 ) if( gs->rs.itsalight == 0 ) if( totallights != 0 ) shade_a_curveRS( h, &fh,gs ); if( gs->rs.TILEMODE == 6 ) if( gs->rs.itsalight == 0 ) if( GactivateGI ) if( totallights == 0 ) shade_a_curveRS( h, &fh,gs ); if( gs->rs.itsalight != 1 ) // not for lights for( x = 0; x < totalhv; x++ ) // phase { fh.v[x].x -= fh.velocity[x].x * .5; fh.v[x].y -= fh.velocity[x].y * .5; fh.v[x].z -= fh.velocity[x].z * .5; //fh.color[x].x=255.0f; } // apply the fog before switching to cam coords if( gs->rs.itsalight == 0 ) for( x = 0; x < totalhv; x++ ) { VERT tmpv; fh.color[x].x /= 255.0f; fh.color[x].y /= 255.0f; fh.color[x].z /= 255.0f; tmpv = fh.v[x]; tmpv.z = -tmpv.z; // hack SHAVEcoord_convertFROMSHAVE( &tmpv ); if( DOING_SWATCH == 0 ) fh.color[x] = SHAVEapply_atmosphere( tmpv, fh.color[x] ); SHAVEcoord_convertTOSHAVE( &tmpv ); fh.color[x].x *= 255.0f; fh.color[x].y *= 255.0f; fh.color[x].z *= 255.0f; if( fh.color[x].x > 255.0f ) fh.color[x].x = 255.0f; if( fh.color[x].y > 255.0f ) fh.color[x].y = 255.0f; if( fh.color[x].z > 255.0f ) fh.color[x].z = 255.0f; if( fh.color[x].x < 0.0f ) fh.color[x].x = 0.0f; if( fh.color[x].y < 0.0f ) fh.color[x].y = 0.0f; if( fh.color[x].z < 0.0f ) fh.color[x].z = 0.0f; } // switch 2 camcoords for( x = 0; x < totalhv; x++ ) fh.v[x] = dvert2[x]; { VERT vec2; unsigned char lum; WFTYPE perphair; VERT zero; init_geomWF( &perphair ); perphair.totalverts = totalhv; alloc_geomWF( &perphair ); zero.x = 0; zero.y = 0; zero.z = 0; for( x = 0; x < totalhv; x++ ) { perphair.v[x] = zero; } lum = ( unsigned char ) ( h->ambient * 255.0f ); for( x = 0; x < totalhv - 1; x++ ) // if (!smallish[x]) { VERT vec; VERT aa, bb; int va, vb; va = x; vb = x + 1; // if (vb>h->segs*h->cutlength-1) {va=h->segs-2; vb=h->segs-1;} if( va > totalhv - 2 ) va = totalhv - 2; if( vb > totalhv - 1 ) vb = totalhv - 1; aa = fh.v[va]; bb = fh.v[vb]; vec.x = bb.x - aa.x; vec.y = bb.y - aa.y; vec.z = 0; vec = Vnorm( vec ); vec2.x = 0; vec2.y = 0; vec2.z = 1.0f; { VERT perp; // VERT perp2; perp.x = vec.y; perp.y = -vec.x; perp.z = 0; // perp=Vcross(vec,vec2); perphair.v[x].x += perp.x; perphair.v[x].y += perp.y; perphair.v[x].z += 0.0f; } } if( totalhv > 1 ) perphair.v[totalhv - 1] = perphair.v[totalhv - 2]; for( x = 0; x < totalhv - 1; x++ ) // if (!smallish[x]) { int qq; POLYDAT tri; int doit = 0; doit = 1; for( qq = 0; qq < 4; qq++ ) { VERT zz; zz.x = 0; zz.y = 0; zz.z = 0; tri.p[qq] = zz; tri.wv[qq] = zz; tri.w[qq] = zz; tri.v[qq] = zz; tri.c[qq] = zz; } if( ( gs->rs.TILEMODE == 0 ) || ( gs->rs.TILEMODE == 6 ) ) if( ( ( gs->rs.itsalight == 3 ) && ( success == 0 ) ) || ( gs->rs.itsalight != 3 ) ) doit = 1; if( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) doit = 1; // if ((clip[x]==0)||(clip[x+1]==0)) doit=1; if( doit ) { int a, b; VERT aa, bb; VERT waa, wbb; float sz1, sz2; VERT perp, perp2; VERT wperp, wperp2; a = x; b = ( x + 1 ); //% wf->totalverts; if( b > totalhv - 1 ) b = totalhv - 1; if( a > totalhv - 2 ) a = totalhv - 2; // if (0==1) // no polygons for the moment if (too_big==0) if ((smallish[a]+smallish[b]!=2)) //||(gs->rs.itsalight==1)) // neither one is a line { perp = perphair.v[a]; // perphair is the smoothed perpendicular in camspace, just a bunch of vectors perp2 = perphair.v[b]; sz1 = fhwidth[a]; sz2 = fhwidth[b]; aa = fh.v[a]; bb = fh.v[b]; //if ( (!isnan_float(perp.x))&& (!isnan_float(perp.y))&& (!isnan_float(perp.z))&& // (!isnan_float(perp2.x))&& (!isnan_float(perp2.y))&& (!isnan_float(perp2.z)) ) { wperp.x = perp.x * sz1; wperp.y = perp.y * sz1; wperp.z = 0; waa = wf->v[a]; wperp2.x = perp2.x * sz2; wperp2.y = perp2.y * sz2; wperp2.z = 0; wbb = wf->v[b]; wperp = cam2world1( gs->rs.current_cam, wperp ); wperp2 = cam2world1( gs->rs.current_cam, wperp2 ); //if (sz1<30) if( sz1 + sz2 > 0 ) { tri.p[0].x = aa.x - perp.x * sz1; tri.p[0].y = aa.y - perp.y * sz1; tri.p[0].z = aa.z; tri.w[0].x = waa.x - wperp.x; tri.w[0].y = waa.y - wperp.y; tri.w[0].z = waa.z - wperp.z; tri.wv[0] = wf->velocity[a]; tri.c[0] = fh.color[a]; tri.v[0] = fh.velocity[a]; if( alphamult[a] < 1.0f ) { // no premult anymore tri.c[0].x *= alphamult[a]; // tri.c[0].y *= alphamult[a]; // tri.c[0].z *= alphamult[a]; } tri.alpha[0] = alphamult[a] * 255.0f /passes; // later mult this by transparency tri.p[1].x = aa.x + perp.x * sz1; tri.p[1].y = aa.y + perp.y * sz1; tri.p[1].z = aa.z; tri.w[1].x = waa.x + wperp.x; tri.w[1].y = waa.y + wperp.y; tri.w[1].z = waa.z + wperp.z; tri.c[1] = fh.color[a]; tri.v[1] = fh.velocity[a]; tri.wv[1] = wf->velocity[a]; // if( alphamult[a] < 1.0f ) // { // tri.c[1].x *= alphamult[a]; // tri.c[1].y *= alphamult[a]; // tri.c[1].z *= alphamult[a]; // } tri.alpha[1] = alphamult[a] * 255.0f/passes; // later mult this by transparency tri.p[2].x = bb.x + perp2.x * sz2; tri.p[2].y = bb.y + perp2.y * sz2; tri.p[2].z = bb.z; tri.w[2].x = wbb.x + wperp2.x; tri.w[2].y = wbb.y + wperp2.y; tri.w[2].z = wbb.z + wperp2.z; tri.c[2] = fh.color[b]; tri.v[2] = fh.velocity[b]; tri.wv[2] = wf->velocity[b]; // if( alphamult[b] < 1.0f ) // { // tri.c[2].x *= alphamult[b]; // tri.c[2].y *= alphamult[b]; // tri.c[2].z *= alphamult[b]; // } tri.alpha[2] = alphamult[b] * 255.0f/passes; // later mult this by transparency tri.p[3] = tri.p[0]; tri.wv[3] = tri.wv[0]; tri.w[3] = tri.w[0]; tri.v[3] = tri.v[0]; tri.c[3] = tri.c[0]; // GLOBAL_CLIPIT = 0; if( gs->rs.itsalight == 1 ) { // tri.p[qq].x+=tri.v[qq].x/2.0f; // phase the shado buffs to .5 // tri.p[qq].y+=tri.v[qq].y/2.0f; // tri.p[qq].z+=tri.v[qq].z/2.0f; // tri.w[qq].x+=tri.wv[qq].x/2.0f; // phase the shado buffs to .5 // tri.w[qq].y+=tri.wv[qq].y/2.0f; // tri.w[qq].z+=tri.wv[qq].z/2.0f; success += draw_poly( tri, cs, 255 ); } else if( gs->rs.TILEMODE == 6 ) cache_polyRS( tri, curtile,gs ); tri.p[0].x = aa.x - perp.x * sz1; tri.p[0].y = aa.y - perp.y * sz1; tri.p[0].z = aa.z; tri.w[0].x = waa.x - wperp.x; tri.w[0].y = waa.y - wperp.y; tri.w[0].z = waa.z - wperp.z; tri.c[0] = fh.color[a]; tri.v[0] = fh.velocity[a]; tri.wv[0] = wf->velocity[a]; // if( alphamult[a] < 1.0f ) // { // tri.c[0].x *= alphamult[a]; // tri.c[0].y *= alphamult[a]; // tri.c[0].z *= alphamult[a]; // } tri.alpha[0] = alphamult[a] * 255.0f/passes; // later mult this by transparency tri.p[1].x = bb.x - perp2.x * sz2; tri.p[1].y = bb.y - perp2.y * sz2; tri.p[1].z = bb.z; tri.w[1].x = wbb.x - wperp2.x; tri.w[1].y = wbb.y - wperp2.y; tri.w[1].z = wbb.z - wperp2.z; tri.c[1] = fh.color[b]; tri.v[1] = fh.velocity[b]; tri.wv[1] = wf->velocity[b]; // if( alphamult[b] < 1.0f ) // { // tri.c[1].x *= alphamult[b]; // tri.c[1].y *= alphamult[b]; // tri.c[1].z *= alphamult[b]; // } tri.alpha[1] = alphamult[b] * 255.0f/passes; // later mult this by transparency tri.p[2].x = bb.x + perp2.x * sz2; tri.p[2].y = bb.y + perp2.y * sz2; tri.p[2].z = bb.z; tri.w[2].x = wbb.x + wperp2.x; tri.w[2].y = wbb.y + wperp2.y; tri.w[2].z = wbb.z + wperp2.z; tri.c[2] = fh.color[b]; tri.v[2] = fh.velocity[b]; tri.wv[2] = wf->velocity[b]; // if( alphamult[b] < 1.0f ) // { // tri.c[2].x *= alphamult[b]; // tri.c[2].y *= alphamult[b]; // tri.c[2].z *= alphamult[b]; // } tri.alpha[2] = alphamult[b] * 255.0f/passes; // later mult this by transparency tri.p[3] = tri.p[0]; tri.wv[3] = tri.wv[0]; tri.w[3] = tri.w[0]; tri.c[3] = tri.c[0]; tri.v[3] = tri.v[0]; tri.alpha[3] = tri.alpha[0]; // GLOBAL_CLIPIT = 0; // printf ("fh velocity[%d] = %f %f %f\n",b,fh.velocity[b].x,fh.velocity[b].y,fh.velocity[b].z); if( gs->rs.itsalight == 1 ) success += draw_poly( tri, cs, 255 ); else if( gs->rs.TILEMODE == 6 ) cache_polyRS( tri, curtile, gs ); // { // int qqq; //for (qqq=0;qqq<3;qqq++) printf ("%f %f %f ",tri.p[qqq].x,tri.p[qqq].y,tri.p[qqq].z); // } } } } // end NO LINES //if (gs->rs.itsalight==0) if (too_big==0) if (smallish[a]+smallish[b]==2) // it's a line seg { aa = fh.v[a]; bb = fh.v[b]; //if ( (!isnan_float(perp.x))&& (!isnan_float(perp.y))&& (!isnan_float(perp.z))&& // (!isnan_float(perp2.x))&& (!isnan_float(perp2.y))&& (!isnan_float(perp2.z)) ) { waa = wf->v[a]; wbb = wf->v[b]; //if (sz1<30) { tri.p[0] = aa; tri.w[0] = waa; tri.c[0] = fh.color[a]; tri.v[0] = fh.velocity[a]; tri.wv[0] = wf->velocity[a]; tri.alpha[0] = alphamult[a] * 255.0f/passes; // later mult this by transparency tri.p[1] = bb; tri.w[1] = wbb;; tri.c[1] = fh.color[b]; tri.v[1] = fh.velocity[b]; tri.wv[1] = wf->velocity[b]; tri.alpha[1] = alphamult[b] * 255.0f/passes; // later mult this by transparency if( gs->rs.itsalight == 1 ) { success += draw_polylineRS( tri, cs, 255,gs ); } else if( gs->rs.TILEMODE == 6 ) cache_polylineRS( tri, curtile,gs ); } } } // end LINES } } free_geomWF( &perphair ); } } } free( fhwidth ); free( clip ); free( dvert2 ); free( smallish ); free( alphamult ); free_geomWF( &fh ); free_geomWF( &hh ); } return ( success ); } static void camspace_clipitDEANERS( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */,GLOBS *gs ) { struct { VERT v; VERT w; VERT color; float alpha; VERT vel; } list1[15] , list2[15], *inList, *outList, *listTemp; int inCount; int pl; int clipoff = 0; int totalp = 0; int x; VERT nrm; VERT pln; float zoomFactor; if( ret->v != NULL ) free_geomWF( ret ); // // Put the starting poly into list1. // for( x = 0; x < 3; x++ ) { list1[x].v = pp.p[x]; list1[x].w = pp.w[x]; list1[x].alpha = pp.alpha[x]; list1[x].color = pp.c[x]; list1[x].vel = pp.v[x]; } inCount = 3; inList = list1; outList = list2; // // Get the camera normal and position of the near clipping plane. // // %%% We could speed things up a bit more if these were only // calculated once per camera, rather than recalculating them for // every poly. But that would require a code reorganization // beyond what I'm willing to tackle right now, and it's not clear // that the performance gain would be significant. // nrm.x = gs->rs.current_cam->view[0][2]; nrm.y = gs->rs.current_cam->view[1][2]; nrm.z = gs->rs.current_cam->view[2][2]; nrm = Vnorm( nrm ); //#ifdef MAX3D if( gs->rs.itsalight == 1 ) zoomFactor = gs->rs.current_cam->zoom * 18.01f; // flicker was .01 if( gs->rs.itsalight != 1 ) zoomFactor = gs->rs.current_cam->zoom * 1.01f; // flicker was .01 zoomFactor = gs->rs.current_cam->zoom * gs->rs.current_cam->nearclip; // flicker was .01 //#endif #ifndef MAX3D if( gs->rs.itsalight == 1 ) zoomFactor = gs->rs.current_cam->zoom * 1.01f; // flicker was .01 if( gs->rs.itsalight != 1 ) zoomFactor = gs->rs.current_cam->zoom * 0.01f; // flicker was .01 #endif // zoomFactor = gs->rs.current_cam->zoom * .01f; pln.x = gs->rs.current_cam->wpos.x + nrm.x * zoomFactor; pln.y = gs->rs.current_cam->wpos.y + nrm.y * zoomFactor; pln.z = gs->rs.current_cam->wpos.z + nrm.z * zoomFactor; for( pl = 0; pl <= 4; pl++ ) // cycle through all the clip planes { if( clipoff == 0 ) { int outCount = 0; int xx; int reject = 0; for( x = 0; x < inCount; x++ ) { float dd = 0.0f, td = 0.0f, perc = 0.0f; int st1 = 0, st2 = 0; int x1 = 0; x1 = ( x + 1 ) % inCount; if( pl == 0 ) // Near clipping plane. { float dr1, dr2; VERT vc1, vc2; VERT ca, ba; float cad, bad; vc1.x = inList[x].w.x - pln.x; vc1.y = inList[x].w.y - pln.y; vc1.z = inList[x].w.z - pln.z; vc1 = Vnorm( vc1 ); dr1 = VDot( vc1, nrm ); vc2.x = inList[x1].w.x - pln.x; vc2.y = inList[x1].w.y - pln.y; vc2.z = inList[x1].w.z - pln.z; vc2 = Vnorm( vc2 ); dr2 = VDot( vc2, nrm ); st1 = ( dr1 <= 0 ); st2 = ( dr2 <= 0 ); if( st1 && st2 ) { reject++; } if( !st1) { { outList[outCount] = inList[x]; outCount++; } if (st2 != st2) { ca.x = pln.x - inList[x].w.x; ca.y = pln.y - inList[x].w.y; ca.z = pln.z - inList[x].w.z; ba.x = inList[x1].w.x - inList[x].w.x; ba.y = inList[x1].w.y - inList[x].w.y; ba.z = inList[x1].w.z - inList[x].w.z; cad = VDot( ca, nrm ); bad = VDot( ba, nrm ); if( bad != 0 ) { perc = cad / bad; perc = fabs( perc ); } else perc = 0.0f; outList[outCount].w.x = inList[x].w.x + ( inList[x1].w.x - inList[x].w.x ) * perc; outList[outCount].w.y = inList[x].w.y + ( inList[x1].w.y - inList[x].w.y ) * perc; outList[outCount].w.z = inList[x].w.z + ( inList[x1].w.z - inList[x].w.z ) * perc; // wait I think I need to get a new projection // on this point outList[outCount].v = world2cam1( gs->rs.current_cam, outList[outCount].w ); outList[outCount].alpha = inList[x].alpha + ( inList[x1].alpha - inList[x].alpha ) * perc; outList[outCount].color.x = inList[x].color.x + ( inList[x1].color.x - inList[x].color.x ) * perc; outList[outCount].color.y = inList[x].color.y + ( inList[x1].color.y - inList[x].color.y ) * perc; outList[outCount].color.z = inList[x].color.z + ( inList[x1].color.z - inList[x].color.z ) * perc; outList[outCount].vel.x = inList[x].vel.x + ( inList[x1].vel.x - inList[x].vel.x ) * perc; outList[outCount].vel.y = inList[x].vel.y + ( inList[x1].vel.y - inList[x].vel.y ) * perc; outList[outCount].vel.z = inList[x].vel.z + ( inList[x1].vel.z - inList[x].vel.z ) * perc; outCount++; } } } else { switch ( pl ) { case 1: // Top clipping plane st1 = ( inList[x].v.y >= ys ); st2 = ( inList[x1].v.y >= ys ); if( st1 && st2 ) { // // Both endpoints are clipped by this plane, so // reject the entire edge. // reject++; } if( st1!=st2) { // // The endpoints are on opposite sides of the // clipping plane, so we must calculate the // intersection point and add it to the // output list. // dd = ys - inList[x].v.y; td = inList[x1].v.y - inList[x].v.y; } break; case 2: // Right clipping plane. st1 = ( inList[x].v.x >= xs ); st2 = ( inList[x1].v.x >= xs ); if( st1 && st2 ) { reject++; } if( st1!=st2) { dd = xs - inList[x].v.x; td = inList[x1].v.x - inList[x].v.x; } break; case 3: // Bottom clipping plane st1 = ( inList[x].v.y < yl ); st2 = ( inList[x1].v.y < yl ); if( st1 && st2 ) { reject++; } if( st1!=st2) { dd = yl - inList[x].v.y; td = inList[x1].v.y - inList[x].v.y; } break; case 4: // Left clipping plane st1 = ( inList[x].v.x < xl ); st2 = ( inList[x1].v.x < xl ); if( st1 && st2 ) { reject++; } if( st1!=st2) { dd = xl - inList[x].v.x; td = inList[x1].v.x - inList[x].v.x; } break; } if( !st1 ) { // // The first endpoint lies inside this plane, so // add it to the output list. // outList[outCount] = inList[x]; outCount++; } if( st1!=st2) { // // Here's the old code: // // perc = 0.0f; // // if (td != 0.0f) perc= dd / td; // // I don't think that we need the zero // check, though. We know that one y value // is >= ys and the other < ys, so they // cannot be the same, so td cannot be // zero. // // The only possibility would be if the // subtraction of the two rounds to zero, // but I don't think that that can happen // on any known floating-point // architecture. // perc = dd / td; // // Here's the old code: // // perc = fabs(perc); // // I don't think it is necessary. // // If the y-value of the first point is // greater than that of the second, then // both dd and td will be positive and so // will the result of the division. // // If the y-value of the first point is // less than that of the second, then both // dd and td will be negative, making the // result of the division once again // positive. // // So 'perc' will always be positive even // without this call. // outList[outCount].v.x = inList[x].v.x + ( inList[x1].v.x - inList[x].v.x ) * perc; outList[outCount].v.y = inList[x].v.y + ( inList[x1].v.y - inList[x].v.y ) * perc; outList[outCount].v.z = inList[x].v.z + ( inList[x1].v.z - inList[x].v.z ) * perc; outList[outCount].w.x = inList[x].w.x + ( inList[x1].w.x - inList[x].w.x ) * perc; outList[outCount].w.y = inList[x].w.y + ( inList[x1].w.y - inList[x].w.y ) * perc; outList[outCount].w.z = inList[x].w.z + ( inList[x1].w.z - inList[x].w.z ) * perc; outList[outCount].alpha = inList[x].alpha + ( inList[x1].alpha - inList[x].alpha ) * perc; outList[outCount].color.x = inList[x].color.x + ( inList[x1].color.x - inList[x].color.x ) * perc; outList[outCount].color.y = inList[x].color.y + ( inList[x1].color.y - inList[x].color.y ) * perc; outList[outCount].color.z = inList[x].color.z + ( inList[x1].color.z - inList[x].color.z ) * perc; outList[outCount].vel.x = inList[x].vel.x + ( inList[x1].vel.x - inList[x].vel.x ) * perc; outList[outCount].vel.y = inList[x].vel.y + ( inList[x1].vel.y - inList[x].vel.y ) * perc; outList[outCount].vel.z = inList[x].vel.z + ( inList[x1].vel.z - inList[x].vel.z ) * perc; outCount++; } } // case (pl) } // x (points) // // %%% Not sure of the logic behind this. If 3 edges get // clipped then don't do any more clip testing? Remember // that after the first couple of clip, we no longer have // a triangle, so losing 3 sides doesn't mean we're done. // // if( reject > 3 ) // clipoff = 1; // // This pass's outList becomes the inList for the next pass, // and vice-versa. // inCount = outCount; listTemp = inList; inList = outList; outList = listTemp; } // if (clipoff == 0) } // for (pl) ret->totalverts = inCount; ret->totalfaces = 1; ret->totalfverts = inCount; alloc_geomWF( ret ); // // The result will be sitting in 'inList', so copy that into 'ret'. // for( x = 0; x < inCount; x++ ) { ret->v[x] = inList[x].v; ret->color[x] = inList[x].color; ret->alpha[x] = inList[x].alpha; ret->velocity[x] = inList[x].vel; } } //#endif static void shade_a_curveRS( CURVEINFO * hp, WFTYPE * wf, GLOBS *gs ) //RENDERHAIR h; { VERT lg; int x; VERT H; VERT eye; int l; VERT tint; WFTYPE tmpcolor; WFTYPE *tmpshad=NULL; WFTYPE tmpgi; int counter = 0; VERT orig_tint; VERT vv; tmpshad = ( WFTYPE * ) malloc( totallights * sizeof( WFTYPE ) ); init_geomWF( &tmpcolor ); tmpcolor.totalverts = wf->totalverts; tmpcolor.totalfaces = wf->totalfaces; tmpcolor.totalfverts = wf->totalfverts; alloc_geomWF( &tmpcolor ); init_geomWF( &tmpgi ); tmpgi.totalverts = wf->totalverts; tmpgi.totalfaces = wf->totalfaces; tmpgi.totalfverts = wf->totalfverts; alloc_geomWF( &tmpgi ); for( x = 0; x < totallights; x++ ) { init_geomWF( &tmpshad[x] ); tmpshad[x].totalverts = wf->totalverts; alloc_geomWF( &tmpshad[x] ); } //#ifdef crap if( GactivateGI ) for( x = 0; x < tmpgi.totalverts; x++ ) { vv = wf->v[x]; vv.z *= -1; SHAVEcoord_convertFROMSHAVE( &vv ); tmpgi.color[x] = SHAVEapply_GI( vv, hp ); } //#endif precalc_shadow_curveRS( wf, tmpshad, hp,gs ); //h=color_a_hair(h);99 for( x = 0; x < wf->totalverts; x++ ) { tmpcolor.color[x].x = 0; tmpcolor.color[x].y = 0; tmpcolor.color[x].z = 0; // printf ("tmpshad.vel %f %f %f\n",tmpshad[0].velocity[x].x,tmpshad[0].velocity[x].y,tmpshad[0].velocity[x].z);fflush(stdout); } l = 0; if( hp->restlength > 0 ) while( l < totallights ) { { VERT fcolor; if( hp->restlength > 0 ) for( x = 0; x < wf->totalverts; x += 1 ) if( ( tmpshad[l].velocity[x].x > 0.01f ) || ( LWlight[l].type == 0 ) ) { VERT a, uv; VERT lum; float shd = 0; VERT norm; float spec; float specB; int trigger = 0; double tmpp[3]; double tmpd[3], tmpc[3]; tmpp[0] = wf->v[x].x; tmpp[1] = wf->v[x].y; tmpp[2] = wf->v[x].z; tmpc[0] = 1.0f; tmpc[1] = 1.0f; tmpc[2] = 1.0f; tmpd[0] = LWlight[l].wpos.x - wf->v[x].x; tmpd[1] = LWlight[l].wpos.y - wf->v[x].y; tmpd[2] = LWlight[l].wpos.z - wf->v[x].z; lg.x = ( float ) tmpd[0]; lg.y = ( float ) tmpd[1]; lg.z = ( float ) tmpd[2]; // light vector lg = Vnorm( lg ); lum.x = ( float ) tmpc[0]; // light color lum.y = ( float ) tmpc[1]; lum.z = ( float ) tmpc[2]; { int l2; VERT shad; VERT wpt; wpt.x = tmpp[0]; wpt.y = tmpp[1]; wpt.z = tmpp[2]; if( ( LWlight[l].trace == 1 ) || ( LWlight[l].type == 1 ) ) // ok it's a spot { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; shad = tmpshad[l].color[x]; lum.x = shad.x; lum.y = shad.y; lum.z = shad.z; } if( LWlight[l].xres > 0 ) if( LWlight[l].trace == 0 ) if( LWlight[l].type == 0 ) // ok it's a point - sum up next 6 { shad.x = 0.0f; shad.y = 0.0f; shad.z = 0.0f; l2 = l; for( l2 = l; l2 < l + 6; l2++ ) if( l2 < totallights ) if( tmpshad[l2].velocity[x].x > 0.01f ) { // if (tmpshad[l2].color[x].x>shad.x) { if( tmpshad[l2].color[x].x > shad.x ) shad.x = tmpshad[l2].color[x].x; if( tmpshad[l2].color[x].y > shad.y ) shad.y = tmpshad[l2].color[x].y; if( tmpshad[l2].color[x].z > shad.z ) shad.z = tmpshad[l2].color[x].z; } } lum.x = shad.x; lum.y = shad.y; lum.z = shad.z; } } { float vv[3]; if( x != 0 ) { vv[0] = ( wf->v[x].x - wf->v[x - 1].x ); vv[1] = ( wf->v[x].y - wf->v[x - 1].y ); vv[2] = ( wf->v[x].z - wf->v[x - 1].z ); } else { vv[0] = ( wf->v[1].x - wf->v[0].x ); vv[1] = ( wf->v[1].y - wf->v[0].y ); vv[2] = ( wf->v[1].z - wf->v[0].z ); } norm.x = vv[0]; norm.y = vv[1]; norm.z = vv[2]; } norm = Vnorm( norm ); eye.x = LWcam.wpos.x - wf->v[x].x; eye.y = LWcam.wpos.y - wf->v[x].y; eye.z = LWcam.wpos.z - wf->v[x].z; eye = Vnorm( eye ); { VERT T, L, V; float shd2 = 0.0f; shd = 0.0f; T = norm; L = lg; V = eye; { float tsq; tsq = VDot( L, T ); tsq *= tsq; shd2 = sqrt( 1.0 - tsq ); } if( shd2 > 0 ) shd += shd2; { float spec2; { float tsq; tsq = VDot( V, T ); spec2 = shd2 * sqrt( 1.0 - tsq * tsq ) - VDot( L, T ) * tsq; } if( spec2 < 0 ) spec2 = 0; spec = pow( spec2, 1.0 / ( 3.0 * ( .101 - hp->kspec ) ) ); } { float spec2; VERT V2; { float tsq; float mix=.4; V2.x=(V.x*(1.0-mix)+T.x*mix); V2.y=(V.y*(1.0-mix)+T.y*mix); V2.z=(V.z*(1.0-mix)+T.z*mix); V2=Vnorm(V2); tsq = VDot( V2, T ); spec2 = shd2 * sqrt( 1.0 - tsq * tsq ) - VDot( L, T ) * tsq; } if( spec2 < 0 ) spec2 = 0; specB = pow( spec2, (1.0 / ( 3.0 * ( .101 - hp->kspec/1.6f ) )) ); } } spec *= hp->spec; if( spec < 0 ) spec = 0; specB *= hp->spec; if( specB < 0 ) specB = 0; shd *= ( hp->diff ); shd += ( 1.0 - hp->diff ); tint.x = wf->color[x].x; tint.y = wf->color[x].y; tint.z = wf->color[x].z; orig_tint = tint; fcolor.x = shd * tint.x; //+tmpgi.color[x].x*tint.x; fcolor.y = shd * tint.y; //+tmpgi.color[x].y*tint.y; fcolor.z = shd * tint.z; //+tmpgi.color[x].z*tint.z; fcolor.x += ( 1.0 - shd ) * LWlight[l].shadowcolor.x; fcolor.y += ( 1.0 - shd ) * LWlight[l].shadowcolor.y; fcolor.z += ( 1.0 - shd ) * LWlight[l].shadowcolor.z; fcolor.x *= lum.x; fcolor.y *= lum.y; fcolor.z *= lum.z; // fcolor.x += ambient[0] * tint.x; // ambient's a global // fcolor.y += ambient[1] * tint.y; // fcolor.z += ambient[2] * tint.z; { fcolor.x += ( spec * lum.x * gs->rs.Gspec_tint.x ); //*tint.x); fcolor.y += ( spec * lum.y * gs->rs.Gspec_tint.y ); //*tint.y); fcolor.z += ( spec * lum.z * gs->rs.Gspec_tint.z ); //*tint.z); } { fcolor.x += ( specB * lum.x * gs->rs.Gspec_tint2.x ); //*tint.x); fcolor.y += ( specB * lum.y * gs->rs.Gspec_tint2.y ); //*tint.y); fcolor.z += ( specB * lum.z * gs->rs.Gspec_tint2.z ); //*tint.z); } { VERT lum2; lum2 = lum; if( lum2.x > 1.0f ) lum2.x = 1.0f; if( lum2.y > 1.0f ) lum2.y = 1.0f; if( lum2.z > 1.0f ) lum2.z = 1.0f; fcolor.x += ( 1.0 - lum2.x ) * LWlight[l].shadowcolor.x; fcolor.y += ( 1.0 - lum2.y ) * LWlight[l].shadowcolor.y; fcolor.z += ( 1.0 - lum2.z ) * LWlight[l].shadowcolor.z; } { tmpcolor.color[x].x = tmpcolor.color[x].x + fcolor.x; tmpcolor.color[x].y = tmpcolor.color[x].y + fcolor.y; tmpcolor.color[x].z = tmpcolor.color[x].z + fcolor.z; if( tmpcolor.color[x].x > 1.0f ) tmpcolor.color[x].x = 1.0f; if( tmpcolor.color[x].y > 1.0f ) tmpcolor.color[x].y = 1.0f; if( tmpcolor.color[x].z > 1.0f ) tmpcolor.color[x].z = 1.0f; } } // x } // iff if( ( LWlight[l].type == 0 ) && ( LWlight[l].trace == 0 ) ) l += 6; // skip the next 5 buffers else l++; //l++; } // total lights for( x = 0; x < wf->totalverts; x++ ) { tint = wf->color[x]; wf->color[x].x = tmpcolor.color[x].x * 255; wf->color[x].y = tmpcolor.color[x].y * 255; wf->color[x].z = tmpcolor.color[x].z * 255; if( GactivateGI ) { wf->color[x].x += ( tmpgi.color[x].x * tint.x * 255 ); wf->color[x].y += ( tmpgi.color[x].y * tint.y * 255 ); wf->color[x].z += ( tmpgi.color[x].z * tint.z * 255 ); } if( wf->color[x].x > 255.0f ) wf->color[x].x = 255.0f; if( wf->color[x].y > 255.0f ) wf->color[x].y = 255.0f; if( wf->color[x].z > 255.0f ) wf->color[x].z = 255.0f; } free_geomWF( &tmpcolor ); for( x = 0; x < totallights; x++ ) { free_geomWF( &tmpshad[x] ); } free_geomWF( &tmpgi ); if (tmpshad) free( tmpshad ); } static void precalc_shadow_curveRS( WFTYPE * h, WFTYPE * bh, CURVEINFO * hp,GLOBS *gs ) { int x, y, z; int oldsamps; for( y = 0; y < totallights; y++ ) for( x = 0; x < h->totalverts; x += 1 ) { bh[y].v[x] = h->v[x]; } for( y = 0; y < totallights; y++ ) { Gilluminate_strandRS( &bh[y], y, hp->ambient,gs ); } } static void Gilluminate_strandRS( WFTYPE * pos, int ll, float hambient,GLOBS *gs ) { VERT ret; VERT pos2; VERT lcolor; VERT drr; VERT lookvec; int q, x; float cone = 1.0f; ret.x = 0.0f; ret.y = 0.0f; ret.z = 0.0f; for( q = 0; q < pos->totalverts; q++ ) { VERT shad; lcolor = LWlight[ll].color; if( LWlight[ll].trace == 0 ) { if (!Gnative_lighting) cone = calculate_light_coneRS( pos->v[q], ll, gs->rs.Gbacklighting, &pos->velocity[q] /* get the raw cone */ ,gs ); else { cone=1.0f; pos->velocity[q].x=1.0f; pos->velocity[q].y=1.0f; pos->velocity[q].z=1.0f; } if( LWlight[ll].xres == 0 ) cone = 1.0f; } else { cone = 1.0f; pos->velocity[q].x=1.0f; pos->velocity[q].y=1.0f; pos->velocity[q].z=1.0f; } pos->color[q] = lcolor; } if (Gnative_lighting) { for( x = 0; x < pos->totalverts; x++ ) pos->v[x].z *= -1; for( x = 0; x < pos->totalverts; x++ ) SHAVEcoord_convertFROMSHAVE( &pos->v[x] ); if( DOING_SWATCH == 0 ) SHAVEapply_illuminationWF( ll, pos ); for( x = 0; x < pos->totalverts; x++ ) SHAVEcoord_convertTOSHAVE( &pos->v[x] ); for( x = 0; x < pos->totalverts; x++ ) pos->v[x].z *= -1; } for( q = 0; q < pos->totalverts; q++ ) { lcolor = pos->color[q]; cone = pos->velocity[q].x; if( LWlight[ll].trace == 0 ) { if( cone > 0.0f ) // speed consequences here { if( LWlight[ll].xres > 0 ) ret = cast_shadows_lgt_simpleRS( pos->v[q], ll,gs ); else { ret.x = 1.0f; ret.y = 1.0f; ret.z = 1.0f; } } } else if( LWlight[ll].trace == 1 ) if( cone > 0.0f ) ret = cast_shadows_lgt_simpleRS( pos->v[q], ll,gs ); { ret.x *= hambient; ret.y *= hambient; ret.z *= hambient; ret.x += ( 1.0f - hambient ); ret.y += ( 1.0f - hambient ); ret.z += ( 1.0f - hambient ); } ret.x *= lcolor.x * cone; ret.y *= lcolor.y * cone; ret.z *= lcolor.z * cone; // ret.x=lcolor.x*cone; // testing the light cone // ret.y=lcolor.x*cone; // ret.z=lcolor.x*cone; pos->color[q] = ret; } } static float calculate_light_coneRS( VERT in, int lgt, float hambient, VERT * rawcone,GLOBS *gs ) { float cone1 = 0.0f; float cone = 0.0f; VERT shad, jitt, jitt2; VERT2 tmp, tmp2; float self_sharp_z = 0; // int add; int i; int ii; float cx, cy; float ox, oy, oz; float mx = 0, my = 0, mz = 0; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; LIGHTINFO tmplg; // int junk; double tmpc[3]; //in.z *= -1; //SHAVEcoord_convertTOSHAVE(&in); cx = gs->rs.calibrateX; cy = gs->rs.calibrateY; gs->rs.calibrateX = 0.0f; gs->rs.calibrateY = 0.0f; //Gclipz=0; // if (LWlight[lgt].zbuff) if( LWlight[lgt].type == 1 ) { float midx, midy; float ddd; float ddx, ddy, ddz; int oldxres, oldyres; tmplg=LWlight[lgt]; memcpy(tmplg.view,LWlight[lgt].view,sizeof(Matrix)); memcpy(tmplg.iview,LWlight[lgt].iview,sizeof(Matrix)); oldxres = LWlight[lgt].xres; oldyres = LWlight[lgt].yres; tmplg.xres=LWlight[lgt].xres; tmplg.yres=LWlight[lgt].yres; if( oldxres == 0 ) { tmplg.xres = 100; tmplg.yres = 100; } if (oldxres>0) { tmp.x = in.x; tmp.y = in.y; tmp.z = in.z; tmp = world2camRS( &tmplg, tmp ,gs); //Gclipz=0; if (LWlight[lgt].type==1) if( tmp.clipz == 0 ) { float ftpx; ftpx = ( ( float ) tmplg.fuzz / ( float ) tmplg.xres ); midx = ( float ) tmplg.xres / 2.0f; midy = ( float ) tmplg.xres / 2.0f; ddx = tmp.x - midx; ddy = tmp.y - midy; cone = 1.0f; ddd = ( float ) fsqrt( ( ddx * ddx ) + ( ddy * ddy ) ); if( midx > 0.0f ) ddd /= ( float ) midx; //ddd/=2.0f; // half fov?? if( ddd >= .99f - ftpx ) cone = 0.0f; if( ddd < 0.55f ) cone = 1.0f; if( ( ddd >= 0.55f ) && ( ddd < 1.0f - ftpx ) ) { ddd -= 0.55f; ddd *= ( ( 1.0f - ftpx ) / .45f ); if( ddd < 0.0f ) ddd = 0.0f; // ddd=1.0f-ddd; ddd = ( 1.0f - ftpx ) - ddd; cone = ddd; } } if (LWlight[lgt].type==1) if( tmp.clipz == 0 ) { cone=1; } } else cone=1.0f; // if( oldxres == 0 ) // { // LWlight[lgt].xres = 0; // LWlight[lgt].yres = 0; // } } if (LWlight[lgt].type==0) cone=1.0f; //if (LWlight[lgt].zbuff) // if( LWlight[lgt].isroot ) // if( LWlight[lgt].type == 0 ) { float midx, midy; float ddd; float ddx, ddy, ddz; int oldxres, oldyres; tmplg=LWlight[lgt]; oldxres = LWlight[lgt].xres; oldyres = LWlight[lgt].xres; memcpy(tmplg.view,LWlight[lgt].view,sizeof(Matrix)); memcpy(tmplg.iview,LWlight[lgt].iview,sizeof(Matrix)); if( oldxres == 0 ) { tmplg.xres = 100; tmplg.yres = 100; } tmp.clipz=0; if (oldxres>0) { tmp.x = in.x; tmp.y = in.y; tmp.z = in.z; tmp = world2camRS( &tmplg, tmp ,gs); } else {cone=1.0f;tmp.clipz=0;} //Gclipz=0; if( tmp.clipz == 0 ) { cone = 1.0f; } // if( oldxres == 0 ) // { // LWlight[lgt].xres = 0; // LWlight[lgt].yres = 0; // } } shad.x = 0.0f; shad.y = 0.0f; shad.z = 0.0f; if( totallights == 0 ) cone = 1.0f; // if( LWlight[lgt].isroot ) if( cone > 0.0f ) if( ( LWlight[lgt].zbuff ) || ( LWlight[lgt].trace ) ) { int i; float cx, cy; VERT worldPt; worldPt = in; shad.x = 0; shad.y = 0; shad.z = 0; cx = gs->rs.calibrateX; cy = gs->rs.calibrateY; gs->rs.calibrateX = 0.0f; gs->rs.calibrateY = 0.0f; if( LWlight[lgt].trace == 0 ) { if( LWlight[lgt].xres > 0 ) if( ( totallights > 0 ) && ( LWlight[lgt].zbuff != NULL ) ) { float lx, ly, hx, hy; float sharp; sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if (!Gnative_lighting) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt = world2camRS( &LWlight[lgt], camPt,gs ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if( skip > 3 ) skip = 3; skip = 4 - skip; skip = 1.0f; numSamples = 0; // come back //if (0==1) { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); // for (p=0;p<4;p++) // no aa? p = 0; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; if( lx < 0 ) lx = 0; if( lx > lxr ) lx = lxr; ly = camPt.y - sharp; if( ly < 0 ) ly = 0; if( ly > lyr ) ly = lyr; hx = camPt.x + sharp; if( hx < 0 ) hx = 0; if( hx > lxr ) hx = lxr; hy = camPt.y + sharp; if( hy < 0 ) ly = 0; if( hy > lyr ) hy = lyr; if( lx == hx ) shad.x = 0.0f; if( ly == hy ) shad.x = 0.0f; if( camPt.clipz == 0 ) shad.x = illum_boxGEOM( jitt.z, lgt, lx, ly, hx, hy ); else shad.x = 0.0f; if( lxr == 0 ) shad.x = 1.0f; } shad.y = shad.x; shad.z = shad.x; } else { shad.x=1;shad.y=1;shad.z=1; } } if( LWlight[lgt].xres == 0 ) { shad.x = 1.0; shad.y = 1.0; shad.z = 1.0; } } else // Gtrace != 0 if( LWlight[lgt].trace ) { VOXSAMP vsamp; VERT rdir; rdir.x = LWlight[lgt].wpos.x - worldPt.x; rdir.y = LWlight[lgt].wpos.y - worldPt.y; rdir.z = LWlight[lgt].wpos.z - worldPt.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, worldPt, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; shad.x = shad.y = shad.z = ( 1.0f - vsamp.opacity ) * 0.75f + 0.25f; } gs->rs.calibrateX = cx; gs->rs.calibrateY = cy; } else { // if( LWlight[lgt].isroot ) if( LWlight[lgt].xres == 0 ) { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; cone=1.0f; } } //#endif // if( LWlight[lgt].isroot == 1 ) // { // LWlight[lgt].conefalloff = cone; // LWlight[lgt].coneillum = shad; // } // This is a form of caching we can't do this for threads // Unless they're local to the thread - revisit this // if( !LWlight[lgt].isroot ) // { // cone = LWlight[lgt].conefalloff; // shad = LWlight[lgt].coneillum; // } cone1 = cone * shad.x; if( ( LWlight[lgt].xres > 0 ) && ( LWlight[lgt].zbuff == NULL ) ) { cone = 1.0f; shad.x = 1.0f; cone1 = 1.0f; } shad.x = ( shad.x + LWlight[lgt].shadowcolor.x * ( 1.0 - shad.x ) ) * ( hambient ) + ( 1.0f - hambient ); shad.y = ( shad.y + LWlight[lgt].shadowcolor.y * ( 1.0 - shad.y ) ) * ( hambient ) + ( 1.0f - hambient ); shad.z = ( shad.z + LWlight[lgt].shadowcolor.z * ( 1.0 - shad.z ) ) * ( hambient ) + ( 1.0f - hambient ); rawcone->x = cone * shad.x; rawcone->y = cone * shad.y; rawcone->z = cone * shad.z; gs->rs.calibrateX = cx; gs->rs.calibrateY = cy; return ( cone1 ); } void threadedCall (unsigned current_thread, void *qqq); typedef struct { int *list; int list_total; int slg; int pass; WFTYPE *outwf; int threadID; CURVEINFO *ci; } BUNCH; static void MTmake_a_bunch( WFTYPE *outwf,int list_total, int *list, int slg, int pass, int threadID,CURVEINFO *cinfo ); extern void MTbunch_of_hairs(int list_total, int *inlist,int slg,int pass, WFTYPE *outwf,CURVEINFO *cinfo) { int th; int inc; int count=0; int xxx; int done=0; void* threadGroup=NULL; int mult=0; BUNCH gbb[SHAVE_MAX_THREADS]; if (list_total>0) { //printf ("bb->pass = %d\n",pass);fflush(stdout); mult=(int)sliders[25][slg].value; if (mult<1) mult=1; th=SHAVEnum_processors(); //th=1; if (th==0) th=1; if (list_total=2) threadGroup= SHAVEstart_thread_group(th); inc=(int)((float)list_total/(float)th); init_geomWF(outwf); if (freeze.totalverts==0) { outwf->totalverts= (LOCAL_SEGS[slg]+3)*mult*list_total; outwf->totalfverts=(LOCAL_SEGS[slg]+3)*mult*list_total; outwf->totalfaces=mult*list_total; } else { outwf->totalverts= (freeze.totalverts+3)*mult*list_total; outwf->totalfverts=(freeze.totalfverts+3)*mult*list_total; outwf->totalfaces=(freeze.totalfaces+3)*mult*list_total; } alloc_geomWF(outwf); outwf->totalverts=0; outwf->totalfverts=0; outwf->totalfaces=0; if (list_total>0) for (xxx=0;xxxoutwf=(WFTYPE *) malloc(sizeof(WFTYPE)); bb->ci=cinfo; bb->list=NULL; bb->list_total=0; bb->list= (int *) malloc((list_total+1)*sizeof(int)); xx=0; init_geomWF(bb->outwf); bb->ci=cinfo; done=0; while (done==0) { bb->list[xx]=inlist[count]; count++; xx++; if ((xxx!=th-1) &&(xx==inc)) done=1; if (count==list_total) done=1; } bb->list_total=xx; bb->pass=pass; bb->slg=slg; bb->threadID=xxx; //push_renderstate(>hreads[bb->threadID],0); // not pushing the hair for now, so no need to free if (th>=2) SHAVEstart_thread (threadGroup,threadedCall,(void*) bb); else threadedCall(0,(void*)bb); } //fixed here if ( (th>=2)) SHAVEend_thread_group(threadGroup); if (list_total>0) { int x; // ok merge the threads; for (x=0;xoutwf->totalverts) { int tf; int tv; tv=outwf->totalverts; tf=outwf->totalfverts; for (xx=0;xxoutwf->totalverts;xx++) { outwf->v[outwf->totalverts]= bb->outwf->v[xx]; outwf->vn[outwf->totalverts]= bb->outwf->vn[xx]; outwf->color[outwf->totalverts]= bb->outwf->color[xx]; //visualize norms here outwf->velocity[outwf->totalverts]=bb->outwf->velocity[xx]; outwf->uv[outwf->totalverts]= bb->outwf->uv[xx]; outwf->alpha[outwf->totalverts]= bb->outwf->alpha[xx]; outwf->totalverts++; } for (xx=0;xxoutwf->totalfverts;xx++) { outwf->facelist[outwf->totalfverts]=bb->outwf->facelist[xx]+tv; outwf->totalfverts++; } for (xx=0;xxoutwf->totalfaces;xx++) { outwf->index[outwf->totalfaces]=bb->outwf->index[xx]; outwf->face_start[outwf->totalfaces]=tf+bb->outwf->face_start[xx]; outwf->face_end[outwf->totalfaces]=tf+bb->outwf->face_end[xx]; outwf->id[outwf->totalfaces]=bb->outwf->id[xx]; outwf->r1[outwf->totalfaces]=bb->outwf->r1[xx]; outwf->r2[outwf->totalfaces]=bb->outwf->r2[xx]; outwf->totalfaces++; } } } //save_geomWF(outwf,"c:\\outgeom.obj"); free_geomWF(bb->outwf); free(bb->outwf); if (bb->list) free(bb->list); } } if (freeze.totalverts>0) // instancing is on make_normalsWF(outwf); } //memcpy(cinfo,gbb[0].ci,sizeof(CURVEINFO)); } static void MTmake_a_bunch( WFTYPE *outwf,int list_total, int *list, int slg, int pass, int threadID,CURVEINFO *ci ); void threadedCall (unsigned current_thread, void* qqq) { int x; BUNCH *bb; bb=(BUNCH *)(qqq); MTmake_a_bunch( bb->outwf,bb->list_total, bb->list, bb->slg, bb->pass, bb->threadID,bb->ci ); //static void MTmake_a_bunch( WFTYPE *outwf,int list_total, int *list, int slg, int pass, GLOBS * gs ) } static void MTmake_a_bunch( WFTYPE *outwf,int list_total, int *list, int slg, int pass, int threadID,CURVEINFO *ci ) { int nokink = 1; int x; int hc2 = 0; float ascalh, ascalr; int pid = 0; int progress = 0; int finish = 0; int smps, killit = 0; CURVEINFO cinfo; BASEHAIR tmpc; VERT vnorm; int clipx1, clipy1, clipx0, clipy0; GLOBS *gs; WFTYPE wf; gs= >hreads[threadID]; cinfo.killme = 0; { int th; int prg = 0; Gslg=slg; gs->Gslg=slg; if( total_slgfaces[slg] > 0 ) { int q; int cnnt; // WFTYPE wf; int dok = 1; init_geomWF( &wf ); Gcurpass = pass; // cursamp=pass; gs->Gcurpass=pass; // gs->cursamp=pass; init_geomWF(outwf); if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) { float d1, d2; BASEHAIR hrest; BASEHAIR h; hrest.killme = 0; progress++; ci->hairID = list[0]; ci->groupID = slg; //SHAVEID=gthreads[threadID].rs.nodeID; // ci->nodeID = SHAVEID; ci->nodeID = gs->rs.nodeID; // was SHAVEID ci->shaveID = gs->rs.SHAVEID; gs->rs.nodeID=GnodeID; { int x; int mult=0; mult=(int)sliders[25][slg].value; if (mult<1) mult=1; if (freeze.totalverts==0) { outwf->totalverts= (LOCAL_SEGS[slg]+3)*mult*list_total; outwf->totalfverts=outwf->totalverts; outwf->totalfaces=mult*list_total; alloc_geomWF(outwf); } if (freeze.totalverts>0) { outwf->totalverts= (freeze.totalverts+3)*mult*list_total; outwf->totalfverts=(freeze.totalfverts+3)*mult*list_total; outwf->totalfaces=(freeze.totalfaces+3)*mult*list_total; alloc_geomWF(outwf); } outwf->totalverts=0; outwf->totalfaces=0; outwf->totalfverts=0; for (x=0;xGhairID=hid; init_geomWF( &wf ); gthreads[threadID].threadID = threadID; gthreads[threadID].Gcurpass = pass; gthreads[threadID].GhairID = hid; gthreads[threadID].Gslg = slg; gthreads[threadID].hairnumber = hid; //printf ("bunch making curve from pass %d\n",pass);fflush(stdout); MTMAYAmake_a_curve( pass, slg, list[x], LOCAL_SEGS[slg], &wf, &gs->ci, >hreads[threadID] ); if (freeze.totalverts==0) { tf=outwf->totalfverts; for (xx=0;xxv [outwf->totalverts]=wf.v[xx]; outwf->vn [outwf->totalverts]=wf.vn[xx]; outwf->color [outwf->totalverts]=wf.color[xx]; outwf->velocity [outwf->totalverts]=wf.velocity[xx]; outwf->uv [outwf->totalverts]=wf.uv[xx]; outwf->alpha [outwf->totalverts]=wf.alpha[xx]; outwf->totalverts++; } for (xx=0;xxfacelist[outwf->totalfverts]=outwf->totalfverts; outwf->totalfverts++; } for (xx=0;xxindex[outwf->totalfaces]=wf.index[xx]; outwf->r1[outwf->totalfaces]=wf.r1[xx]; outwf->r2[outwf->totalfaces]=wf.r2[xx]; outwf->face_start[outwf->totalfaces]=tf+wf.face_start[xx]; outwf->face_end[outwf->totalfaces]=tf+wf.face_end[xx]; outwf->id[outwf->totalfaces]=hid; outwf->totalfaces++; } free_geomWF(&wf); } if (freeze.totalverts>0) { int tv; tf=outwf->totalfverts; tv=outwf->totalverts; for (xx=0;xxv [outwf->totalverts]=wf.v[xx]; outwf->vn [outwf->totalverts]=wf.vn[xx]; outwf->color [outwf->totalverts]=wf.color[xx]; outwf->velocity [outwf->totalverts]=wf.velocity[xx]; outwf->uv [outwf->totalverts]=wf.uv[xx]; outwf->alpha [outwf->totalverts]=wf.alpha[xx]; outwf->totalverts++; } for (xx=0;xxfacelist[outwf->totalfverts]=wf.facelist[xx]+tv; outwf->totalfverts++; } for (xx=0;xxindex[outwf->totalfaces]=wf.index[xx]; outwf->r1[outwf->totalfaces]=wf.r1[xx]; outwf->r2[outwf->totalfaces]=wf.r2[xx]; outwf->face_start[outwf->totalfaces]=tf+wf.face_start[xx]; outwf->face_end[outwf->totalfaces]=tf+wf.face_end[xx]; outwf->id[outwf->totalfaces]=wf.id[xx]; outwf->totalfaces++; } free_geomWF(&wf); } } } } } } //if (gs->rs.Gindex) //free(gs->rs.Gindex); //if (gs->rs.Gkd) kd_free(gs->rs.Gkd); // hc2 } static VERT cast_shadows_lgt_simpleBAD( VERT worldPt, int lgt,GLOBS *gs ) { VERT shad; int i, q, mp = 0; float cx, cy; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; float sharp; shad.x = 0; shad.y = 0; shad.z = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; // if (Gtrace == 0) if( LWlight[lgt].blank == 0 ) if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].zbuff ) if( LWlight[lgt].trace == 0 ) { float lx, ly, hx, hy; float maxp = 0; int x, y; float angle; VERT tmpa, tmpb, in; in = worldPt; for( i = 0; i < totalhairfiles; i++ ) { for( q = 0; q < 5; q++ ) if( Gshavep[i].passes[q] > mp ) mp = Gshavep[i].passes[q]; } MAXPASSES = mp; tmpa.x = in.x - LWlight[lgt].wpos.x; tmpa.y = in.y - LWlight[lgt].wpos.y; tmpa.z = in.z - LWlight[lgt].wpos.z; tmpa = Vnorm( tmpa ); tmpb.x = LWlight[lgt].view[0][2]; tmpb.y = LWlight[lgt].view[1][2]; tmpb.z = LWlight[lgt].view[2][2]; tmpb = Vnorm( tmpb ); angle = VDot( tmpa, tmpb ); if( angle > 0.0f ) { if( ( totallights > 0 ) ) // && ( (LWlight[lgt].zbuff != NULL) ) ) { sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if( ( LWlight[lgt].xres != 0 ) ) // if( ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; VERT2 cpt1, cpt2, cpt, pt; float d, dx, dy; pt.x = worldPt.x; pt.y = worldPt.y; pt.z = worldPt.z; cpt = world2cam( &LWCamOPEN, pt ); cpt1 = cpt; cpt2 = cpt; cpt1.x += 1; cpt1.y += 1; cpt1 = cam2world( &LWCamOPEN, cpt1 ); cpt2 = cam2world( &LWCamOPEN, cpt2 ); cpt1 = world2cam( &LWlight[lgt], cpt1 ); cpt2 = world2cam( &LWlight[lgt], cpt2 ); dx = cpt1.x - cpt2.x; dy = cpt1.y - cpt2.y; d = sqrt( dx * dx + dy * dy ); if( sharp < d * .75 ) { sharp = d * .75; m = sharp; } camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt.clip = 0; camPt.clipz = 0; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if( skip > 3 ) skip = 3; skip = 1.0f; numSamples = 0; { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); p = 0; shad.x = 0.0f; if( !camPt.clipz ) { int skip = 0; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; ly = camPt.y - sharp; hx = camPt.x + sharp; hy = camPt.y + sharp; if( lx < 0 ) skip = 1; if( lx > lxr ) skip = 1; if( ly < 0 ) skip = 1; if( ly > lyr ) skip = 1; if( hx < 0 ) skip = 1; if( hx > lxr ) skip = 1; if( hy < 0 ) skip = 1; if( hy > lyr ) skip = 1; if( lx == hx ) shad.x = 1.0f; if( ly == hy ) shad.x = 1.0f; // if( camPt.clip == 0 ) // flicker if( skip == 0 ) shad.x = illum_box_cursamp( jitt.z, lgt, lx, ly, hx, hy, gs->cursamp ); // cursamp needs to be passed down the chain! // else // shad.x = 1.0f; if( lxr == 0 ) shad.x = 1.0f; if( skip == 1 ) shad.x = 0.0f; } shad.y = shad.x; shad.z = shad.x; } } else { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; } } else // (totallights == 0) || (LWlight[lgt].zbuff == NULL) { // float cone=1.0f; if( LWlight[lgt].xres == 0 ) shad.x = shad.y = shad.z = 1.0; if( LWlight[lgt].xres > 0 ) shad.x = shad.y = shad.z = 0.0; } } else { shad.x = shad.y = shad.z = 0.0f; } } if( LWlight[lgt].blank ) { shad.x = shad.y = shad.z = 0.0f; } if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].trace == 0 ) if( !LWlight[lgt].zbuff ) { shad.x = shad.y = shad.z = 0.0f; } //else // Gtrace != 0 if( LWlight[lgt].trace == 1 ) { VOXSAMP vsamp; VERT rdir; rdir.x = LWlight[lgt].wpos.x - worldPt.x; rdir.y = LWlight[lgt].wpos.y - worldPt.y; rdir.z = LWlight[lgt].wpos.z - worldPt.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, worldPt, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; shad.x = shad.y = shad.z = ( 1.0f - vsamp.opacity ); } calibrateX = cx; calibrateY = cy; // this is blacking out return shad; } static void mk_polymatRS( Matrix m, int n,GLOBS *gs ) { VERT xv, yv, zv; VERT v1,vm1; VERT vv; VERT jk; jk.x=0.0f; jk.y=0.0f; jk.z=0.0f; v1=gs->rs.v[gs->rs.facelist[gs->rs.face_start[n]+1]]; vv=gs->rs.v[gs->rs.facelist[gs->rs.face_start[n]]]; vm1=gs->rs.v[gs->rs.facelist[gs->rs.face_end[n]-1]]; // xv.x = v[facelist[face_start[n] + 1]].x - v[facelist[face_start[n]]].x; // xv.y = v[facelist[face_start[n] + 1]].y - v[facelist[face_start[n]]].y; // xv.z = v[facelist[face_start[n] + 1]].z - v[facelist[face_start[n]]].z; // zv.x = v[facelist[face_end[n] - 1]].x - v[facelist[face_start[n]]].x; // zv.y = v[facelist[face_end[n] - 1]].y - v[facelist[face_start[n]]].y; // zv.z = v[facelist[face_end[n] - 1]].z - v[facelist[face_start[n]]].z; xv.x = v1.x - vv.x; xv.y = v1.y - vv.y; xv.z = v1.z - vv.z; zv.x = vm1.x - vv.x; zv.y = vm1.y - vv.y; zv.z = vm1.z - vv.z; xv = Vnorm( xv ); zv = Vnorm( zv ); yv = Vcross( xv, zv ); zv = Vcross (yv, xv); mkmatrix( m, xv, yv, zv, jk ); } static void mk_polymatRS2( Matrix m, int n,VERT handle,GLOBS *gs ) { VERT xv, yv, zv; VERT v1,vm1; VERT vv; VERT jk; jk.x=0.0f; jk.y=0.0f; jk.z=0.0f; v1=gs->rs.v[gs->rs.facelist[gs->rs.face_start[n]+1]]; vv=gs->rs.v[gs->rs.facelist[gs->rs.face_start[n]]]; vm1=gs->rs.v[gs->rs.facelist[gs->rs.face_end[n]-1]]; // xv.x = v[facelist[face_start[n] + 1]].x - v[facelist[face_start[n]]].x; // xv.y = v[facelist[face_start[n] + 1]].y - v[facelist[face_start[n]]].y; // xv.z = v[facelist[face_start[n] + 1]].z - v[facelist[face_start[n]]].z; // zv.x = v[facelist[face_end[n] - 1]].x - v[facelist[face_start[n]]].x; // zv.y = v[facelist[face_end[n] - 1]].y - v[facelist[face_start[n]]].y; // zv.z = v[facelist[face_end[n] - 1]].z - v[facelist[face_start[n]]].z; // xv.x = v1.x - vv.x; // xv.y = v1.y - vv.y; // xv.z = v1.z - vv.z; xv=handle; zv.x = vm1.x - vv.x; zv.y = vm1.y - vv.y; zv.z = vm1.z - vv.z; xv = Vnorm( xv ); zv = Vnorm( zv ); yv = Vcross( xv, zv ); zv = Vcross( yv, xv ); mkmatrix( m, xv, yv, zv, jk ); } static void Smk_polymatRS( Matrix m, int n, GLOBS *gs ) { VERT xv, yv, zv; VERT jk; jk.x=0.0f; jk.y=0.0f; jk.z=0.0f; jk.x = 0; jk.y = 0; jk.z = 0; xv.x = gs->rs.Shair[n + 1].hv[0].x - gs->rs.Shair[n].hv[0].x; xv.y = gs->rs.Shair[n + 1].hv[0].y - gs->rs.Shair[n].hv[0].y; xv.z = gs->rs.Shair[n + 1].hv[0].z - gs->rs.Shair[n].hv[0].z; yv.x = gs->rs.Shair[n].hv[1].x - gs->rs.Shair[n].hv[0].x; yv.y = gs->rs.Shair[n].hv[1].y - gs->rs.Shair[n].hv[0].y; yv.z = gs->rs.Shair[n].hv[1].z - gs->rs.Shair[n].hv[0].z; xv = Vnorm( xv ); yv = Vnorm( yv ); zv = Vcross( xv, yv ); zv = Vnorm( zv ); mkmatrix( m, xv, yv, zv, jk ); } static VERT cast_shadows_lgt_simpleRS( VERT worldPt, int lgt, GLOBS *gs ) { VERT shad; int i, q, mp = 0; float cx, cy; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; float sharp; shad.x = 0; shad.y = 0; shad.z = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; // if (Gtrace == 0) if( LWlight[lgt].blank == 0 ) if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].zbuff ) if( LWlight[lgt].trace == 0 ) { float lx, ly, hx, hy; float maxp = 0; int x, y; float angle; VERT tmpa, tmpb, in; in = worldPt; for( i = 0; i < totalhairfiles; i++ ) { for( q = 0; q < 5; q++ ) if( Gshavep[i].passes[q] > mp ) mp = Gshavep[i].passes[q]; } MAXPASSES = mp; tmpa.x = in.x - LWlight[lgt].wpos.x; tmpa.y = in.y - LWlight[lgt].wpos.y; tmpa.z = in.z - LWlight[lgt].wpos.z; tmpa = Vnorm( tmpa ); tmpb.x = LWlight[lgt].view[0][2]; tmpb.y = LWlight[lgt].view[1][2]; tmpb.z = LWlight[lgt].view[2][2]; tmpb = Vnorm( tmpb ); angle = VDot( tmpa, tmpb ); if( angle > 0.0f ) { if( ( totallights > 0 ) ) // && ( (LWlight[lgt].zbuff != NULL) ) ) { sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if( ( LWlight[lgt].xres != 0 ) ) // if( ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; VERT2 cpt1, cpt2, cpt, pt; float d, dx, dy; pt.x = worldPt.x; pt.y = worldPt.y; pt.z = worldPt.z; cpt = world2cam( &LWCamOPEN, pt ); cpt1 = cpt; cpt2 = cpt; cpt1.x += 1; cpt1.y += 1; cpt1 = cam2world( &LWCamOPEN, cpt1 ); cpt2 = cam2world( &LWCamOPEN, cpt2 ); cpt1 = world2cam( &LWlight[lgt], cpt1 ); cpt2 = world2cam( &LWlight[lgt], cpt2 ); dx = cpt1.x - cpt2.x; dy = cpt1.y - cpt2.y; d = sqrt( dx * dx + dy * dy ); if( sharp < d * .75 ) { sharp = d * .75; m = sharp; } camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt.clip = 0; camPt.clipz = 0; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if( skip > 3 ) skip = 3; skip = 1.0f; numSamples = 0; { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); p = 0; shad.x = 0.0f; if( !camPt.clipz ) { int skip = 0; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; ly = camPt.y - sharp; hx = camPt.x + sharp; hy = camPt.y + sharp; if( lx < 0 ) skip = 1; if( lx > lxr ) skip = 1; if( ly < 0 ) skip = 1; if( ly > lyr ) skip = 1; if( hx < 0 ) skip = 1; if( hx > lxr ) skip = 1; if( hy < 0 ) skip = 1; if( hy > lyr ) skip = 1; if( lx == hx ) shad.x = 1.0f; if( ly == hy ) shad.x = 1.0f; // if( camPt.clip == 0 ) // flicker if( skip == 0 ) shad.x = illum_box_cursamp( jitt.z, lgt, lx, ly, hx, hy, gs->cursamp ); // cursamp needs to be passed down the chain! // else // shad.x = 1.0f; if( lxr == 0 ) shad.x = 1.0f; if( skip == 1 ) shad.x = 0.0f; } shad.y = shad.x; shad.z = shad.x; } } else { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; } } else // (totallights == 0) || (LWlight[lgt].zbuff == NULL) { // float cone=1.0f; if( LWlight[lgt].xres == 0 ) shad.x = shad.y = shad.z = 1.0; if( LWlight[lgt].xres > 0 ) shad.x = shad.y = shad.z = 0.0; } } else { shad.x = shad.y = shad.z = 0.0f; } } if( LWlight[lgt].blank ) { shad.x = shad.y = shad.z = 0.0f; } if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].trace == 0 ) if( !LWlight[lgt].zbuff ) { shad.x = shad.y = shad.z = 0.0f; } //else // Gtrace != 0 if( LWlight[lgt].trace == 1 ) { VOXSAMP vsamp; VERT rdir; rdir.x = LWlight[lgt].wpos.x - worldPt.x; rdir.y = LWlight[lgt].wpos.y - worldPt.y; rdir.z = LWlight[lgt].wpos.z - worldPt.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, worldPt, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; shad.x = shad.y = shad.z = ( 1.0f - vsamp.opacity ); } calibrateX = cx; calibrateY = cy; return shad; } static int draw_polylineRS( POLYDAT pp, int layer, unsigned char lum,GLOBS *gs ) { int x; int ll; int success = 0; POLYDAT pp1; // GLOBAL_CLIPIT = 0; for( x = 0; x < 2; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = cam2world( gs->rs.current_cam, tmpv ); // if( tmpv.clip ) // GLOBAL_CLIPIT = 1; pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } pp1 = tocamRS( gs->rs.current_cam, pp,gs ); // printf ("pp1 velocity= %f %f %f\n",pp1.v[0].x,pp1.v[0].y,pp1.v[0].z); // if ((itsalight==0)||(itsalight==2)) if( ( gs->rs.itsalight == 0 ) ) if( ( gs->rs.current_cam == &LWcam ) || ( gs->rs.TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; ll = x; gs->cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_polyline2RS( pp1, ll, lum,gs ); } if( gs->rs.itsalight == 2 ) if( ( gs->rs.current_cam == &LWcam ) || (gs->rs.TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // current_cam->cursamp=x; // current_cam->lwtime=x; // x = layer; // Was Gcurrent_time ll = x; gs->cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_polyline2RS( pp1, ll, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( ( gs->rs.itsalight == 2 ) ) if( gs->rs.current_cam != &LWcam ) for( x = 0; x < GextrasampLIGHT; x++ ) { ll = Gmotion_samp + x; //.. ll=x; gs->cursamp = x; draw_polyline2RS( pp1, x, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 0 ) if( ( gs->rs.itsalight == 2 ) ) if( gs->rs.current_cam != &LWcam ) for( x = 0; x < 1; x++ ) { // ll=layer*Gmotion_samp+x; ll = x; gs->cursamp = x; draw_polyline2RS( pp1, layer, lum,gs ); } if( gs->rs.itsalight == 3 ) // we're tagging tiles for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; gs->cursamp = x; success += draw_polyline2RS( pp1, x, lum,gs ); } if( gs->rs.TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( gs->rs.itsalight == 1 ) // for (x=0;xrs.itsalight != 1 ) for( x = 0; x < 2; x++ ) { if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[layer * 4].x; pp.p[x].y += campass[layer * 4].y; } if( gs->rs.TILEMODE != 3 ) if( gs->rs.TILEMODE != 4 ) if( gs->rs.itsalight == 2 ) { pp.p[x].x += gs->rs.calibrateX; pp.p[x].y += gs->rs.calibrateY; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } if( gs->rs.itsalight == 2 ) { int csmp; csmp = layer; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( gs->rs.itsalight != 1 ) gs->cursamp = layer; tim = ( float ) layer / ( float ) Gmotion_samp; if( gs->rs.itsalight == 1 ) tim = 0.0f; if( gs->rs.itsalight != 1 ) if( !( ( gs->rs.itsalight == 2 ) && ( gs->rs.TILEMODE == 0 ) ) ) for( x = 0; x < 2; x++ ) { //if (cursamp>0) if( gs->rs.itsalight != 1 ) { pp.p[x].x += pp.v[x].x * tim; pp.p[x].y += pp.v[x].y * tim; pp.p[x].z += pp.v[x].z * tim; pp.w[x].x += pp.wv[x].x * tim; pp.w[x].y += pp.wv[x].y * tim; pp.w[x].z += pp.wv[x].z * tim; } //if (cursamp==0) // { // pp.p[x].x+=pp.v[x].x*.55f; // pp.p[x].y+=pp.v[x].y*.55f; // pp.p[x].z+=pp.v[x].z*.55f; // pp.w[x].x+=pp.wv[x].x*.55f; // pp.w[x].y+=pp.wv[x].y*.55f; // pp.w[x].z+=pp.wv[x].z*.55f; // } } // Gclipx0=0;Gclipy0=0; // Gclipx1=current_cam->xres;Gclipy1=current_cam->yres; if( gs->rs.itsalight != 1 ) if( ( gs->rs.TILEMODE > 0 ) && ( gs->rs.TILEMODE < 6 ) ) { gs->rs.Gclipx0 = 0; gs->rs.Gclipy0 = 0; gs->rs.Gclipx1 = LWcam.xres; gs->rs.Gclipy1 = LWcam.yres; } if( gs->rs.itsalight == 1 ) { gs->rs.Gclipx0 = 0; gs->rs.Gclipy0 = 0; gs->rs.Gclipx1 = current_cam->xres; gs->rs.Gclipy1 = current_cam->yres; } { float xl, yl, xs, ys; { // yl = gs->rs.Gclipy0-1;// + 4; // xl = gs->rs.Gclipx0-1;// + 4; // wasn't like this before yl = gs->rs.Gclipy0-GLOBALSAMP*2;// + 4; xl = gs->rs.Gclipx0-GLOBALSAMP*2;// + 4; // wasn't like this before xs = gs->rs.Gclipx1+GLOBALSAMP;// - 4; ys = gs->rs.Gclipy1+GLOBALSAMP;// - 4; // if( yl < 0 ) // yl = 0; // if( xl < 0 ) // xl = 0; } { // flicker .. int xx; int clippit = 0; int reject = 0; int cp = 0; VERT pdir; VERT camdir; VERT eye; { WFTYPE ret; init_geomWF( &ret ); { int qqq; qqq=camspace_clipitLINERS( &pp, xl, yl, xs, ys, gs->rs.current_cam->zoom,gs ); if(qqq) // if( ret.totalverts >= 2 ) // for( xx = 1; xx < ret.totalverts - 1; xx++ ) { // pp.p[0] = ret.v[0]; // pp.c[0] = ret.color[0]; // pp.alpha[0] = ret.alpha[0]; // pp.v[0] = ret.velocity[0]; // pp.p[1] = ret.v[1]; // pp.c[1] = ret.color[1]; // pp.alpha[1] = ret.alpha[1]; // pp.v[1] = ret.velocity[1]; // eliminate a linear poly // if( !( ( pp.v[0].x == pp.v[1].x ) && ( pp.v[1].x == pp.v[2].x ) ) || ( ( pp.v[0].y == pp.v[1].y ) && ( pp.v[1].y == pp.v[2].y ) ) ) { if( gs->rs.itsalight == 3 ) success += draw_polyline2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 2 ) success += draw_polyline2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 1 ) success += draw_polyline2newZRS( pp, layer, lum,gs ); if( gs->rs.itsalight == 0 ) { success += draw_polyline2newRS( pp, layer, lum,gs ); } } } } free_geomWF( &ret ); } } } return ( success ); } int sgn(float a) { return (a == 0) ? 0 : (a<0 ? -1 : 1); } int draw_polyline2newZRS(POLYDAT pp,int laya,unsigned char lum,GLOBS *gs) { return(1); } int draw_polyline2newRS(POLYDAT pp,int layer,unsigned char lum,GLOBS *gs) { int Lsclipx0, Lsclipx1, Lsclipy0, Lsclipy1; int GSxres, GSyres; int x; int y; int pagesize; int lxxx= -1,lyyy= -1; //if (0==1) { // pageres = gs->rs.current_cam->xres * gs->rs.current_cam->yres; // we can assume this is a tile GSxres = gs->rs.current_cam->xres * GLOBALSAMP; GSyres = gs->rs.current_cam->yres * GLOBALSAMP; // if (pleft.xrs.Gclipx0 * GLOBALSAMP; Lsclipy0 = gs->rs.Gclipy0 * GLOBALSAMP; Lsclipx1 = gs->rs.Gclipx1 * GLOBALSAMP; Lsclipy1 = gs->rs.Gclipy1 * GLOBALSAMP; // pageres = alltiles.sx * alltiles.sy * ( int ) GLOBALSAMP *( int ) GLOBALSAMP; // for ( x = 0; x < 2; x++ ) // do we really want additional anti aliasing? // { // // pp.p[x].x += campass[layer * 4].x; // pp.p[x].y += campass[layer * 4].y; // } for( x = 0; x < 2; x++ ) { pp.p[x].x *= ( float ) GLOBALSAMP; pp.p[x].x-=Lsclipx0; pp.p[x].y *= ( float ) GLOBALSAMP; pp.p[x].y-=Lsclipy0; pp.v[x].x *= ( float ) GLOBALSAMP; pp.v[x].y *= ( float ) GLOBALSAMP; } if( gs->rs.itsalight != 1 ) // ?? { gs->tilebuff.cursamp = layer; gs->rs.current_cam->cursamp=layer; } gs->tilebuff.cursamp=0; // ?? { float u; float d; float dx,dy,dz; float sx,sy,sz,sr,sg,sb,sa; float xx,yy,zz,rr,gg,bb,aa; float idd; dx=pp.p[1].x-pp.p[0].x; dy=pp.p[1].y-pp.p[0].y; dz=pp.p[1].z-pp.p[0].z; d=sqrt(dx*dx+dy*dy)*2; idd=floor(d); if (idd>2.0f) idd-=1.0f; if (d>0.0f) { float fsy,fsx; int ssx,ssy; xx=pp.p[0].x; yy=pp.p[0].y; zz=pp.p[0].z; rr=pp.c[0].x; gg=pp.c[0].y; bb=pp.c[0].z; aa=pp.alpha[0]; sx=dx/d; sy=dy/d; sz=dz/d; sr=(pp.c[1].x-pp.c[0].x)/d; sg=(pp.c[1].y-pp.c[0].y)/d; sb=(pp.c[1].z-pp.c[0].z)/d; sa=(pp.alpha[1]-pp.alpha[0])/d; fsx=fabs(sx); fsy=fabs(sy); ssx=0; if (sx>0) ssx=1; if (sx<0) ssx= -1; ssy=0; if (sy>0) ssy=1; if (sy<0) ssy= -1; for (u=0;u<=idd;u++) { int add; int xxx,yyy,xxx2,yyy2; xxx= (int) floor(xx); yyy= (int) floor(yy); // xxx=(int) xx; // yyy=(int) yy; //#ifdef crap if ( ! ( (lxxx==xxx)&&(lyyy==yyy) ) ) { if ((xxx>=0)&&(xxx<(alltiles.sx)*GLOBALSAMP)) if ((yyy>=0)&&(yyy<(alltiles.sy)*GLOBALSAMP)) { add=xxx+yyy*alltiles.sx*GLOBALSAMP; if ((add>=0) &&( addtilebuff.zPage) ) push_pixel(&gs->tilebuff,add,add*4,rr,gg,bb,aa,zz,layer); lxxx=xxx; lyyy=yyy; } } //#endif xx+=sx; yy+=sy; zz+=sz; rr+=sr; gg+=sg; bb+=sb; aa+=sa; } } } } return(1); } int draw_polyline2newZ(POLYDAT pp,int layer,unsigned char lum,GLOBS *gs) { int Lsclipx0, Lsclipx1, Lsclipy0, Lsclipy1; int GSxres, GSyres; int x; int y; int pagesize; //if (0==1) { // pageres = gs->rs.current_cam->xres * gs->rs.current_cam->yres; // we can assume this is a tile GSxres = gs->rs.current_cam->xres;// * GLOBALSAMP; GSyres = gs->rs.current_cam->yres;// * GLOBALSAMP; // if (pleft.xrs.Gclipx0;// * GLOBALSAMP; Lsclipy0 = gs->rs.Gclipy0;// * GLOBALSAMP; Lsclipx1 = gs->rs.Gclipx1;// * GLOBALSAMP; Lsclipy1 = gs->rs.Gclipy1;// * GLOBALSAMP; // pageres = alltiles.sx * alltiles.sy * ( int ) GLOBALSAMP *( int ) GLOBALSAMP; gs->tilebuff.cursamp=0; // ?? { float u; float d; float dx,dy,dz; float sx,sy,sz,sr,sg,sb,sa; float xx,yy,zz,rr,gg,bb,aa; dx=pp.p[1].x-pp.p[0].x; dy=pp.p[1].y-pp.p[0].y; dz=pp.p[1].z-pp.p[0].z; d=sqrt(dx*dx+dy*dy); if (d>0.0f) { xx=pp.p[0].x; yy=pp.p[0].y; zz=pp.p[0].z; sx=dx/d; sy=dy/d; sz=dz/d; for (u=0;utilebuff,add,add*4,rr,gg,bb,aa,zz,layer); if ((add>0)&&(addrs.current_cam->zPage)) if (zzrs.current_cam->zbuff[add]) gs->rs.current_cam->zbuff[add]=zz; xx+=sx; yy+=sy; zz+=sz; // rr+=sr; // gg+=sg; // bb+=sb; // aa+=sa; } } } } return(1); } static int draw_poly2newHAIRTILERS( POLYDAT pp, int layer, unsigned char lum, GLOBS *gs ) { // int triangles = 0; int x; // int success = 0; float y; int a, b; float y1; // int same = 0; float alpha; float maxy = -99999, miny = 99999; int imaxy, iminy; VERT vec1, vec2; VERT cvec1, cvec2; float a1, a2; float avec1, avec2; float abas1, abas2; VERT bas1, bas2; VERT cbas1, cbas2; VERT p1, p2, p3, p4, c1, c2, c3, c4; VERT zero; // int pageres; float tim = 0.0f; int offscreen = 0; int equal = 0; int Lsclipx0, Lsclipx1, Lsclipy0, Lsclipy1; int GSxres, GSyres; GSxres = gs->rs.current_cam->xres * GLOBALSAMP; GSyres = gs->rs.current_cam->yres * GLOBALSAMP; // if (pleft.xrs.Gclipx0 * GLOBALSAMP; Lsclipy0 = gs->rs.Gclipy0 * GLOBALSAMP; Lsclipx1 = gs->rs.Gclipx1 * GLOBALSAMP; Lsclipy1 = gs->rs.Gclipy1 * GLOBALSAMP; zero.x = 0.0f; zero.y = 0.0f; zero.z = 0.0f; vec1 = zero; vec2 = zero; cvec1 = zero; cvec2 = zero; bas1 = zero; cbas1 = zero; abas1 = 0.0f; abas2 = 0.0f; bas2 = zero; cbas2 = zero; p1 = zero; p2 = zero; c1 = zero; c2 = zero; a1 = 0.0f; a2 = 0.0f; pp.p[3] = pp.p[0]; // wrap pp.c[3] = pp.c[0]; // wrap pp.v[3] = pp.v[0]; // wrap pp.alpha[3] = pp.alpha[0]; // wrap // pageres = gs->rs.current_cam->xres * gs->rs.current_cam->yres; // pageres = alltiles.sx * alltiles.sy * ( int ) GLOBALSAMP *( int ) GLOBALSAMP; for ( x = 0; x < 4; x++ ) { { pp.p[x].x += campass[layer * 4].x; pp.p[x].y += campass[layer * 4].y; } } for( x = 0; x < 4; x++ ) { pp.p[x].x *= ( float ) GLOBALSAMP; pp.p[x].y *= ( float ) GLOBALSAMP; pp.v[x].x *= ( float ) GLOBALSAMP; pp.v[x].y *= ( float ) GLOBALSAMP; } gs->rs.current_cam->cursamp=layer; gs->tilebuff.cursamp=0; tim = 0.0f; { for( x = 0; x < 4; x++ ) { int off = 0; if( pp.p[x].y < miny ) miny = pp.p[x].y; if( pp.p[x].y > maxy ) maxy = pp.p[x].y; } imaxy = ( int ) ( maxy ); iminy = ( int ) ( miny ); { if( iminy < 0 ) iminy = 0; for( y = ( float ) iminy; y < ( float ) imaxy + 1.0f; y += 1.0f ) //<-- this was the last one { int yclip = 1; int baseadd = 0; int gbaseadd = 0; { int gclpy; int lp; lp = 0; gclpy = ( int ) ( y - Lsclipy0 ) * alltiles.sx * GLOBALSAMP; baseadd = gclpy + lp; gbaseadd = gclpy ; } y1 = y; //+campass[cursamp].y; if( ( ( y >= Lsclipy0 ) && ( y < Lsclipy1 ) ) ) yclip = 0; if( ( ( y >= gs->rs.Gclipy0 ) && ( y < gs->rs.Gclipy1 ) ) ) yclip = 0; if( yclip == 0 ) { int aa; int done = 0; a = -1; for( aa = 0; aa < 3; aa++ ) { if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas1 = pp.p[aa]; cbas1 = pp.c[aa]; abas1 = pp.alpha[aa]; vec1.x = pp.p[aa + 1].x - pp.p[aa].x; vec1.y = pp.p[aa + 1].y - pp.p[aa].y; vec1.z = pp.p[aa + 1].z - pp.p[aa].z; cvec1.x = pp.c[aa + 1].x - pp.c[aa].x; cvec1.y = pp.c[aa + 1].y - pp.c[aa].y; cvec1.z = pp.c[aa + 1].z - pp.c[aa].z; avec1 = pp.alpha[aa + 1] - pp.alpha[aa]; a = aa; done = 1; } if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas1 = pp.p[aa + 1]; cbas1 = pp.c[aa + 1]; abas1 = pp.alpha[aa + 1]; vec1.x = pp.p[aa].x - pp.p[aa + 1].x; vec1.y = pp.p[aa].y - pp.p[aa + 1].y; vec1.z = pp.p[aa].z - pp.p[aa + 1].z; cvec1.x = pp.c[aa].x - pp.c[aa + 1].x; cvec1.y = pp.c[aa].y - pp.c[aa + 1].y; cvec1.z = pp.c[aa].z - pp.c[aa + 1].z; avec1 = pp.alpha[aa] - pp.alpha[aa + 1]; a = aa; done = 1; } } done = 0; for( aa = 0; aa < 3; aa++ ) { if( aa != a ) if( done == 0 ) if( ( pp.p[aa].y <= y ) && ( pp.p[aa + 1].y >= y ) ) { bas2 = pp.p[aa]; cbas2 = pp.c[aa]; abas2 = pp.alpha[aa]; vec2.x = pp.p[aa + 1].x - pp.p[aa].x; vec2.y = pp.p[aa + 1].y - pp.p[aa].y; vec2.z = pp.p[aa + 1].z - pp.p[aa].z; cvec2.x = pp.c[aa + 1].x - pp.c[aa].x; cvec2.y = pp.c[aa + 1].y - pp.c[aa].y; cvec2.z = pp.c[aa + 1].z - pp.c[aa].z; avec2 = pp.alpha[aa + 1] - pp.alpha[aa]; b = aa; done = 1; } if( aa != a ) if( done == 0 ) if( ( pp.p[aa + 1].y <= y ) && ( pp.p[aa].y >= y ) ) { bas2 = pp.p[aa + 1]; cbas2 = pp.c[aa + 1]; abas2 = pp.alpha[aa + 1]; vec2.x = pp.p[aa].x - pp.p[aa + 1].x; vec2.y = pp.p[aa].y - pp.p[aa + 1].y; vec2.z = pp.p[aa].z - pp.p[aa + 1].z; cvec2.x = pp.c[aa].x - pp.c[aa + 1].x; cvec2.y = pp.c[aa].y - pp.c[aa + 1].y; cvec2.z = pp.c[aa].z - pp.c[aa + 1].z; avec2 = pp.alpha[aa] - pp.alpha[aa + 1]; b = aa; done = 1; } } // ok, we really want to be doing this twice .. once at the top of the scanline and once at the bottom // y1 is really the base of the scaneline, so we also want to do it for y1 + 1 too if( done != 0 ) { float bas = 0; if( vec1.y != 0.0f ) bas = ( ( y1 ) - bas1.y ) / vec1.y; // vertical interp { p1.x = bas1.x + ( vec1.x ) * bas; p1.z = bas1.z + ( vec1.z ) * bas; c1.x = cbas1.x + ( cvec1.x ) * bas; c1.y = cbas1.y + ( cvec1.y ) * bas; c1.z = cbas1.z + ( cvec1.z ) * bas; a1 = abas1 + ( avec1 ) * bas; } if( vec2.y != 0.0f ) bas = ( ( y1 ) - bas2.y ) / vec2.y; { p2.x = bas2.x + ( vec2.x ) * bas; p2.z = bas2.z + ( vec2.z ) * bas; c2.x = cbas2.x + ( cvec2.x ) * bas; c2.y = cbas2.y + ( cvec2.y ) * bas; c2.z = cbas2.z + ( cvec2.z ) * bas; a2 = abas2 + ( avec2 ) * bas; } } // ok we have a pair - now scan across // if (((int)vec1.y!=0)&&((int)vec2.y!=0)) if( done != 0 ) { VERT pleft, cleft, pright, cright; float dx = 0.0f, dz = 0.0f, aleft, aright; float cdx = 0.0f, cdy = 0.0f, cdz = 0.0f, ad; pleft = zero; pright = zero; cleft = zero; cright = zero; aleft = 0.0f; aright = 0.0f; // first sort left and right if( p1.x < p2.x ) { pleft = p1; pright = p2; cleft = c1; cright = c2; aleft = a1; aright = a2; } if( p2.x <= p1.x ) { pleft = p2; pright = p1; cleft = c2; cright = c1; aleft = a2; aright = a1; } dx = pright.x - pleft.x; if( dx != 0.0f ) { dz = ( pright.z - pleft.z ) / ( float ) dx; cdx = ( cright.x - cleft.x ) / ( float ) dx; cdy = ( cright.y - cleft.y ) / ( float ) dx; cdz = ( cright.z - cleft.z ) / ( float ) dx; ad = ( aright - aleft ) / ( float ) dx; } else // if dx==0 { dz = 0.0f; cdx = 0.0f; cdy = 0.0f; cdz = 0.0f; ad = 0.0f; } { float firstpix,lastpix; int clipx = 1; int x1; int qq2; float tt; // was here int pcount=0; int endpix; // qq2 = ( int ) ceil(pright.x); qq2 = ( int ) (pright.x); firstpix=fabs(pleft.x)-fabs(floor(pleft.x)); lastpix=fabs(pright.x)-fabs(floor(pright.x)); lastpix=1.0f-lastpix; endpix=qq2-(int)pleft.x; for( tt = ( float ) pleft.x; tt <= ( float ) ( qq2 ); tt += 1.0f ) { int clipit = 0; if( ( ( tt >= Lsclipx0 ) && ( tt <= Lsclipx1 ) ) ) { float alpha; int ok = 1; VERT pc, cc; float xx; int x2; int y2; VERT2 wpt; VERT wpt2; x = ( int ) ( tt ); x1 = ( int ) ( x ); x2 = x1; y2 = ( int ) y; // pc.x = ( float ) x; // pc.y = ( float ) ( ( int ) y ); // round it off x2 = x2 - Lsclipx0; y2 = y2 - Lsclipy0; xx = ( float ) ( tt - pleft.x ); // +campass[cursamp+layer*minsamps].x)-pleft.x; pc.z = pleft.z + dz * ( float ) xx; cc.x = cleft.x + cdx * ( float ) xx; cc.y = cleft.y + cdy * ( float ) xx; cc.z = cleft.z + cdz * ( float ) xx; alpha = aleft + ad * ( float ) xx; ok = 1; if( ok ) { int pixoff = 0; int aa4 = 1; float ftt, fy; float geomz = 1000000.0f; int geomztest = 1; int hairztest = 1; ok = 1; gs->rs.current_cam = &gs->tilebuff; if( ( int ) gs->rs.current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = gs->rs.current_cam->geombuff[gbaseadd + x2]; aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; // ok = 1; if( pc.z > geomz - .000000001 ) geomztest = 0; aa4 *= 4; if( ( gs->rs.current_cam == &LWcam ) && ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) // necesary? { ok = 0; } if( ( ( y < Lsclipy0 ) || ( y >= Lsclipy1 ) ) ) { ok = 0; } if( ( ( x1 < Lsclipx0 ) || ( x1 >= Lsclipx1 ) ) ) { ok = 0; } if( ok ) // this used to include geomz or hairz failiure { // success += 1; { if (geomztest) if( gs->rs.TILEMODE == 6 ) if( gs->rs.itsalight == 0 ) if( gs->rs.current_cam->ibuff ) { unsigned char * cppt; VERT bg; float ia; float ba; if( alpha < 0.0f ) alpha = 0.0f; if( alpha > 255.0f ) alpha = 255.0f; ia = 1.0f - ( alpha / 255.0f ); if( aa4 >= 0 ) if( ( int ) gs->rs.current_cam->ibound > aa4 + 4 ) { if (pcount==0) push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x*firstpix, cc.y*firstpix, cc.z*firstpix, alpha*firstpix, pc.z,layer); if (pcount==endpix) push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x*lastpix, cc.y*lastpix, cc.z*lastpix, alpha*lastpix, pc.z,layer); if ((pcount!=0)&&(pcount!=endpix)) push_pixel(&gs->tilebuff,baseadd+x2,aa4, cc.x, cc.y, cc.z, alpha, pc.z,layer); } } } } // ok } // plot } // pair interp pcount++; } // loop } // variable decl } // variable decl } // y>0 y .995f ) u = .995f; if( aa.hv[0].z == bb.hv[0].z ) { stp = 1; } memcpy( &ret, &aa, sizeof( BASEHAIR ) ); dx = bb.norm.x - aa.norm.x; dy = bb.norm.y - aa.norm.y; dz = bb.norm.z - aa.norm.z; ret.norm.x = aa.norm.x + dx * u; ret.norm.y = aa.norm.y + dy * u; ret.norm.z = aa.norm.z + dz * u; ret.restlength = aa.restlength * ( 1 - u ) + bb.restlength * u; ret.multasp = aa.multasp * ( 1 - u ) + bb.multasp * u; ret.offset = aa.offset * ( 1 - u ) + bb.offset * u; ret.aspect = aa.aspect * ( 1 - u ) + bb.aspect * u; ret.norm = Vnorm( ret.norm ); ret.mtl = aa.mtl; ret.handle = aa.handle; for( x = 0; x < 60; x++ ) // interpolate sliders { dx = bb.slider[x] - aa.slider[x]; ret.slider[x] = aa.slider[x] + dx * u; } ret.cutlength = ret.slider[29]; breakit = 0; if( global_segs == 5 ) stp = 3; if( aa.mtl != bb.mtl ) breakit = 1; if( aa.splitgroup != bb.splitgroup ) breakit = 1; if( ( aa.splitmerge == 1 ) && ( bb.splitmerge == 1 ) ) breakit = 0; // merge override for( x = 0; x < 15; x += stp ) { float dx, dy, dz; dx = bb.hv[x].x - aa.hv[x].x; dy = bb.hv[x].y - aa.hv[x].y; dz = bb.hv[x].z - aa.hv[x].z; du = bb.uu - aa.uu; dv = bb.vv - aa.vv; // d=distance(aa.hv[x],bb.hv[x]); // ret.color[x]=aa.color[x]; ret.hv[x].x = aa.hv[x].x + dx * u; ret.hv[x].y = aa.hv[x].y + dy * u; ret.hv[x].z = aa.hv[x].z + dz * u; dx = bb.velocity[x].x - aa.velocity[x].x; dy = bb.velocity[x].y - aa.velocity[x].y; dz = bb.velocity[x].z - aa.velocity[x].z; ret.velocity[x].x = aa.velocity[x].x + dx * u; ret.velocity[x].y = aa.velocity[x].y + dy * u; ret.velocity[x].z = aa.velocity[x].z + dz * u; dx = bb.noisev[x].x - aa.noisev[x].x; dy = bb.noisev[x].y - aa.noisev[x].y; dz = bb.noisev[x].z - aa.noisev[x].z; ret.noisev[x].x = aa.noisev[x].x + dx * u; ret.noisev[x].y = aa.noisev[x].y + dy * u; ret.noisev[x].z = aa.noisev[x].z + dz * u; ret.uu = aa.uu + du * u; ret.vv = aa.vv + dv * u; } ret.vid = aa.vid; dx = bb.restlength - aa.restlength; ret.restlength = aa.restlength + dx * u; tmphair = ret; tmphair.handle = ret.handle; memcpy( &tmphair, &ret, sizeof( BASEHAIR ) ); if( breakit == 1 ) { int qq; float toss; toss = ( float ) 1.0f - u; //(float)drand98(); toss += ( ( float ) MTdrand98( gs ) * ( float ) .6 - ( float ) .3 ); if( toss > .5 ) { ret = aa; for( qq = 0; qq < 15; qq++ ) { float uu; uu = ( float ) qq / ( float ) 15.0f; ret.hv[qq].x -= aa.hv[0].x; ret.hv[qq].y -= aa.hv[0].y; ret.hv[qq].z -= aa.hv[0].z; ret.noisev[qq].x -= aa.noisev[0].x; ret.noisev[qq].y -= aa.noisev[0].y; ret.noisev[qq].z -= aa.noisev[0].z; ret.uu -= aa.uu; ret.vv -= aa.vv; ret.hv[qq].x += tmphair.hv[0].x; ret.hv[qq].y += tmphair.hv[0].y; ret.hv[qq].z += tmphair.hv[0].z; ret.hv[qq].x = ret.hv[qq].x * ( ( float ) 1.0f - uu ) + aa.hv[qq].x * ( uu ); ret.hv[qq].y = ret.hv[qq].y * ( ( float ) 1.0f - uu ) + aa.hv[qq].y * ( uu ); ret.hv[qq].z = ret.hv[qq].z * ( ( float ) 1.0f - uu ) + aa.hv[qq].z * ( uu ); ret.noisev[qq].x = ret.noisev[qq].x * ( ( float ) 1.0f - uu ) + aa.noisev[qq].x * ( uu ); ret.noisev[qq].y = ret.noisev[qq].y * ( ( float ) 1.0f - uu ) + aa.noisev[qq].y * ( uu ); ret.noisev[qq].z = ret.noisev[qq].z * ( ( float ) 1.0f - uu ) + aa.noisev[qq].z * ( uu ); ret.handle.x = ret.handle.x * ( 1.0f - uu ) + aa.handle.x * uu; ret.handle.y = ret.handle.y * ( 1.0f - uu ) + aa.handle.y * uu; ret.handle.z = ret.handle.z * ( 1.0f - uu ) + aa.handle.z * uu; ret.uu = ret.uu * ( ( float ) 1.0f - uu ) + aa.uu * uu; ret.vv = ret.vv * ( ( float ) 1.0f - uu ) + aa.vv * uu; ret.mtl = aa.mtl; ret.multasp=aa.multasp; ret.offset=aa.offset; ret.aspect=aa.aspect; } } if( toss < .5 ) { ret = bb; for( qq = 0; qq < 15; qq++ ) { float uu; uu = ( float ) qq / ( float ) 15.0f; ret.hv[qq].x -= bb.hv[0].x; ret.hv[qq].y -= bb.hv[0].y; ret.hv[qq].z -= bb.hv[0].z; ret.noisev[qq].x -= bb.noisev[0].x; ret.noisev[qq].y -= bb.noisev[0].y; ret.noisev[qq].z -= bb.noisev[0].z; ret.hv[qq].x += tmphair.hv[0].x; ret.hv[qq].y += tmphair.hv[0].y; ret.hv[qq].z += tmphair.hv[0].z; ret.uu -= bb.uu; ret.uu += tmphair.uu; ret.vv -= bb.vv; ret.vv += tmphair.vv; ret.mtl = bb.mtl; ret.multasp=bb.multasp; ret.aspect=bb.aspect; ret.offset=bb.offset; ret.hv[qq].x = ret.hv[qq].x * ( 1.0f - uu ) + bb.hv[qq].x * ( uu ); ret.hv[qq].y = ret.hv[qq].y * ( 1.0f - uu ) + bb.hv[qq].y * ( uu ); ret.hv[qq].z = ret.hv[qq].z * ( 1.0f - uu ) + bb.hv[qq].z * ( uu ); ret.noisev[qq].x = ret.noisev[qq].x * ( ( float ) 1.0f - uu ) + bb.noisev[qq].x * ( uu ); ret.noisev[qq].y = ret.noisev[qq].y * ( ( float ) 1.0f - uu ) + bb.noisev[qq].y * ( uu ); ret.noisev[qq].z = ret.noisev[qq].z * ( ( float ) 1.0f - uu ) + bb.noisev[qq].z * ( uu ); ret.handle.x = ret.handle.x * ( 1.0f - uu ) + bb.handle.x * uu; ret.handle.y = ret.handle.y * ( 1.0f - uu ) + bb.handle.y * uu; ret.handle.z = ret.handle.z * ( 1.0f - uu ) + bb.handle.z * uu; ret.uu = ret.uu * ( ( float ) 1.0f - uu ) + bb.uu * uu; ret.vv = ret.vv * ( ( float ) 1.0f - uu ) + bb.vv * uu; } } } return ( ret ); } static int camspace_clipitLINERS( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */,GLOBS *gs ) { // struct // { // VERT v; // VERT w; // VERT color; // float alpha; // VERT vel; // } list1[2] , list2[2], *inList, *outList, *listTemp; int inCount; int pl; int clipoff = 0; int totalp = 0; int x; VERT nrm; VERT pln; float zoomFactor; // // Put the starting poly into list1. // // for( x = 0; x < 2; x++) // { // // list1[x].v = pp->p[x]; // list1[x].w = pp->w[x]; // list1[x].alpha = pp->alpha[x]; // list1[x].color = pp->c[x]; // list1[x].vel = pp->v[x]; // } inCount = 2; // inList = list1; // outList = list2; // // Get the camera normal and position of the near clipping plane. // // %%% We could speed things up a bit more if these were only // calculated once per camera, rather than recalculating them for // every poly. But that would require a code reorganization // beyond what I'm willing to tackle right now, and it's not clear // that the performance gain would be significant. // nrm.x = gs->rs.current_cam->view[0][2]; nrm.y = gs->rs.current_cam->view[1][2]; nrm.z = gs->rs.current_cam->view[2][2]; nrm = Vnorm( nrm ); //#ifdef MAX3D if( gs-> rs.itsalight == 1 ) zoomFactor = gs->rs.current_cam->zoom * 18.01f; // flicker was .01 if( gs->rs.itsalight != 1 ) zoomFactor = gs->rs.current_cam->zoom * 1.01f; // flicker was .01 zoomFactor = gs->rs.current_cam->zoom * gs->rs.current_cam->nearclip; // flicker was .01 //#endif #ifndef MAX3D if( gs->rs.itsalight == 1 ) zoomFactor = gs-> rs.current_cam->zoom * 1.01f; // flicker was .01 if( gs->rs.itsalight != 1 ) zoomFactor = gs->rs.current_cam->zoom * 0.01f; // flicker was .01 #endif // zoomFactor = gs->rs.current_cam- >zoom * .01f; pln.x = gs->rs.current_cam->wpos.x + nrm.x * zoomFactor; pln.y = gs->rs.current_cam->wpos.y + nrm.y * zoomFactor; pln.z = gs->rs.current_cam->wpos.z + nrm.z * zoomFactor; for( pl = 0; pl <= 4; pl++ ) // cycle through all the clip planes { { int xx; int reject = 0; for( x = 0; x < 2; x++ ) // <1 ? { float dd = 0.0f, td = 0.0f, perc = 0.0f; int st1 = 0, st2 = 0; int x1 = 0; // x1 = ( x + 1 ) % 1; x1=1; if (x==1) x1=0; if( pl == 0 ) // Near clipping plane. { float dr1, dr2; VERT vc1, vc2; VERT ca, ba; float cad, bad; vc1.x = pp->w[x].x - pln.x; vc1.y = pp->w[x].y - pln.y; vc1.z = pp->w[x].z - pln.z; vc1 = Vnorm( vc1 ); dr1 = VDot( vc1, nrm ); vc2.x = pp->w[x1].x - pln.x; vc2.y = pp->w[x1].y - pln.y; vc2.z = pp->w[x1].z - pln.z; vc2 = Vnorm( vc2 ); dr2 = VDot( vc2, nrm ); st1 = ( dr1 <= 0 ); st2 = ( dr2 <= 0 ); if( st1 && st2 ) { return 0; } else { // if (st2) // if( !st1 ) if( !st1 && st2 ) { ca.x = pln.x - pp->w[x].x; ca.y = pln.y - pp->w[x].y; ca.z = pln.z - pp->w[x].z; ba.x = pp->w[x1].x - pp->w[x].x; ba.y = pp->w[x1].y - pp->w[x].y; ba.z = pp->w[x1].z - pp->w[x].z; cad = VDot( ca, nrm ); bad = VDot( ba, nrm ); if( bad != 0 ) { perc = cad / bad; perc = fabs( perc ); } else perc = 0.0f; pp->w[x1].x = pp->w[x].x + ( pp->w[x1].x - pp->w[x].x ) * perc; pp->w[x1].y = pp->w[x].y + ( pp->w[x1].y - pp->w[x].y ) * perc; pp->w[x1].z = pp->w[x].z + ( pp->w[x1].z - pp->w[x].z ) * perc; // wait I think I need to get a new projection // on this point pp->p[x1] = world2cam1( gs->rs.current_cam, (pp->w[x1]) ); pp->alpha[x1] = pp->alpha[x] + ( pp->alpha[x1] - pp->alpha[x] ) * perc; pp->c[x1].x = pp->c[x].x + ( pp->c[x1].x - pp->c[x].x ) * perc; pp->c[x1].y = pp->c[x].y + ( pp->c[x1].y - pp->c[x].y ) * perc; pp->c[x1].z = pp->c[x].z + ( pp->c[x1].z - pp->c[x].z ) * perc; pp->v[x1].x = pp->v[x].x + ( pp->v[x1].x - pp->v[x].x ) * perc; pp->v[x1].y = pp->v[x].y + ( pp->v[x1].y - pp->v[x].y ) * perc; pp->v[x1].z = pp->v[x].z + ( pp->v[x1].z - pp->v[x].z ) * perc; } } } else { switch ( pl ) { case 1: // Top clipping plane st1 = ( pp->p[x].y >= ys ); st2 = ( pp->p[x1].y >= ys ); if( st1 && st2 ) { return 0; } else if( !st1 && st2 ) { // // The endpoints are on opposite sides of the // clipping plane, so we must calculate the // intersection point and add it to the // output list. // dd = ys - pp->p[x].y; td = pp->p[x1].y - pp->p[x].y; } break; case 2: // Right clipping plane. st1 = ( pp->p[x].x >= xs ); st2 = ( pp->p[x1].x >= xs ); if( st1 && st2 ) { return 0; } else if( !st1 && st2 ) { dd = xs - pp->p[x].x; td = pp->p[x1].x - pp->p[x].x; } break; case 3: // Bottom clipping plane st1 = ( pp->p[x].y < yl ); st2 = ( pp->p[x1].y < yl ); if( st1 && st2 ) { return 0; } else if( !st1 && st2 ) { dd = yl - pp->p[x].y; td = pp->p[x1].y - pp->p[x].y; } break; case 4: // Left clipping plane st1 = ( pp->p[x].x < xl ); st2 = ( pp->p[x1].x < xl ); if( st1 && st2 ) { return 0; } else if( !st1 && st2 ) { dd = xl - pp->p[x].x; td = pp->p[x1].x - pp->p[x].x; } break; } // if (st2) // if( !st1 ) // if (fabs(td)>0) if( !st1 && st2 ) { // // Here's the old code: // // perc = 0.0f; // // if (td != 0.0f) perc= dd / td; // // I don't think that we need the zero // check, though. We know that one y value // is >= ys and the other < ys, so they // cannot be the same, so td cannot be // zero. // // The only possibility would be if the // subtraction of the two rounds to zero, // but I don't think that that can happen // on any known floating-point // architecture. // perc = dd / td; // // Here's the old code: // // perc = fabs(perc); // // I don't think it is necessary. // // If the y-value of the first point is // greater than that of the second, then // both dd and td will be positive and so // will the result of the division. // // If the y-value of the first point is // less than that of the second, then both // dd and td will be negative, making the // result of the division once again // positive. // // So 'perc' will always be positive even // without this call. // pp->p[x1].x = pp->p[x].x + ( pp->p[x1].x - pp->p[x].x ) * perc; pp->p[x1].y = pp->p[x].y + ( pp->p[x1].y - pp->p[x].y ) * perc; pp->p[x1].z = pp->p[x].z + ( pp->p[x1].z - pp->p[x].z ) * perc; pp->w[x1].x = pp->w[x].x + ( pp->w[x1].x - pp->w[x].x ) * perc; pp->w[x1].y = pp->w[x].y + ( pp->w[x1].y - pp->w[x].y ) * perc; pp->w[x1].z = pp->w[x].z + ( pp->w[x1].z - pp->w[x].z ) * perc; pp->alpha[x1] = pp->alpha[x] + ( pp->alpha[x1] - pp->alpha[x] ) * perc; pp->c[x1].x = pp->c[x].x + ( pp->c[x1].x - pp->c[x].x ) * perc; pp->c[x1].y = pp->c[x].y + ( pp->c[x1].y - pp->c[x].y ) * perc; pp->c[x1].z = pp->c[x].z + ( pp->c[x1].z - pp->c[x].z ) * perc; pp->v[x1].x = pp->v[x].x + ( pp->v[x1].x - pp->v[x].x ) * perc; pp->v[x1].y = pp->v[x].y + ( pp->v[x1].y - pp->v[x].y ) * perc; pp->v[x1].z = pp->v[x].z + ( pp->v[x1].z - pp->v[x].z ) * perc; } } // case (pl) } // x (points) // listTemp = inList; // inList = outList; // outList = listTemp; } // if (clipoff == 0) } // for (pl) // // The result will be sitting in 'inList', so copy that into POLYDAT. // return 1; } static void fetch_hairRS( int xx, float t,GLOBS *gs ) { int yy, zz, x, y; int oldContext = RW_CONTEXT; gs->rs.nodeID=xx; RW_CONTEXT = RW_LOCAL; global_lastID = -1; hairfiles[xx].pos = 0; hairstate[xx].pos = 0; // hairfiles[xx].time = t; // hairstate[xx].time = t; if( hairfiles[xx].data ) read_hair( &hairfiles[xx] ); else free_MEMFILE( &hairfiles[xx] ); if( hairstate[xx].data ) read_state_machine( &hairstate[xx] ); else free_MEMFILE( &hairstate[xx] ); // clear these out GnodeID = xx; // this is a stack ID not a hair ID gt = hairstate[xx].time; // if (DEGENERATE_OBJECT==1) { // freeverts();Dfreeverts(); // free_MEMFILE(&hairstate[xx]); // free_MEMFILE(&hairfiles[xx]); // } mkbounds( ); reset_faces( ); checkforzero( ); make_normals( ); for( x = 0; x < totalverts; x++ ) hair[x].norm = vn[x]; // for (x=0;x 0 ) if( LOCAL_PASSES[yy] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[yy]; } for( yy = 0; yy < totalverts; yy++ ) for( zz = 0; zz < 15; zz++ ) { hair[yy].velocity[zz].x = hair[yy].hv[zz].x - hair[yy].lasthv[zz].x; hair[yy].velocity[zz].y = hair[yy].hv[zz].y - hair[yy].lasthv[zz].y; hair[yy].velocity[zz].z = hair[yy].hv[zz].z - hair[yy].lasthv[zz].z; hair[yy].hv[zz] = hair[yy].lasthv[zz]; } for( yy = 0; yy < total_splines; yy++ ) { for( zz = 0; zz < 15; zz++ ) { Shair[yy].hv[zz] = Slasthair[yy].hv[zz]; Shair[yy].velocity[zz].x = Sthishair[yy].hv[zz].x - Slasthair[yy].hv[zz].x; Shair[yy].velocity[zz].y = Sthishair[yy].hv[zz].y - Slasthair[yy].hv[zz].y; Shair[yy].velocity[zz].z = Sthishair[yy].hv[zz].z - Slasthair[yy].hv[zz].z; } } hairfiles[xx].pos = 0; hairstate[xx].pos = 0; RW_CONTEXT = oldContext; } int radius_killRS(float input_radius, VERT vvv,GLOBS *gs) { VERT2 tm; float rad=1.0f; float gss; float d; float r2; float coin; tm.x = vvv.x; tm.y = vvv.y; tm.z = vvv.z; tm = world2camRS( gs->rs.current_cam, tm,gs ); tm.x += 1.0f; ///(float)current_cam->xres; tm = cam2world( gs->rs.current_cam, tm ); tm.x -= vvv.x; tm.y -= vvv.y; tm.z -= vvv.z; // gss = 1.0f / ( float ) GLOBALSAMP; gss = 1.0f; gss/=2.0f; d = sqrt( tm.x * tm.x + tm.y * tm.y + tm.z * tm.z ); // pixel span if( d != 0 ) rad /= d; else rad = 0; r2=input_radius*rad; if( gs->rs.itsalight == 0 ) if( r2 < gss ) { if (r2 < gss) // itsaline = 1; r2 = gss; } coin=MTdrand98(gs); // fprintf (stdout,"r2=%f\n",r2);fflush(stdout); //MTJsrand(gs->lastSeed,gs); if (gs->rs.itsalight) return(0); if (r2