// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include "lotswfROOTRS.c" extern void MAYAmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE * ret, CURVEINFO * cret ) { VERT offs; WFTYPE geom; int segs = 1; 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; global_segs = 56; 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; //if (freeze.totalverts==0) // if( LOCAL_PASSES[slg] > 0 ) // current_samp = current_samp % LOCAL_PASSES[slg]; // GhairID = hairnum; // Gpass = current_samp; cret->depthpass = current_samp; cret->hairID = hairnum; // cursamp=current_samp; if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) // if( LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; // clones = // make_spline_hair( slg, hairnum, 0, 3, &geom, // cret ); clones = make_spline_hairROOT( slg, hairnum, 0, segs, &geom, cret ); // cret->killme=0; // I don't think we ever want to kill roots - do we? // printf("geom.totalverts=%d\n",geom.totalverts); // printf(" slg->%d\n",slg); // fflush(stderr); if( cret->killme == 0 ) { if( clones == 0 ) clones = 1; ret->totalverts = ( clones + 1 ); ret->totalfverts = ( clones + 1 ); ret->totalfaces = ( clones + 1 ); if( ret->totalverts > 0 ) alloc_geomWF( ret ); if( clones == 0 ) clones = 1; ret->totalverts = clones; ret->totalfverts = clones; ret->totalfaces = clones; for( x = 0; x < clones; x++ ) { ret->v[x] = geom.v[0]; ret->facelist[x] = x; ret->face_start[x] = x; ret->face_end[x] = x + 1; ret->v[x].z *= -1.0f; ret->uv[x].x = cret->u; ret->uv[x].y = cret->v; ret->uv[x].z = 0.0f; ret->color[x] = geom.color[0]; } } free_geomWF( &geom ); // free_geom(&geom); } cret->depthpass = current_samp; cret->hairID = hairnum; } static int make_spline_hairROOT( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ) { VERT offs; int index = 0; // float rr; // int x; BASEHAIR lowhair; init_a_hair( &lowhair ); //static BASEHAIR hh[1]; ////WFTYPE tmpwf; global_segs = 56; //// 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]= draw_lotsWFROOT( slg, hairnum, offs, clone, &lowhair, cinfo,cinfo->depthpass ); } // 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; init_geomWF( geom ); free_geomWF( geom ); //if (lowhair.killme==1) printf ("killed\n");// // don't actually kill it if( cinfo->killme == 0 ) // if (lowhair.restlength>0) { int xx; //geom will get allocated in here? ///resize_base_hair(&lowhair,geom,cinfo,segs); // no need geom->totalverts = 1; //segs geom->totalfaces = 1; geom->totalfverts = 1; // segs alloc_geomWF( geom ); geom->v[0] = lowhair.hv[0]; for( xx = 0; xx < 1; xx++ ) geom->facelist[xx] = xx; geom->face_start[0] = 0; geom->face_end[0] = 1; if( lowhair.cutlength == 0 ) cinfo->killme = 1; //mk_spline_geom(&hh[0], geom, segs); } if( cinfo->killme ) { free_geomWF( geom ); geom->totalverts = 0; lowhair.dreadcount = 0; cinfo->killme = 1; init_geomWF( geom); } return ( ( int ) lowhair.dreadcount ); } void MTdraw_lotsWFROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp,GLOBS * gs ) { // BASEHAIR rtt[20]; int nokink = 1; int pd; int pqp; static float jfloat; // BASEHAIR hh[20]; float ascalh, ascalr; VERT t1[15], t2[15]; int qv; VERT xv, yv, zv, b; int pid = 0; int killit = 0; BASEHAIR h; float d1 = 1.0, d2 = 1.0f; BASEHAIR hrest; int x; int cc; int cc2; int cloneON = 0; static int chk = 1; static int lp; int index; int indx; //int samp; cinfo->shadowHair = 1; if( ind > LOCAL_SHADCNT[slg] ) cinfo->shadowHair = 0; init_a_hair( &hrest ); init_a_hair( &h ); cloneON=0; clone=0; cc2=samp; cc=samp; h.killme = 0; cinfo->killme = 0; h.killme = 0; hrest.killme = 0; cinfo->killme = 0; killit = 0; hrest.killme = 0; cinfo->killme = 0; cinfo->diff = 0.0f; cinfo->kspec = 0.0f; cinfo->norm.x = 0.0f; cinfo->norm.y = 1.0f; cinfo->norm.z = 0.0f; cinfo->shad = 0.0f; cinfo->spec = 0.0f; cinfo->tiprad = 0.0f; cinfo->baserad = 0.0f; // cinfo->hairID = gs->GhairID; cinfo->hairID = ind; cinfo->nodeID = GnodeID; // cinfo->depthpass = gs->passnumber; cinfo->depthpass = cc; cinfo->ambient = 0.0f; cinfo->restlength = 0.0f; cinfo->cutlength = 0.0f; cinfo->mtl = slg; cinfo->u = 0; cinfo->v = 0; cinfo->u2 = 0; cinfo->v2 = 0; x = ind; gs->random_seed_offset=Grandom_seed_offset; cloneON=0; clone=0; samp=0; { int cll; cll=sliders[25][slg].value; if (cll==0) cll=1; indx=ind; if (clone>0) indx= ind*cll+clone+cll*samp*LOCAL_CNT[slg]*LOCAL_PASSES[slg]; } hrest.hairnumber=x; chk=1; MTJsrand(ind,gs); { float rand1; float rand2; rand1 = ( float ) MTdrand98( gs ); rand2 = ( float ) MTdrand98( gs ); for( pd = 0; pd < ( int ) ( 37. * rand1 + 10. * cc * rand2 ); pd++ ) { float jjunk; jjunk = ( float ) MTdrand98( gs ); } } { if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) { if( slg == 4 ) pid = (int)( floor ) ( ( float ) MTdrand98( gs ) * ( ( double ) total_slgfaces[slg] - 1 ) - .000001f ); // pid=(floor)((float)MTdrand98(gs)*((double)total_slgfaces[slg]-1)-.000001f); if( slg != 4 ) { int rp = 0; rp = ( int ) ( ( float ) MTdrand98( gs ) * ( ( double ) total_slgfaces[slg] ) - .000001f ); if( rp > total_slgfaces[slg] - 1 ) rp = total_slgfaces[slg] - 1; pid = slgfaces[slg][rp]; } // if (slg!=4) if( total_slgfaces[slg] > 0 ) if( pid > total_slgfaces[slg] - 1 ) pid = total_slgfaces[slg] - 1; // pid = slgfaces[slg][pid]; chk = 1; if( killit == 0 ) if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( slg != 4 ) { while( ( MTcheckface( pid, gs ) == 0 ) ) //||(pid==total_slgfaces[slg])) { int rp; rp = ( int ) ( ( float ) MTdrand98( gs ) * ( ( double ) total_slgfaces[slg] ) - .000001f ); if( rp > total_slgfaces[slg] - 1 ) rp = total_slgfaces[slg] - 1; pid = slgfaces[slg][rp]; } } } } if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) { int lp; lp = LOCAL_PASSES[slg]; //lp-=1;if (lp<1) lp=1; // MTJsrand( ( unsigned long ) ( ind * 11 + cc * 6555 ), gs ); mixitup( ); killit = 0; cinfo->killme = 0; MTJsrand(ind,gs); //Pid=0; mixitup( ); hrest.hairnumber=x; #ifdef threadiness if( cachemode == PLAYBACK_CACHE ) { hrest = MTgen_resthair_ROOT( pid, slg, cinfo, gs ); hrest.killme = 0; cinfo->killme = 0; killit = 0; } else #endif hrest = MTgen_resthair_ROOT( pid, slg, cinfo, gs ); { int qq; for( qq = 0; qq < 2; qq++ ) hrest.hv[qq] = hrest.noisev[qq]; } hrest.killme = 0; cinfo->killme = 0; killit = 0; hrest.pid = pid; // d1 = ascalr; // d2 = ascalh; //MTJsrand(indx,gs); // was here //MTcolor_a_hair(&hrest,gs); pqp=LOCAL_PASSES[slg]; if (pqp<1) pqp=1; #ifdef threadiness if (ind= 0 ) { // Gtex_info[qq] = Gtex_cacheinfo[GnodeID][slg][tt + samp * Gtex_totalchannels[GnodeID][slg] + Gtex_totalchannels[GnodeID][slg] * ind * Gshavep[GnodeID].passes[slg]]; Gtex_info[qq] = Gtex_cacheinfo[GnodeID][slg][tt + Gtex_totalchannels[GnodeID][slg] * ind]; tt++; } } } { int pp; if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 1 ) for( pp = 0; pp < 60; pp++ ) { int tt; hrest.slider[pp] = Gtex_info[pp]; } } } else #endif { int pp; for( pp = 0; pp < 60; pp++ ) { int tt; hrest.slider[pp] = 1; } } mixitup( ); hrest.hairnumber=x; hrest.index=x; #ifdef threadiness if (indmtl = slg; cinfo->groupID = slg; if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 0 ) for( pp = 0; pp < 60; pp++ ) { hrest.slider[pp] = SHAVEapply_texture( cinfo, hrest.noisev[0], SHAVEID, pp, hrest.slider[pp] ); } if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 1 ) for( pp = 0; pp < 60; pp++ ) //-= if( Gtex_info[pp] >= 0.0f ) { hrest.slider[pp] = Gtex_info[pp]; } // if( cloneON == 0 ) /// MTJsrand( ( unsigned long ) ( ind * 11 + cc * 6555 ), gs ); // else // MTJsrand( ( unsigned long ) ( ind * 11 ), gs ); MTJsrand (indx,gs); mixitup( ); hrest.hairnumber=x; MTcolor_a_hair( &hrest, gs ); } } #endif MTJsrand(indx,gs); MTcolor_a_hair(&hrest,gs); memcpy( outhair, &hrest, sizeof( BASEHAIR ) ); } } void MTdraw_lotsWFRSROOTREST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, int samp,GLOBS * gs ) { // BASEHAIR rtt[20]; int nokink = 1; int pd; static float jfloat; float lGtex_info[60]; // BASEHAIR hh[20]; float ascalh, ascalr; VERT t1[15], t2[15]; int qv; VERT xv, yv, zv, b; int pid = 0; int killit = 0; BASEHAIR h; float d1 = 1.0, d2 = 1.0f; BASEHAIR hrest; int x; int cc; int cc2; int cloneON = 0; int pqp; static int chk = 1; static int lp; int indx; VERT lGdisplace; samp=0; cinfo->shadowHair = 1; if( ind > gs->rs.LOCAL_SHADCNT[slg] ) cinfo->shadowHair = 0; init_a_hair( &hrest ); init_a_hair( &h ); if( gs->rs.sliders[25][slg].value > 0 ) cloneON = 1; //cloneON=0; //clone=0; cc2=0; cc=0; cc=samp; cc2=samp; gs->Gcurpass=samp; cinfo->depthpass = cc2; h.killme = 0; cinfo->killme = 0; ascalr = 1.0f; ascalh = ascalr; h.killme = 0; hrest.killme = 0; cinfo->killme = 0; killit = 0; // Gslg = slg; hrest.killme = 0; cinfo->killme = 0; cinfo->diff = 0.0f; cinfo->kspec = 0.0f; cinfo->norm.x = 0.0f; cinfo->norm.y = 1.0f; cinfo->norm.z = 0.0f; cinfo->shad = 0.0f; cinfo->spec = 0.0f; cinfo->tiprad = 0.0f; cinfo->baserad = 0.0f; // cinfo->hairID = gs->GhairID; cinfo->hairID = ind; cinfo->nodeID = gs->rs.nodeID; // cinfo->depthpass = gs->passnumber; // cinfo->depthpass = gs->cursamp; cinfo->ambient = 0.0f; cinfo->restlength = 0.0f; cinfo->cutlength = 0.0f; cinfo->mtl = slg; cinfo->u = 0; cinfo->v = 0; cinfo->u2 = 0; cinfo->v2 = 0; x = ind; pqp=gs->rs.LOCAL_PASSES[slg]; if (pqp<1) pqp=1; //cloneON=0; //clone=0; { int cll; cll=gs->rs.sliders[25][slg].value; if (cll==0) cll=1; indx= ind*cll+clone+cll*samp*gs->rs.LOCAL_CNT[slg]*gs->rs.LOCAL_PASSES[slg]; } hrest.hairnumber=x; chk=1; MTJsrand(ind,gs); { float rand1; float rand2; rand1 = ( float ) MTdrand98( gs ); rand2 = ( float ) MTdrand98( gs ); for( pd = 0; pd < ( int ) ( 37. * rand1 + 10. * cc * rand2 ); pd++ ) { float jjunk; jjunk = ( float ) MTdrand98( gs ); } } { if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) { if( slg == 4 ) pid = (int)( floor ) ( ( float ) MTdrand98( gs ) * ( ( double ) gs->rs.total_slgfaces[slg] - 1 ) - .000001f ); // pid=(floor)((float)MTdrand98(gs)*((double)total_slgfaces[slg]-1)-.000001f); if( slg != 4 ) { int rp = 0; rp = ( int ) ( ( float ) MTdrand98( gs ) * ( ( double ) gs->rs.total_slgfaces[slg] ) - .000001f ); if( rp > gs->rs.total_slgfaces[slg] - 1 ) rp = gs->rs.total_slgfaces[slg] - 1; pid = gs->rs.slgfaces[slg][rp]; } // if (slg!=4) if( gs->rs.total_slgfaces[slg] > 0 ) if( pid > gs->rs.total_slgfaces[slg] - 1 ) pid = gs->rs.total_slgfaces[slg] - 1; // pid = slgfaces[slg][pid]; chk = 1; if( killit == 0 ) if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) if( slg != 4 ) { while( ( MTcheckfaceRS( pid, gs ) == 0 ) ) //||(pid==total_slgfaces[slg])) { int rp; rp = ( int ) ( ( float ) MTdrand98( gs ) * ( ( double ) gs->rs.total_slgfaces[slg] ) - .000001f ); if( rp > gs->rs.total_slgfaces[slg] - 1 ) rp = gs->rs.total_slgfaces[slg] - 1; pid = gs->rs.slgfaces[slg][rp]; } } } } if( gs->rs.total_slgfaces[slg] > 0 ) if( gs->rs.LOCAL_CNT[slg] > 0 ) { int lp; lp = gs->rs.LOCAL_PASSES[slg]; //lp-=1;if (lp<1) lp=1; MTJsrand( ( unsigned long ) ( ind * 11 + cc * 6555 ), gs ); mixitup( ); killit = 0; cinfo->killme = 0; MTJsrand(ind,gs); mixitup( ); hrest.hairnumber=x; hrest.index=x; if( cachemode == PLAYBACK_CACHE ) { hrest = MTgen_resthair_ROOTRS( pid, slg, cinfo, gs ); hrest.killme = 0; cinfo->killme = 0; killit = 0; } else hrest = MTgen_resthair_ROOTRS( pid, slg, cinfo, gs ); { int qq; for( qq = 0; qq < 2; qq++ ) hrest.hv[qq] = hrest.noisev[qq]; } hrest.killme = 0; cinfo->killme = 0; killit = 0; hrest.pid = pid; // d1 = ascalr; // d2 = ascalh; MTJsrand(indx,gs); MTcolor_a_hairRS( &hrest, gs ); MTJsrand(ind,gs); #ifdef threadiness if (indrs.LOCAL_CNT[slg]*pqp) if( TEXCACHEMODE == 1 ) { int qq; int tt = 0; // Gdisplace = Gtex_cachedisplace[gs->rs.nodeID][slg][ind + gs->Gcurpass * Gshavep[gs->rs.nodeID].haircount[slg]]; lGdisplace = Gtex_cachedisplace[gs->rs.nodeID][slg][ind ]; for( qq = 0; qq < 60; qq++ ) { lGtex_info[qq] = 1.0f; tt = Gtex_channellink[gs->rs.nodeID][qq]; if( Gtex_channellink[gs->rs.nodeID][qq] >= 0 ) { // Gtex_info[qq] = Gtex_cacheinfo[gs->rs.nodeID][slg][tt + gs->Gcurpass * Gtex_totalchannels[gs->rs.nodeID][slg] + Gtex_totalchannels[gs->rs.nodeID][slg] * ind * Gshavep[gs->rs.nodeID].passes[slg]]; lGtex_info[qq] = Gtex_cacheinfo[gs->rs.nodeID][slg][tt + Gtex_totalchannels[gs->rs.nodeID][slg] * ind]; } } } { int pp; if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 1 ) for( pp = 0; pp < 60; pp++ ) { int tt; hrest.slider[pp] = lGtex_info[pp]; } } if( TEXCACHEMODE != 1 ) #endif { int pp; for( pp = 0; pp < 60; pp++ ) { int tt; hrest.slider[pp] = 1.0f; } } mixitup( ); hrest.hairnumber=x; #ifdef threadiness if (indrs.LOCAL_CNT[slg]*pqp) { if( cachemode != PLAYBACK_CACHE ) { mixitup( ); { int pp; cinfo->mtl = slg; cinfo->groupID = slg; if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 0 ) for( pp = 0; pp < 60; pp++ ) { hrest.slider[pp] = SHAVEapply_texture( cinfo, hrest.hv[0], gs->rs.SHAVEID, pp, hrest.slider[pp] ); } if( DOING_SWATCH == 0 ) if( TEXCACHEMODE == 1 ) for( pp = 0; pp < 60; pp++ ) //-= if( Gtex_info[pp] >= 0.0f ) { hrest.slider[pp] = lGtex_info[pp]; } // if( cloneON == 0 ) // MTJsrand( ( unsigned long ) ( ind * 11 + cc * 6555 ), gs ); // else // MTJsrand( ( unsigned long ) ( ind * 11 ), gs ); MTJsrand(indx,gs); mixitup( ); hrest.hairnumber=x; MTcolor_a_hairRS( &hrest, gs ); } } } else #endif { MTJsrand(indx,gs); mixitup( ); hrest.hairnumber=x; MTcolor_a_hairRS( &hrest, gs ); } } memcpy( outhair, &hrest, sizeof( BASEHAIR ) ); }