// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 static int draw_a_curveLine2( WFTYPE * wf, CURVEINFO * h, int cs ); static void camspace_clipit( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ); int cache_poly( POLYDAT tri, int xx ); static int draw_a_curve2( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ); static int check_curve( CURVEINFO * hp, WFTYPE * wf ); static int tag_a_curve2( WFTYPE * wf, CURVEINFO * h, int cs ); //void lineDraw(int x0, int y0, int x1, int y1, Color color); //#include "gui_obsolete.c" double drand98( void ); static void IdleFunc( void ); // GLOBALS static void DRAW_STATUS(char name[655]) { } static int draw_a_curve( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ); static int draw_a_bunch( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ) { int x,lid; int mult=0; int y; //int fce; int fce; int q; WFTYPE smll; mult=(int)sliders[25][Gslg].value; if (mult==0) mult=1; init_geomWF(&smll); y=0; //for (y=0;ytotalfaces;y+=mult) // ok we're making assumptions about multipliers here. while (ytotalfaces) { int face; int f=0; int q; int curID; int done=0; mult=0; q=y; curID=wf->id[q]; if (q>=0) while (done==0) { q++; mult++; if (q>=wf->totalfaces) done=1; // BUG scenes with few hairs + shadows will crash without this change if (q>=0) if (qtotalfaces) // BUG scenes with few hairs + shadows will crash without this change if (wf->id[q]!=curID) done=1; } if (mult==0) mult=1; smll.totalverts=(LOCAL_SEGS[Gslg]+3)*mult; smll.totalfverts=(LOCAL_SEGS[Gslg]+3)*mult; smll.totalfaces=mult; alloc_geomWF(&smll); smll.totalverts=0; smll.totalfaces=0; smll.totalfverts=0; f=0; for (fce=y;fceface_start[fce];gface_end[fce];g++) { int gg; gg=wf->facelist[g]; smll.v[smll.totalverts]=wf->v[gg]; smll.uv[smll.totalverts]=wf->uv[gg]; smll.color[smll.totalverts]=wf->color[gg]; smll.vn[smll.totalverts] = wf->vn[ gg ]; smll.velocity[smll.totalverts]=wf->velocity[gg]; smll.alpha[smll.totalverts]=wf->alpha[gg]; smll.facelist[smll.totalverts]=smll.totalverts; smll.totalverts++; smll.totalfverts++; } smll.face_start[f]=ft; smll.face_end[f]=smll.totalfverts; smll.id[f]=wf->id[fce]; smll.totalfaces++; smll.r1[f]=wf->r1[fce]; smll.r2[f]=wf->r2[fce]; h->baserad=wf->r1[fce]; h->tiprad=wf->r2[fce]; f++; } { int g; for (g=0;ghairID=GhairID; h->shaveID=SHAVEID; h->nodeID=GnodeID; h->cutlength=1.0f; h->groupID=Gslg; h->killme=0; h->mtl=Gslg; //TILEMODE=2; //printf ("draw a curve %d\n",GhairID);fflush(stdout); for( q = 0; q < smll.totalverts; q++ ) { smll.v[q].z = -smll.v[q].z; smll.velocity[q].z = -smll.velocity[q].z; smll.vn[q].z = -smll.vn[q].z; } //printf ("id = %d smll.totalverts = %d smll.totalfaces= %d\n",smll.id[0],smll.totalverts,smll.totalfaces);fflush(stdout); draw_a_curve( &smll, h, cs, curtile ); free_geomWF(&smll); y+=mult; } free_geomWF(wf); return(1); } static int draw_a_curve( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ) { int doit = 0; if( TILEMODE != 0 ) { if( TILEMODE < 6 ) { // tagging itsalight = 3; ///AAAAA current_cam = &LWcam; Gclipx0 = 0; Gclipx1 = LWcam.xres; Gclipy0 = 0; Gclipy1 = LWcam.yres; //printf ("draw a curve cs=%d\n",cs);fflush(stdout); doit = tag_a_curve2( wf, h, cs ); } if( TILEMODE == 6 ) { // itsalight=3; ///AAAAA // doit=draw_a_curve2(wf,h,cs); // itsalight=0; // if (doit>0) itsalight = 0; // draw_a_curveLine2(wf,h, cs); draw_a_curve2( wf, h, cs, curtile ); // draw_a_clumpCP2(h,cs); } } if( TILEMODE == 0 ) { if( itsalight == 0 ) { current_cam = &LWcam; // itsalight=3; ///AAAAA // doit=draw_a_curve2(wf,h,cs); itsalight = 0; // if (doit>0) tag_a_curve2( wf, h, cs ); // draw_a_clumpCP2(h,cs); } if( itsalight == 1 ) { int x; TILEMODE = 0; for( x = 0; x < totallights; x++ ) if( LWlight[x].xres > 0 ) { current_cam = &LWlight[x]; // draw_a_curveLine2(wf,h, cs); draw_a_curve2( wf, h, cs, 0 ); } // draw_a_clumpCP2(h,cs); } } return ( doit ); } static int draw_a_curve2( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ) { int success = 0; WFTYPE fh; WFTYPE hh; int totalhv = 0; float rad; float lastrad; VERT2 tm; int x; float d; int last = 0; int slg = 0; int stp; VERT lastaa; float *fhwidth = NULL; int docurve = 0; int *clip = NULL; VERT *dvert2 = NULL; float *alphamult; float hss; int *smallish; float passes=1.0f; if( wf->totalverts > 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; if( h->cutlength != 0 ) //if (h->killme==0) { float gs; int itsaline = 0; gs = 1.0f / ( float ) GLOBALSAMP; if (itsalight==1) gs= .75; if( head >= 0 ) if( h->mtl == head ) slg = 0; if( beard >= 0 ) if( h->mtl == beard ) slg = 1; if( eyebrow >= 0 ) if( h->mtl == eyebrow ) slg = 2; if( eyelash >= 0 ) if( h->mtl == eyelash ) slg = 3; if( splines >= 0 ) if( h->mtl == splines ) slg = 4; // h->ambient=sliders[7][slg].value*h->slider[7]; cs = cs % LOCAL_PASSES[slg]; passes=(float)LOCAL_PASSES[slg]; passes/=2.5f; 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)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 = world2cam( current_cam, tm ); tm.x += 1.0f; ///(float)current_cam->xres; //tm.y=0; //tm.z=0; //tm=vxmp(current_cam->iview,tm); tm = cam2world( 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; 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( alpha > 1.0f ) alpha = 1.0f; if( alpha < 0.0f ) alpha = 0.0f; if( itsalight == 0 ) if( r2 < gs ) { r2 = gs; // itsaline = 1; } } // if( r2 < .025 ) // r2 = .025; if( itsalight == 1 ) if( r2 < .05 ) { float r3; r3 = 0.05f; // itsaline = 1; r2 = r3; } { // 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 = world2cam( current_cam, aaa ); 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( TILEMODE == 6 ) if( itsalight == 0 ) if( totallights != 0 ) shade_a_curve( h, &fh ); if( TILEMODE == 6 ) if( itsalight == 0 ) if( GactivateGI ) if( totallights == 0 ) shade_a_curve( h, &fh ); if( 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; } // apply the fog before switching to cam coords if( 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++ ) { 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++ ) { 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( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( ( ( itsalight == 3 ) && ( success == 0 ) ) || ( itsalight != 3 ) ) doit = 1; if( ( TILEMODE > 0 ) && ( 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 (smallish[a]+smallish[b]==0) { 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( current_cam, wperp ); wperp2 = cam2world1( 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( 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( TILEMODE == 6 ) cache_poly( tri, curtile ); 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( itsalight == 1 ) success += draw_poly( tri, cs, 255 ); else if( TILEMODE == 6 ) cache_poly( tri, curtile ); // { // int qqq; //for (qqq=0;qqq<3;qqq++) printf ("%f %f %f ",tri.p[qqq].x,tri.p[qqq].y,tri.p[qqq].z); // } } } } } } free_geomWF( &perphair ); } } } free( fhwidth ); free( clip ); free( dvert2 ); free( smallish ); free( alphamult ); free_geomWF( &fh ); free_geomWF( &hh ); } return ( success ); } static int draw_a_curveLine2( WFTYPE * wf, CURVEINFO * h, int cs ) { int success = 0; WFTYPE fh; WFTYPE hh; int totalhv = 0; float rad; float lastrad; VERT2 tm; int x; float d; int last = 0; int slg = 0; int stp; VERT lastaa; float *fhwidth = NULL; int docurve = 0; int *clip = NULL; VERT *dvert2 = NULL; float hss; clip = ( int * ) malloc( wf->totalverts * sizeof( int ) ); fhwidth = ( float * ) malloc( wf->totalverts * sizeof( float ) ); 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; if( h->cutlength != 0 ) //if (h->killme==0) { if( head >= 0 ) if( h->mtl == head ) slg = 0; if( beard >= 0 ) if( h->mtl == beard ) slg = 1; if( eyebrow >= 0 ) if( h->mtl == eyebrow ) slg = 2; if( eyelash >= 0 ) if( h->mtl == eyelash ) slg = 3; if( splines >= 0 ) if( h->mtl == splines ) slg = 4; // h->ambient=sliders[7][slg].value*h->slider[7]; cs = cs % LOCAL_PASSES[slg]; stp = 1; if( global_segs == 5 ) stp = 10; //rad=(float)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 = world2cam( current_cam, tm ); tm.x += 1.0f; ///(float)current_cam->xres; //tm.y=0; //tm.z=0; //tm=vxmp(current_cam->iview,tm); tm = cam2world( 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; last = 0; //hss=(float)LOCAL_SEGS[h->mtl]; hss = ( float ) wf->totalverts; lastrad = 0; for( x = 0; x < wf->totalverts - 1; x++ ) { float r1; float r2; int docurve = 1; r2 = ( float ) ( ( ( wf->totalverts - 1 ) - ( x + 1 ) ) / ( float ) ( wf->totalverts - 1 ) ) * h->baserad; // +h->thickness*sliders[20][h->slgroup].value*.00045); r2 += ( ( float ) ( x + 1 ) / ( ( float ) ( wf->totalverts - 1 ) ) ) // *sliders[20][h->slgroup].value* * h->tiprad; if( x == 0 ) lastrad = r2 * rad; r2 *= rad; r1 = lastrad; { // 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 = world2cam( current_cam, aaa ); 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]; lastaa = aa; fhwidth[totalhv] = r1; fh.color[totalhv] = wf->color[x]; fh.velocity[totalhv] = wf->velocity[x]; fh.uv[totalhv] = wf->uv[x]; dvert2[totalhv] = aa; lastrad = r2; totalhv++; } } } // // fh.totalverts = totalhv; docurve = 1; //if ((TILEMODE!=6)||(itsalight==1)) //if ((TILEMODE!=6)||(itsalight==1)) //if (itsalight==0) //docurve=0; //if (check_curve(h,&fh)) 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( TILEMODE == 6 ) if( itsalight == 0 ) if( totallights != 0 ) shade_a_curve( h, &fh ); if( 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; } } // apply the fog before switching to cam coords if( 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]; { unsigned char lum; VERT zero; zero.x = 0; zero.y = 0; zero.z = 0; lum = ( unsigned char ) ( h->ambient * 255.0f ); for( x = 0; x < totalhv - 1; x++ ) { int qq; int doit = 0; if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( ( ( itsalight == 3 ) && ( success == 0 ) ) || ( itsalight != 3 ) ) doit = 1; if( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) doit = 1; // if ((clip[x]==0)||(clip[x+1]==0)) doit=1; if( doit ) { POLYDAT tri; int a, b; VERT aa, bb; VERT waa, wbb; float sz1, sz2; a = x; b = ( x + 1 ) % wf->totalverts; sz1 = fhwidth[x]; sz2 = fhwidth[b]; aa = fh.v[x]; bb = fh.v[b]; //if (sz1<30) if( sz1 + sz2 > 0 ) { waa = wf->v[x]; tri.p[0].x = aa.x; tri.p[0].y = aa.y; tri.p[0].z = aa.z; tri.w[0].x = waa.x; tri.w[0].y = waa.y; tri.w[0].z = waa.z; tri.wv[0] = wf->velocity[x]; tri.c[0] = fh.color[a]; tri.v[0] = fh.velocity[a]; tri.rad[0] = sz1; waa = wf->v[b]; tri.p[1].x = bb.x; tri.p[1].y = bb.y; tri.p[1].z = bb.z; tri.w[1].x = waa.x; tri.w[1].y = waa.y; tri.w[1].z = waa.z; tri.rad[1] = sz2; tri.c[1] = fh.color[b]; tri.v[1] = fh.velocity[b]; tri.wv[1] = wf->velocity[b]; // GLOBAL_CLIPIT = 0; success += draw_line( tri, cs, 255 ); } } } } } } Nfree( fhwidth ); Nfree( clip ); Nfree( dvert2 ); free_geomWF( &fh ); free_geomWF( &hh ); return ( success ); } static void precalc_shadow_curve( WFTYPE * h, WFTYPE * bh, CURVEINFO * hp ) { 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_strand( &bh[y], y, hp->ambient ); } } #ifdef MAYA3D #endif static void shade_a_curve( CURVEINFO * hp, WFTYPE * wf ) //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_curve( wf, tmpshad, hp ); //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; } 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 = LWCamOPEN.wpos.x - wf->v[x].x; eye.y = LWCamOPEN.wpos.y - wf->v[x].y; eye.z = LWCamOPEN.wpos.z - wf->v[x].z; lg.x = lg.x; lg.y = lg.y; lg.z = lg.z; // lg.z ok? eye = Vnorm( eye ); { VERT T, L, V,V2; 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 ) )) ); } V2.x= -V.x; V2.y= -V.y; V2.z= -V.z; spec *= hp->spec; if( spec < 0 ) spec = 0; { float spec2; { float tsq; 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 ) )) ); } } 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; fcolor.y += ambient[1] * tint.y; fcolor.z += ambient[2] * tint.z; { fcolor.x += ( spec * lum.x * Gspec_tint.x ); //*tint.x); fcolor.y += ( spec * lum.y * Gspec_tint.y ); //*tint.y); fcolor.z += ( spec * lum.z * Gspec_tint.z ); //*tint.z); } { fcolor.x += ( specB * lum.x * Gspec_tint2.x ); //*tint.x); fcolor.y += ( specB * lum.y * Gspec_tint2.y ); //*tint.y); fcolor.z += ( specB * lum.z * 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 ); } int poly_tile_check( POLYDAT * tri, int xx ) { int x; int clipit = 0; int ret = 0; int ok = 0; //ret=1; // hack // if (0==1) { int okk=0; for (x=0;x<3;x++) { if (tri->p[x].z<=Gmax_geom_screen) okk=1; if (tri->p[x].z+tri->v[x].z<=Gmax_geom_screen) okk=1; } if (okk==0) clipit=1; //check right if (clipit==0) { ok = 0; for( x = 0; x < 3; x++ ) { if( tri->p[x].x <= ( float ) ( alltiles.tile[xx].x2 ) ) ok = 1; if( tri->p[x].x + tri->v[x].x <= alltiles.tile[xx].x2 ) ok = 1; } if( ok == 0 ) clipit = 1; } if( clipit == 0 ) { ok = 0; //check left for( x = 0; x < 3; x++ ) { if( tri->p[x].x + tri->v[x].x >= alltiles.tile[xx].x1 ) ok = 1; if( tri->p[x].x >= alltiles.tile[xx].x1 ) ok = 1; } if( ok == 0 ) clipit = 1; } if( clipit == 0 ) { ok = 0; //check up for( x = 0; x < 3; x++ ) { if( tri->p[x].y + tri->v[x].y <= ( float ) ( alltiles.tile[xx].y2 ) ) ok = 1; if( tri->p[x].y <= ( float ) ( alltiles.tile[xx].y2 ) ) ok = 1; } if( ok == 0 ) clipit = 1; } if( clipit == 0 ) { ok = 0; //check down for( x = 0; x < 3; x++ ) { if( tri->p[x].y + tri->v[x].y >= alltiles.tile[xx].y1 ) ok = 1; if( tri->p[x].y >= alltiles.tile[xx].y1 ) ok = 1; } if( ok == 0 ) clipit = 1; } if( clipit == 1 ) ret = 0; if( clipit == 0 ) ret = 1; } return ( ret ); } int cache_poly(POLYDAT tri, int xx) { draw_poly(tri,0,255); return(1); } int cache_polyOLD( POLYDAT tri, int xx ) { // // Let's make sure that only one thread accesses this at a time. // // SHAVEmutex_lock(&Gcache_poly_mutex); { int t, tt; POLYDATSM sm; POLYDAT pp1; int x; int clippit=0; memcpy( &pp1, &tri, sizeof( POLYDAT ) ); for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = tri.p[x].x; tmpv.y = tri.p[x].y; tmpv.z = tri.p[x].z; tmpv = cam2world( current_cam, tmpv ); pp1.p[x].x = tmpv.x; pp1.p[x].y = tmpv.y; pp1.p[x].z = tmpv.z; } pp1 = tocam( current_cam, pp1 ); t = alltiles.tile[xx].triangles; { VERT cpos,camdir,pvec; cpos=current_cam->wpos; camdir.x = current_cam->view[0][2]; camdir.y = current_cam->view[1][2]; camdir.z = current_cam->view[2][2]; pvec.x=pp1.w[0].x-cpos.x; pvec.y=pp1.w[0].y-cpos.y; pvec.z=pp1.w[0].z-cpos.z; pvec=Vnorm(pvec); if (VDot(pvec,camdir)<.1) clippit=1; } if (clippit==0) if(alltiles.tile[xx].triangle_cache) if( poly_tile_check( &pp1, xx ) ) { // if( t < 3000000 ) //<- this would rescue limits, but can cause artifacts // if (t alltiles.tile[xx].triangle_limit - 100 ) { // printf ("expanding cache\n"); // fflush(stdout); tt = alltiles.tile[xx].triangle_limit; alltiles.tile[xx].triangle_limit += 50000; // printf ("raising limit to %d\n",alltiles.tile[xx].triangle_limit);fflush(stdout); alltiles.tile[xx].triangle_cache = ( POLYDATSM * ) realloc( alltiles.tile[xx].triangle_cache, ( alltiles.tile[xx].triangle_limit ) * sizeof( POLYDATSM ) ); if (alltiles.tile[xx].triangle_cache==NULL) { free(alltiles.tile[xx].triangle_cache); printf ("allocation failed! %d\n",alltiles.tile[xx].triangle_limit);fflush(stdout); } } if(alltiles.tile[xx].triangle_cache) poly2sm( &tri, &sm ); if(alltiles.tile[xx].triangle_cache) memcpy( &alltiles.tile[xx].triangle_cache[t], &sm, sizeof( POLYDATSM ) ); alltiles.tile[xx].triangles++; // Gaccept_poly++; } } // else Greject_poly++; // SHAVEmutex_unlock(&Gcache_poly_mutex); } return ( 1 ); } static void draw_lotsHAIROLD( int cs ) //int cs; { int curtile = 0; 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 slg; int clipx1, clipy1, clipx0, clipy0; float tcnnt = 0; int lpp = 0; int low_mem=0; if( low_mem == 0 ) { mkbounds( ); reset_faces( ); checkforzero( ); make_normals( ); for( x = 0; x < totalverts; x++ ) hair[x].norm = vn[x]; // for (x=0;x 0 ) { // if (itsalight==1) tcnnt += ( float ) LOCAL_CNT[slg]; // if (itsalight==0) // tcnnt += ( float )LOCAL_CNT[slg]*LOCAL_PASSES[slg]; } tcnnt /= 5.0f; Gdeep_shadows = 1; for( x = 0; x < 5; x++ ) if( total_slgfaces[x] > 0 ) hc2++; if( low_mem == 0 ) if( hc2 > 0 ) { int slg; int th; int prg = 0; for( slg = 0; slg < 5; slg++ ) if( total_slgfaces[slg] > 0 ) if( low_mem == 0 ) { int q; int cnnt; int dok = 1; //if (itsalight==1) cnnt = LOCAL_CNT[slg]; //else //cnnt=LOCAL_CNT[slg]*LOCAL_PASSES[slg]; if( itsalight == 1 ) if( Gdeep_shadows == 0 ) cnnt *= ( LOCAL_PASSES[slg] ); if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) for( x = 0; x < cnnt; x++ ) if( low_mem == 0 ) #ifdef progress_update if( Gdone == 0 ) #endif { int fin; // GLOBS *gs; // globs .. Gslg = slg; GhairID = x; cursamp = cs; fin = draw_oneHAIR( slg, x, cs, curtile ); // end loop #ifdef progress_update lpp++; if( itsalight == 1 ) if( lpp >= ( int ) 100 ) { global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); if( finish != 0 ) { Gdone = 1; low_mem = 1; x = cnnt; if( GLOBAL_VERBOSE ) printf( "INTERRUPTED!\n" ); } lpp = 0; } #endif } } } // hc2 //for (x=0;x 0 ) { // if (itsalight==1) tcnnt += ( float ) LOCAL_CNT[slg]; // if (itsalight==0) // tcnnt += ( float )LOCAL_CNT[slg]*LOCAL_PASSES[slg]; } Gpass=0; Gcurpass=0; tcnnt /= 5.0f; Gdeep_shadows = 1; for( x = 0; x < 5; x++ ) if( total_slgfaces[x] > 0 ) hc2++; if( low_mem == 0 ) if( hc2 > 0 ) { int slg; int th; int prg = 0; for( slg = 0; slg < 5; slg++ ) if( total_slgfaces[slg] > 0 ) if( low_mem == 0 ) { int q; int cnnt; int dok = 1; cnnt = LOCAL_CNT[slg]; Gslg = slg; GhairID = x; Gpass=0; Gcurpass=0; // if (cnnt>0) // push_renderstate(>hreads[0],0); if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) for( x = 0; x < cnnt*LOCAL_PASSES[slg]; x++ ) if( low_mem == 0 ) #ifdef progress_update if( Gdone == 0 ) #endif { int fin; int qq=0; // GLOBS *gs; // globs .. Gslg = slg; GhairID = x; //for (qq=0;qq 0 ) { // if (itsalight==1) tcnnt += ( float ) LOCAL_CNT[slg]; // if (itsalight==0) // tcnnt += ( float )LOCAL_CNT[slg]*LOCAL_PASSES[slg]; } tcnnt /= 5.0f; Gdeep_shadows = 1; for( x = 0; x < 5; x++ ) if( total_slgfaces[x] > 0 ) hc2++; //est+=(est*totallights); ///est*=MBsampling; est=gthreads[0].total_hairs; #ifdef progress_update SHAVEprogress( -1, est ); SHAVEprogress( 0, est ); #endif global_progress=0; if( low_mem == 0 ) if( hc2 > 0 ) { int slg; int th; int prg = 0; int qq=0; for( slg = 0; slg < 5; slg++ ) if( total_slgfaces[slg] > 0 ) if( low_mem == 0 ) for (qq=0;qqcnnt) inc=cnnt; if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) for( x = 0; x < cnnt; x+=inc ) // for( x = 0; x < cnnt; x+ ) if( low_mem == 0 ) { WFTYPE wf; CURVEINFO cinfo; int fin; int b; int xx; init_geomWF(&wf); Gslg = slg; GhairID = x; list_total=0; b=x+inc; if (b>=cnnt) b=cnnt; b-=x; list_total=0; for (xx=0;xx 0 ) { // if (itsalight==1) tcnnt += ( float ) LOCAL_CNT[slg]; // if (itsalight==0) // tcnnt += ( float )LOCAL_CNT[slg]*LOCAL_PASSES[slg]; } tcnnt /= 5.0f; Gdeep_shadows = 1; for( x = 0; x < 5; x++ ) if( total_slgfaces[x] > 0 ) hc2++; est=gthreads[0].total_hairs; #ifdef progress_update SHAVEprogress( -1, est ); SHAVEprogress( 0, est ); #endif global_progress=0; if( low_mem == 0 ) if( hc2 > 0 ) { int slg; int th; int prg = 0; int qq; for( slg = 0; slg < 5; slg++ ) if( total_slgfaces[slg] > 0 ) if( low_mem == 0 ) // for (qq=0;qqcnnt) inc=cnnt; if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) for( x = 0; x < cnnt; x+=inc ) // for( x = 0; x < cnnt; x+ ) if( low_mem == 0 ) { WFTYPE wf; CURVEINFO cinfo; int fin; int b; int xx; init_geomWF(&wf); Gslg = slg; GhairID = x; list_total=0; b=x+inc; if (b>=cnnt) b=cnnt; b-=x; list_total=0; for (xx=0;xx 0 ) { int q; int cnnt; WFTYPE wf; CURVEINFO cinfo; int dok = 1; init_geomWF( &wf ); Gcurpass = cs; x = xid; 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++; hairID = ( x ); slgID = slg; cinfo.hairID = hairID; cinfo.groupID = slg; cinfo.nodeID = GnodeID; if( 0 == 1 ) if( progress > 1000 ) if( TILEMODE == 0 ) { progress = 0; global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); } // if (TILEMODE==2) // { // progress=0; // global_progress++; // finish=SHAVEprogress(global_progress,estimated_total); // } cs=0; ///LOCAL_SEGS[slg]=15; if( finish != 1 ) {// come back here 11/1 MAYAmake_a_curve( cs, slg, x, LOCAL_SEGS[slg], &wf, &cinfo); 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;q 0 ) { int q; int cnnt; WFTYPE wf; CURVEINFO cinfo; int dok = 1; init_geomWF( &wf ); Gcurpass = cs; gs->passnumber = cs; gs->cursamp=cs; Gpass=cs; x = xid; 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++; hairID = ( x ); slgID = slg; cinfo.hairID = hairID; cinfo.groupID = slg; cinfo.nodeID = GnodeID; if( 0 == 1 ) if( progress > 1000 ) if( TILEMODE == 0 ) { progress = 0; global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); } // if (TILEMODE==2) // { // progress=0; // global_progress++; // finish=SHAVEprogress(global_progress,estimated_total); // } ///LOCAL_SEGS[slg]=15; if( finish != 1 ) { MTMAYAmake_a_curve( cs, slg, x, 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;q 0 ) { int q; int cnnt; WFTYPE wf; CURVEINFO cinfo; int dok = 1; init_geomWF( &wf ); x = xid; 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++; hairID = ( x ); slgID = slg; // if (progress>100) #ifdef proress_update if( TILEMODE == 0 ) { progress = 0; global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); } #endif // if (progress>50) // if (TILEMODE==2) // { // progress=0; // finish=SHAVEprogress(global_progress,estimated_total); // } if( finish != 1 ) { MAYAmake_a_curveROOT( cs, slg, x, &wf, &cinfo ); 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; } } free_geomWF( &wf ); } } // hc2 return ( finish ); } static void draw_lotsROOTS( int cs ) //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; mkbounds( ); reset_faces( ); checkforzero( ); make_normals( ); for( x = 0; x < totalverts; x++ ) hair[x].norm = vn[x]; // for (x=0;x 0 ) hc2++; if( hc2 > 0 ) { int slg; int th; int prg = 0; for( slg = 0; slg < 5; slg++ ) if( total_slgfaces[slg] > 0 ) { int q; int cnnt; int dok = 1; cnnt = LOCAL_CNT[slg]; if( itsalight == 1 ) if( Gdeep_shadows == 0 ) cnnt *= ( LOCAL_PASSES[slg] ); if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) for( x = 0; x < cnnt; x++ ) if( finish == 0 ) { Gslg = slg; GhairID = x; Gcurpass = cs; finish = draw_oneROOT( slg, x, cs ); } } } // hc2 } // // Dean's speedups: // // o Got rid of the local WFTYPEs, which use dynamic allocation, and // replaced them with static arrays. Note that we use arrays of // structs rather than a struct of arrays because that means that each // array element can be copied with a single block move rather than // individually assigning each member. This also makes the code a bit // smaller and easier to read. // // o Instead of copying the output of one clip pass into the input array for // the next pass, we just use pointers to the two arrays and swap them // at the end of each pass. // // o Hoisted the calculation of the near clipping plane position ('pln') // out of the loop, so it only gets called once per invocation rather // than once per vertex. // // Note that this could be improved upon even more if the position were // calculated in advance whenever 'current_cam' changes, and the value // stuffed into a global. However we're only talking about saving 4 // mults, 3 adds and 3 assignments per invocation, so it might not be // worth the hassle of tracking down all of the cam changes. // // o Got rid of the fabs() calls for the top, bottom, left and right // planes as they were unnecessary: the values are already guaranteed to // be positive. // // o Got rid of unnecessary zero-division guard checks for the top, // bottom, left and right planes as they were unnecessary: the values // are guaranteed to be non-zero. // // o Replaced 'if' statements which do boolean assignments with direct // boolean assignment of condition result. // // o Replaced most of the 'if's for the clipping planes with a 'switch' // statement as that's faster. // // o Got rid of unnecessary variable initializations. // static void camspace_clipitDEANE( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ) { 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 = current_cam->view[0][2]; nrm.y = current_cam->view[1][2]; nrm.z = current_cam->view[2][2]; nrm = Vnorm( nrm ); //#ifdef MAX3D if( itsalight == 1 ) zoomFactor = current_cam->zoom * 18.01f; // flicker was .01 if( itsalight != 1 ) zoomFactor = current_cam->zoom * 1.01f; // flicker was .01 zoomFactor = current_cam->zoom * current_cam->nearclip; // flicker was .01 //#endif #ifndef MAX3D if( itsalight == 1 ) zoomFactor = current_cam->zoom * 1.01f; // flicker was .01 if( itsalight != 1 ) zoomFactor = current_cam->zoom * 0.01f; // flicker was .01 #endif // zoomFactor = current_cam->zoom * .01f; pln.x = current_cam->wpos.x + nrm.x * zoomFactor; pln.y = current_cam->wpos.y + nrm.y * zoomFactor; pln.z = 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++; } else { if( !st1 ) { outList[outCount] = inList[x]; outCount++; } if( st1 != 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( 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++; } 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 - 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++; } else 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++; } else 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++; } else 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 // clipping code here // input is one triangle, output is a wftype with a strip of triangles. // if the triangle culled completely, the structure returns empty static int trivial_reject( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */ ) { int pl; int ret = 0; int totalp = 0; int totalnewp = 0; int x; int gonna_clip = 0; float dist; totalp = 3; for( pl = 0; pl <= 4; pl++ ) // cycle through all the clip planes { int reject; int xx; reject = 0; for( x = 0; x < totalp; x++ ) { int x1; x1 = ( x + 1 ) % ( totalp ); // check for borders; // 0 if( pl == 1 ) { int st1 = 0, st2 = 0; if( pp->p[x].y >= ys ) st1 = 1; if( pp->p[x].y < ys ) st1 = 0; if( pp->p[x1].y >= ys ) st2 = 1; if( pp->p[x1].y < ys ) st2 = 0; if( st1 != st2 ) gonna_clip = 1; if( ( st1 == 1 ) && ( st2 == 1 ) ) // states are different, ones above the other's below { reject++; } } // check for borders; // 1 if( pl == 2 ) { int st1, st2; if( pp->p[x].x >= xs ) st1 = 1; if( pp->p[x].x < xs ) st1 = 0; if( pp->p[x1].x >= xs ) st2 = 1; if( pp->p[x1].x < xs ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) // states are different, ones above the other's below { reject++; } if( st1 != st2 ) gonna_clip = 1; } // check for borders; // 2 if( pl == 3 ) { int st1, st2; if( pp->p[x].y < yl ) st1 = 1; if( pp->p[x].y >= yl ) st1 = 0; if( pp->p[x1].y < yl ) st2 = 1; if( pp->p[x1].y >= yl ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) // states are different, ones above the other's below { reject++; } if( st1 != st2 ) gonna_clip = 1; } // check for borders; // 3 if( pl == 4 ) { int st1, st2; if( pp->p[x].x < xl ) st1 = 1; if( pp->p[x].x >= xl ) st1 = 0; if( pp->p[x1].x < xl ) st2 = 1; if( pp->p[x1].x >= xl ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) // states are different, ones above the other's below { reject++; } if( st1 != st2 ) gonna_clip = 1; } // check for borders; // nearclip // 0 if( pl == 0 ) { int st1, st2; float dr1, dr2; VERT pln; VERT vc1, vc2; VERT nrm; VERT ca, ba; float cad, bad; nrm.x = current_cam->view[0][2]; nrm.y = current_cam->view[1][2]; nrm.z = current_cam->view[2][2]; pln.x = current_cam->wpos.x + nrm.x * current_cam->zoom * .01; pln.y = current_cam->wpos.y + nrm.y * current_cam->zoom * .01; pln.z = current_cam->wpos.z + nrm.z * current_cam->zoom * .01; vc1.x = pp->v[x].x - pln.x; vc1.y = pp->v[x].y - pln.y; vc1.z = pp->v[x].z - pln.z; vc1 = Vnorm( vc1 ); dr1 = VDot( vc1, nrm ); vc2.x = pp->v[x1].x - pln.x; vc2.y = pp->v[x1].y - pln.y; vc2.z = pp->v[x1].z - pln.z; vc2 = Vnorm( vc2 ); dr2 = VDot( vc2, nrm ); if( dr1 <= 0 ) st1 = 1; if( dr1 > 0 ) st1 = 0; if( dr2 <= 0 ) st2 = 1; if( dr2 > 0 ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) // states are different, ones above the other's below { reject++; } if( st1 != st2 ) gonna_clip = 1; } // done checking lateral borders // stuff newp into tempp } // x (points) if( reject == totalp ) { pl = 5; // stop ret = 1; // not gonna clip - just reject me } } // pl if( ret == 0 ) if( gonna_clip ) ret = 2; return ( ret ); } static void MTdisplace_randscale( BASEHAIR * h, GLOBS * gs ) { int xx; float rs = 1.0f; float rss; rss=h->randscale; rss*=0.7f; // rs=h->randscale*drand98(); // rs+=(1.0-h->randscale); rs = MTdrand98( gs ); rs = ( rss ) * rs + ( 1.0 - rss ) * 1.0f; if( rs != 1.0f ) for( xx = 1; xx < 15; xx++ ) { h->hv[xx].x -= h->hv[0].x; h->hv[xx].y -= h->hv[0].y; h->hv[xx].z -= h->hv[0].z; h->hv[xx].x *= rs; h->hv[xx].y *= rs; h->hv[xx].z *= rs; h->hv[xx].x += h->hv[0].x; h->hv[xx].y += h->hv[0].y; h->hv[xx].z += h->hv[0].z; } h->restlength *= rs; } static void displace_scale( BASEHAIR * h, float rs ) { int xx; if( rs != 1.0f ) for( xx = 1; xx < 15; xx++ ) { h->hv[xx].x -= h->hv[0].x; h->hv[xx].y -= h->hv[0].y; h->hv[xx].z -= h->hv[0].z; h->hv[xx].x *= rs; h->hv[xx].y *= rs; h->hv[xx].z *= rs; h->hv[xx].x += h->hv[0].x; h->hv[xx].y += h->hv[0].y; h->hv[xx].z += h->hv[0].z; } } static void MTdisplace_kinky( BASEHAIR * h, float ss9, float freqq1, GLOBS * gs ) { int a; int xx; int oc; float ss1, ss2; float freqqx, freqqy, freqqz; a = 1; oc = Gcurpass; freqqx = h->kinkfreqX * .01; freqqy = h->kinkfreqY * .01; freqqz = h->kinkfreqZ * .01; #ifdef EXTERNAL_COLLISION // freqqx=freqqx; // freqqy=freqqx; // freqqz=freqqx; unlock #endif //#ifdef MAYA3D //ss1=h->kink*.1; // commented out on 2.7v51 //ss2=h->kinkroot*.1; // commented out on 2.7v51 ss1 = h->kink * 3.0f; ss2 = h->kinkroot * 3.0f; //#endif #ifdef EXTERNAL_COLLISION ///ss1*=.1; // commented out on 2.7v51 ///ss2*=.1; // commented out on 2.7v51 #endif if( h->slgroup == 4 ) freqqx *= 56.0f; if( h->slgroup == 4 ) freqqy *= 56.0f; if( h->slgroup == 4 ) freqqz *= 56.0f; // if (h->dreadcount>0) Gcurpass = 0; // no ghosting // if (global_segs==5) // a=3; /// if (h->kink>0) // if (freqq>0) if( ( ss1 > 0.0f ) || ( ss2 > 0.0f ) ) { for( xx = 1; xx < 15; xx += a ) if( xx != 0 ) { float sc1; float sc2; float amp = 1.0f; float freqx, freqy, freqz; float hr; VERT dv; hr = ( float ) 9999999.0f; dv.x = 0; dv.y = 0; dv.z = 0; // for (x=face_start[h->pid];xpid];x++) // { // float tmphr; // tmphr=resthair[facelist[x]].restlength; // if (tmphrrestlength; //yikes!! /// hr=1.0f; // we're changing this back for soft? sc1 = ( hr ) * ss1; sc1 *= 2.0f; sc1 *= ( xx / 15.0f ); sc1 /= 15.0f; sc2 = ( hr ) * ss2; // root sc2 *= 2.0f; sc2 *= ( ( 15.0f - ( float ) xx ) / 15.0f ); // freq=h->restlength/400.0f; // freqx = ( ( float )1.0 / restBOUNDLENGTH ) * 180.0f; // freqy = ( ( float )1.0 / restBOUNDLENGTH ) * 180.0f; // freqz = ( ( float )1.0 / restBOUNDLENGTH ) * 180.0f; freqx = ( 1.0 / h->restlength ); freqy = ( 1.0 / h->restlength ); freqz = ( 1.0 / h->restlength ); // freq=(h->restlength/(float)BOUNDLENGTH)*11150.0f; freqx *= freqqx; freqy *= freqqy; freqz *= freqqz; if( ( sc1 != 0.0f ) || ( sc2 != 0.0f ) ) { dv.x += ( float ) ( getnoise( h->noisev[xx].x * freqx, h->noisev[xx].y * freqy, h->noisev[xx].z * freqz ) - ( float ) .5f ) * amp; dv.y += ( float ) ( getnoise( h->noisev[xx].x * freqx + ( float ) 72.3, h->noisev[xx].y * freqy + ( float ) 16.08, h->noisev[xx].z * freqz + ( float ) 3.0f ) - ( float ) .5f ) * amp; dv.z += ( float ) ( getnoise( h->noisev[xx].x * freqx + ( float ) 15.0f, h->noisev[xx].y * freqy + ( float ) 19.99f, h->noisev[xx].z * freqz + ( float ) 12.0f ) - ( float ) .5f ) * amp; } amp /= ( float ) 4.0f; freqx *= ( float ) 4.0f; freqy *= ( float ) 4.0f; freqz *= ( float ) 4.0f; if( Gfast_eval == 0 ) if( ( sc1 != 0.0f ) || ( sc2 != 0.0f ) ) { // h->noisev[xx].x+=(getnoise(h->noisev[xx].x*freq,h->noisev[xx].y*freq,h->noisev[xx].z*freq)-.5f)*sc; dv.x += ( float ) ( getnoise( h->noisev[xx].x * freqx + ( float ) 72.3, h->noisev[xx].y * freqy + ( float ) 16.08, h->noisev[xx].z * freqz + ( float ) 3.0f ) - ( float ) .5f ) * amp; dv.y += ( float ) ( getnoise( h->noisev[xx].x * freqx + ( float ) 72.3, h->noisev[xx].y * freqy + ( float ) 16.08, h->noisev[xx].z * freqz + ( float ) 3.0f ) - ( float ) .5f ) * amp; dv.z += ( float ) ( getnoise( h->noisev[xx].x * freqx + ( float ) 15.0f, h->noisev[xx].y * freqy + ( float ) 19.99, h->noisev[xx].z * freqz + ( float ) 12.0f ) - ( float ) .5f ) * amp; amp /= 2; } //freq*=4; if( sc1 != 0.0f ) { h->hv[xx].x += dv.x * sc1; h->hv[xx].y += dv.y * sc1; h->hv[xx].z += dv.z * sc1; } if( sc2 != 0.0f ) { h->hv[xx].x += dv.x * sc2; h->hv[xx].y += dv.y * sc2; h->hv[xx].z += dv.z * sc2; } // h->hv[xx].x+=(getnoise(h->hv[xx].x*freq,h->hv[xx].y*freq,h->hv[xx].z*freq)-.5f)*sc; // h->hv[xx].y+=(getnoise(h->hv[xx].x*freq+72.3,h->hv[xx].y*freq+16.08,h->hv[xx].z*freq+3.0f)-.5f)*sc; // h->hv[xx].z+=(getnoise(h->hv[xx].x*freq+15.0f,h->hv[xx].y*freq+19.99,h->hv[xx].z*freq+12.0f)-.5f)*sc; } } Gcurpass = oc; if( 0 == 1 ) { float rs = 1.0f; rs = h->randscale * MTdrand98( gs ); rs += ( 1.0 - h->randscale ); for( xx = 1; xx < 15; xx++ ) { h->hv[xx].x -= h->hv[0].x; h->hv[xx].y -= h->hv[0].y; h->hv[xx].z -= h->hv[0].z; h->hv[xx].x *= rs; h->hv[xx].y *= rs; h->hv[xx].z *= rs; h->hv[xx].x += h->hv[0].x; h->hv[xx].y += h->hv[0].y; h->hv[xx].z += h->hv[0].z; } } } static void color_a_hair( BASEHAIR * h ) { 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 == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // 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] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); //fprintf (stdout,"diagnostic1 sliders[46][0].value = %f h->slider[46] = %f\n",sliders[46][0].value,h->slider[45]);fflush(stdout); tint.x = ( sliders[9][slg].value ) / 255.0f; tint.y = ( sliders[10][slg].value ) / 255.0f; tint.z = ( sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( sliders[18][slg].value ) / 255.0f; tint1.z = ( 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( drand98( ) < ( sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = sliders[13][slg].value / 255.0f; tnt.y = sliders[14][slg].value / 255.0f; tnt.z = 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 = drand98( ); // rh1 = drand98( ); // rs1 = drand98( ); // rv1 -= .5; rv1 = smoothstep(rv1); rv1 = smoothstep(rv1); rc.x = drand98( ); rc.y = drand98( ); rc.z = drand98( ); { float h1, s1, l1; float rv; float rr, gg, bb; float hue1; hue1 = sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .45; 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 = ( sliders[39][slg].value / 100.0f ) * h->slider[39]; //rv*=.5f; 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 = sliders[12][slg].value / 100.0f; hue1 *= h->slider[12]; hue1 *= .45; // 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 = ( 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; 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; } h->killme = 0; Jsrand( ( unsigned long ) ( h->hairnumber * 11 ) ); { int xx; for( xx = 0; xx < 5; xx++ ) drand98( ); } if( dmapp.x * dmapp.x < drand98( ) ) h->killme = 1; } static void color_a_hairSOFT( BASEHAIR * h ) { 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 == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // 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] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; //fprintf (stdout,"diagnostic2 sliders[46][0].value = %f h->slider[46] = %f\n",sliders[46][0].value,h->slider[45]);fflush(stdout); h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ for( x = 0; x < 15; x++ ) { h->color[x].x = 1.0f; h->color[x].y = 1.0f; h->color[x].z = 1.0f; } h->killme = 0; Jsrand( ( unsigned long ) ( h->hairnumber * 11 ) ); { int xx; for( xx = 0; xx < 5; xx++ ) drand98( ); } if( dmapp.x * dmapp.x < drand98( ) ) h->killme = 1; } static void color_a_hairROOT( BASEHAIR * h ) { 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 == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // drand59 dmapp.x *= h->slider[28]; // density llnmap.x *= h->slider[29]; h->killme = 0; // for (xx=0;xx<30;xx++) { float tmp; tmp=drand98(); } // MTmix100(gs)(); { int xx; for( xx = 0; xx < 5; xx++ ) drand98( ); } if( dmapp.x * dmapp.x < drand98( ) ) // if( dmapp.x < drand98( ) ) h->killme = 1; h->killme = 0; h->thickness = h->slider[20] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = llnmap.x; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); // h->dreadcount = sliders[25][slg].value; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); tint.x = ( sliders[9][slg].value ) / 255.0f; tint.y = ( sliders[10][slg].value ) / 255.0f; tint.z = ( sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( sliders[18][slg].value ) / 255.0f; tint1.z = ( 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( drand98( ) < ( sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = sliders[13][slg].value / 255.0f; tnt.y = sliders[14][slg].value / 255.0f; tnt.z = 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 = drand98( ); //rh1=drand98(); //rs1=drand98(); // rv1 -= .5; // rv1 *= 2.0f; rv1 = smoothstep(rv1); rv1 = smoothstep(rv1); rc.x = drand98( ); rc.y = drand98( ); rc.z = drand98( ); { float h1, s1, l1; float rv; float rr, gg, bb; float hue1; hue1 = 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 - ( 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 = 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.0 - ( hue1 ) ) + ( rr * ( hue1 ) ); tint.y = ( tint.y ) * ( 1.0 - ( hue1 ) ) + ( gg * ( hue1 ) ); tint.z = ( tint.z ) * ( 1.0 - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = 1.0 - ( sliders[39][slg].value / 100.0f ) * h->slider[39]; 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; for( x = 0; x < 15; x++ ) { 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; } } POLYDAT slice_scan( POLYDAT a, int y ) { int x; int aa, bb, cc; int flp = 0; POLYDAT ret; return ( a ); } static int draw_poly2new( POLYDAT pp, int layer, unsigned char lum ) { 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 GSclipx0, GSclipx1, GSclipy0, GSclipy1; int GSxres, GSyres; GSxres = current_cam->xres * GLOBALSAMP; GSyres = current_cam->yres * GLOBALSAMP; // if (pleft.xxres * current_cam->yres; if ( TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( float ) GLOBALSAMP *( float ) GLOBALSAMP; } if ( itsalight != 1 ) for ( x = 0; x < 4; x++ ) { if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( 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( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight == 2 ) { pp.p[x].x += calibrateX; // we're only doing this for occlusion! pp.p[x].y += calibrateY; } } if( 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( itsalight != 1 ) for( x = 0; x < 4; x++ ) { if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight == 2 ) { pp.p[x].x += .5; // we're only doing this for occlusion! pp.p[x].y -= .5; } } if( itsalight != 1 ) { tilebuff.cursamp = layer; current_cam->cursamp=layer; } tilebuff.cursamp=0; tim = 0.0f; //if (0==1) //if (TILEMODE!=2) if( ( TILEMODE > 0 ) && ( 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( !( ( TILEMODE > 0 ) && ( 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 (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( itsalight == 1 ) if( imaxy > current_cam->yres - 1 ) imaxy = 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( TILEMODE == 0 ) { int scanl; scanl = ( int ) y *current_cam->xres; baseadd = scanl ; gbaseadd = scanl ; } if( TILEMODE != 0 ) { int gclpy; int lp; lp = 0; gclpy = ( int ) ( y - GSclipy0 ) * alltiles.sx * GLOBALSAMP; // printf ("y=%f Gclipy0=%f\n",(float)y,(float)Gclipy0); baseadd = gclpy + lp; // layer*(pageres); gbaseadd = gclpy +layer*pageres; // gbaseadd=(int)(y-Gclipy0*GLOBALSAMP)*alltiles.sx*GLOBALSAMP; ; } y1 = y; //+campass[cursamp].y; ////- if( ( TILEMODE != 0 ) && ( ( y >= GSclipy0 ) && ( y < GSclipy1 ) ) ) yclip = 0; ////- // if ((TILEMODE==0)&&((y>=Gclipy0)&&(y= Gclipy0 ) && ( y < 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; } { int clipx = 1; int x1; int qq2; float tt; // was here qq2 = ( int ) pright.x; //if (itsalight==1) baseadd=0; //if (TILEMODE==0) // if ((pright.x-pleft.x)xres) clipx=0; //if (TILEMODE>0) // if ((pright.x-pleft.x)xres*GLOBALSAMP) clipx=0; ////- for( tt = ( float ) pleft.x; tt <= ( float ) ( qq2 ); 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( itsalight != 2 ) if( itsalight > 0 ) if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; if( TILEMODE == 0 ) ////- if( current_cam == &LWcam ) ////- if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) ////- if( !( ( tt >= GSclipx0 ) && ( tt <= GSclipx1 ) ) ) clipit = 1; ////- if( TILEMODE == 0 ) ////- if( current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < current_cam->xres ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) ////- if( 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( TILEMODE > 0 ) x2 = x2 - GSclipx0; if( TILEMODE > 0 ) y2 = y2 - GSclipy0; 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 (TILEMODE==1) ok=1; if( TILEMODE == 0 ) if( ( ( y2 < Gclipy0 ) || ( y2 >= Gclipy1 ) ) ) { ok = 0; } if( TILEMODE == 0 ) if( ( ( x2 < Gclipx0 ) || ( x2 >= Gclipx1 ) ) ) { ok = 0; } // x2 and y2 were >= if( ( TILEMODE != 0 ) && ( ( y2 < 0 ) || ( y2 >= GSyres ) ) ) { ok = 0; } if( ( 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( TILEMODE == 6 ) current_cam = &tilebuff; if( current_cam->geombuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( ( int ) current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = current_cam->geombuff[gbaseadd + x2]; if( ( TILEMODE == 0 ) ) aa4 = ( int ) y2 *current_cam->xres + x2; if( ( TILEMODE != 0 ) ) aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; ok = 1; if( baseadd + x2 >= 0 ) if( ( int ) current_cam->zbound > baseadd + x2 ) { if( current_cam->zbuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 2 ) // if( ( TILEMODE == 0 ) // ) // we don't sort for hair // if( itsalight != 2 ) if( pc.z > current_cam->zbuff[baseadd + x2] ) hairztest = 0; } if( itsalight != 1 ) // we don't want to occlude with geom on a light pass if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( pc.z > geomz - .000000001 ) geomztest = 0; aa4 *= 4; if( TILEMODE == 1 ) ok = 1; ////- if( TILEMODE == 0 ) ////- if( ( current_cam == &LWcam ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) ////- { ok = 0; } ////- if( itsalight != 2 ) if( ( itsalight > 0 ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) { ok = 0; } if( TILEMODE != 0 ) ////- if( ( current_cam == &LWcam ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) ////- { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) ////- { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( x1 < GSclipx0 ) || ( x1 >= GSclipx1 ) ) ) ////- { ok = 0; } // printf ("tilemode=%d\n",TILEMODE); // if ((TILEMODE>0)&&(TILEMODE<6)) ok =0; // if (itsalight==2) ok=1; if( ok ) // this used to include geomz or hairz failiure { success += 1; // if( geomztest ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 3 ) { // if( 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) if( TILEMODE == 6 ) if( itsalight == 0 ) if( 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 ) current_cam->ibound > aa4 + 4 ) { push_pixel(&tilebuff,baseadd+x2,aa4, cc.x, cc.y, cc.z, alpha, pc.z,layer); } } } } // ok } // plot } // pair interp } // loop } // variable decl } // variable decl } // y>0 ytotalverts; tmpcolor.totalfaces = wf->totalfaces; tmpcolor.totalfverts = wf->totalfverts; alloc_geomWF( &tmpcolor ); LWlight[0].wpos.x = 1000.0f; LWlight[0].wpos.y = 1000.0f; LWlight[0].wpos.z = 1000.0f; //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; } if( head >= 0 ) if( hp->mtl == head ) slg = 0; if( beard >= 0 ) if( hp->mtl == beard ) slg = 1; if( eyebrow >= 0 ) if( hp->mtl == eyebrow ) slg = 2; if( eyelash >= 0 ) if( hp->mtl == eyelash ) slg = 3; if( splines >= 0 ) if( hp->mtl == splines ) slg = 4; // hp->ambient=sliders[7][slg].value*hp->slider[7]; if( hp->restlength > 0 ) for( l = 0; l < 1; l++ ) { //if (LWlight[l].zbuff) { VERT fcolor; if( hp->restlength > 0 ) for( x = 0; x < wf->totalverts; x += 1 ) { VERT a, uv; VERT lum; float shd; 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 = 1.0f; lum.y = 1.0f; lum.z = 1.0f; if( LWlight[l].wind == 1 ) { lum.x = 0; lum.y = 0; lum.z = 0; } { VERT shad; VERT wpt; wpt.x = tmpp[0]; wpt.y = tmpp[1]; wpt.z = tmpp[2]; // if (LWlight[l].wind==0) { 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; } } { 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; lg.x = lg.x; lg.y = lg.y; lg.z = lg.z; // lg.z ok? eye = Vnorm( eye ); { VERT T, L, V; float shd2 = 0.0f; shd = 0.0f; T = norm; L = lg; V = eye; { float tsq; float tsq2; tsq = VDot( L, T ); tsq *= tsq; tsq2 = 1.0f - tsq; if( tsq2 > 0.0f ) shd2 = sqrt( 1.0 - tsq ); else shd2 = 0.0f; } if( shd2 > 0 ) shd += shd2; { float spec2; float spec3; { float tsq; float tsq2; tsq2 = 1.0f - tsq * tsq; if( tsq2 < 0 ) tsq2 = 0; tsq = VDot( V, T ); if( tsq2 != 0 ) spec2 = shd2 * sqrt( tsq2 ) - VDot( L, T ) * tsq; else spec2 = -VDot( L, T ) * tsq; } { float tsq; float tsq2; VERT iV; tsq2 = 1.0f - tsq * tsq; if( tsq2 < 0 ) tsq2 = 0; iV.x= -V.x; iV.y= -V.y; iV.z= -V.z; tsq = VDot( iV, T ); if( tsq2 != 0 ) spec3 = shd2 * sqrt( tsq2 ) - VDot( L, T ) * tsq; else spec3 = -VDot( L, T ) * tsq; } if( spec3 < 0 ) spec3 = 0; if( spec2 < 0 ) spec2 = 0; spec = pow( spec2, 1.0 / ( 3.0 * ( .101 - hp->kspec ) ) ); specB = pow( spec3, 1.0 / ( 3.0 * ( .101 - hp->kspec ) ) ); } } spec *= hp->spec; specB *= hp->spec; if( spec < 0 ) spec = 0; 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; fcolor.x = shd * tint.x; fcolor.y = shd * tint.y; fcolor.z = shd * tint.z; fcolor.x *= lum.x; fcolor.y *= lum.y; fcolor.z *= lum.z; fcolor.x += ambient[0] * tint.x; fcolor.y += ambient[1] * tint.y; fcolor.z += ambient[2] * tint.z; { fcolor.x += ( spec * lum.x ); //*tint.x); // fcolor.y += ( spec * lum.y ); //*tint.y); // fcolor.z += ( spec * lum.z ); //*tint.z); } { // fcolor.x += ( specB * lum.x ); //*tint.x); // fcolor.y += ( specB * lum.y ); //*tint.y); fcolor.z += ( specB * lum.z ); //*tint.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 } // total lights for( x = 0; x < wf->totalverts; 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; } free_geomWF( &tmpcolor ); // for (x=0;xits_flyaway; { float wt; for (xx=0;xx<20*MTdrand98(gs)+10;xx++) wt=MTdrand98(gs); if (wtrs.Gflyaway_percent) { fly=1; h->thickness/=2.0f; } else fly=0; } //MTJsrand(gs->lastSeed,gs); // reset the randome gen ss = h->rootfrizz + h->tipfrizz; freqqx = h->frizzfreqX * .5; freqqy = h->frizzfreqY * .5; freqqz = h->frizzfreqZ * .5; // if (h->frizzanim!=0.0f) if (h->frizzanim>0.0f||(h->rootfrizz>0.0f)||h->tipfrizz>0.0f||h->flyaway>0.0f||h->mess>0.0f) // if (freqq>0) { VERT offs; dv.x = 0; dv.y = 0; dv.z = 0; // aa.x=resthair[facelist[face_start[h->pid]+2]].hv[0].x; // aa.y=resthair[facelist[face_start[h->pid]+2]].hv[0].y; // aa.z=resthair[facelist[face_start[h->pid]+2]].hv[0].z; // bb.x=resthair[facelist[face_start[h->pid]]].hv[0].x; // bb.y=resthair[facelist[face_start[h->pid]]].hv[0].y; // bb.z=resthair[facelist[face_start[h->pid]]].hv[0].z; // cc.x=resthair[facelist[face_start[h->pid]+1]].hv[0].x; // cc.y=resthair[facelist[face_start[h->pid]+1]].hv[0].y; // cc.z=resthair[facelist[face_start[h->pid]+1]].hv[0].z; //aa.x=aa.x-bb.x; //aa.y=aa.y-bb.y; //aa.z=aa.z-bb.z; //aa=Vnorm(aa); //cc.x=cc.x-bb.x; //cc.y=cc.y-bb.y; //cc.z=cc.z-bb.z; //cc=Vnorm(cc); //bb=Vcross(aa,cc); //bb=Vnorm(bb); //aa=Vcross(bb,cc); //mkmatrix2(pm,aa,bb,cc,cc); //inverse(pm,ipm); //if (fly) //if (h->frizzanim!=0.0f) { amp = 1.0f; // freqx = ( freqqx ) / ( ( float )restBOUNDLENGTH ); // freqy = ( freqqy ) / ( ( float )restBOUNDLENGTH ); // freqz = ( freqqz ) / ( ( float )restBOUNDLENGTH ); freqx = freqqx / ( h->restlength * 111.1f ); freqy = freqqy / ( h->restlength * 111.1f ); freqz = freqqz / ( h->restlength * 111.1f ); // freq*= (restBOUNDLENGTH/h->restlength); if( h->slgroup == 4 ) freqx *= 56.0f; if( h->slgroup == 4 ) freqy *= 56.0f; if( h->slgroup == 4 ) freqz *= 56.0f; #ifdef EXTERNAL_COLLISION // backwards compatibility if( h->slgroup != 4 ) { freqx *= 5.0f; freqy *= 5.0f; freqz *= 5.0f; // unlock } #endif //if (h->slgroup==4) h->rootfrizz/=(float)2; //if (h->slgroup==4) h->tipfrizz/=(float)2; //offs.x=h->norm.x*(float)gt*freq; //offs.x=0; frizz animation //offs.y=h->norm.y*(float)gt*freq*.44; //offs.z=0; //offs.z=h->norm.z*(float)gt*freq; h->animdir.x = 0.0f; h->animdir.y = 1.0f; h->animdir.z = 0.0f; // h->animdir=Ganim_dir[h->slgroup]; offs.x = 0; offs.y = 0; offs.z = 0; //offs.x=gt*freqx*h->animspeed*h->animdir.x; //offs.y=gt*freqy*h->animspeed*h->animdir.y; //offs.z=gt*freqz*h->animspeed*h->animdir.z; ss *= ( float ) ( ( 6.283 / 360.0f ) * 2.0f ); ss /= 42.0f; pp = 0; // if (h->slgroup==4) pp=15-1; dv.x += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp; if( Gfast_eval == 0 ) { freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp; //#ifdef crap freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp; //#endif //#ifdef crap freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; freqx *= 2; freqy *= 2; freqz *= 2; amp /= 2.0f; offs.x *= 2.0f; offs.y *= 2.0f; offs.z *= 2.0f; dv.x += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.y += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; dv.z += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp; //#endif } } if (h->frizzanim>0.0f||(h->rootfrizz>0.0f)||h->tipfrizz>0.0f||h->flyaway>0.0f||h->mess>0.0f) { //dv=Vnorm(dv); dv.x *= ( 1.0 - h->frizzanim ); dv.y *= ( 1.0 - h->frizzanim ); dv.z *= ( 1.0 - h->frizzanim ); dv2.x = 0; dv2.y = 0; dv2.z = 0; if( h->frizzanim != 0.0f ) { amp = 1.0f; // freqx = ( freqqx ) / ( ( float )restBOUNDLENGTH ); // freqy = ( freqqy ) / ( ( float )restBOUNDLENGTH ); // freqz = ( freqqz ) / ( ( float )restBOUNDLENGTH ); freqx /= ( 40.0f ); freqy /= ( 40.0f ); freqz /= ( 40.0f ); freqx /= 2.0f; freqy /= 2.0f; freqz /= 2.0f; // freq*= (restBOUNDLENGTH/h->restlength); if( h->slgroup == 4 ) freqx *= 1.0f; if( h->slgroup == 4 ) freqy *= 1.0f; if( h->slgroup == 4 ) freqz *= 1.0f; //if (h->slgroup==4) h->rootfrizz/=(float)2; //if (h->slgroup==4) h->tipfrizz/=(float)2; //offs.x=h->norm.x*(float)gt*freq; //offs.x=0; frizz animation //offs.y=h->norm.y*(float)gt*freq*.44; //offs.z=0; //offs.z=h->norm.z*(float)gt*freq; h->animdir.x = 0.0f; h->animdir.y = 1.0f; h->animdir.z = 0.0f; // h->animdir=Ganim_dir[h->slgroup]; offs.x = gt * freqx * h->animspeed * h->animdir.x; offs.y = gt * freqy * h->animspeed * h->animdir.y; offs.z = gt * freqz * h->animspeed * h->animdir.z; // ss*=(float)((6.283/360.0f)*2.0f); // ss/=42.0f; pp = 0; // if (h->slgroup==4) pp=15-1; dv2.x += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + .5f, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp * .25f; dv2.y += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y + .5f, h->noisev[pp].z * freqz + offs.z ) - ( float ) .5 ) * amp * .25f; dv2.z += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x, h->noisev[pp].y * freqy + offs.y, h->noisev[pp].z * freqz + offs.z + .5f ) - ( float ) .5 ) * amp * .25f; if( Gfast_eval == 0 ) { offs.x *= 1.1f; offs.y *= 1.1f; offs.z *= 1.1f; freqx *= 2.0f; freqy *= 2.0f; freqz *= 2.0f; amp /= 2.0f; dv2.x += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + .5f + 48.0f, h->noisev[pp].y * freqy + offs.y + 32.0f, h->noisev[pp].z * freqz + offs.z + 12.0f ) - ( float ) .5 ) * amp * .25f; dv2.y += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + 48.0f, h->noisev[pp].y * freqy + offs.y + .5f + 32.0f, h->noisev[pp].z * freqz + offs.z + 12.0f ) - ( float ) .5 ) * amp * .25f; dv2.z += ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + 48.0f, h->noisev[pp].y * freqy + offs.y + 32.0f, h->noisev[pp].z * freqz + offs.z + .5f + 12.0f ) - ( float ) .5 ) * amp * .25f; offs.x /= 1.1f; offs.y /= 1.1f; offs.z /= 1.1f; freqx *= 2.0f; freqy *= 2.0f; freqz *= 2.0f; offs.x *= 1.13f; offs.y *= 1.13f; offs.z *= 1.13f; dv2.x += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + .5f + 18.0f, h->noisev[pp].y * freqy + offs.y + 42.0f, h->noisev[pp].z * freqz + offs.z + 22.0f ) - ( float ) .5 ) * amp * .25f - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + 18.0f, h->noisev[pp].y * freqy + offs.y + 42.0f, h->noisev[pp].z * freqz + offs.z + 22.0f ) - ( float ) .5 ) * amp * .25f; dv2.y += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + 18.0f, h->noisev[pp].y * freqy + offs.y + .5f + 42.0f, h->noisev[pp].z * freqz + offs.z + 22.0f ) - ( float ) .5 ) * amp * .25f - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + 18.0f, h->noisev[pp].y * freqy + offs.y + 42.0f, h->noisev[pp].z * freqz + offs.z + 22.0f ) - ( float ) .5 ) * amp * .25f; dv2.z += ( float ) ( getnoise ( h->noisev[pp].x * freqx + offs.x + 18.0f, h->noisev[pp].y * freqy + offs.y + 42.0f, h->noisev[pp].z * freqz + offs.z + .5f + 22.0f ) - ( float ) .5 ) * amp * .25f - ( float ) ( getnoise( h->noisev[pp].x * freqx + offs.x + 18.0f, h->noisev[pp].y * freqy + offs.y + 42.0f, h->noisev[pp].z * freqz + offs.z + 12.0f ) - ( float ) .5 ) * amp * .25f; offs.x /= 1.13f; offs.y /= 1.13f; offs.z /= 1.13f; } //dv2=Vnorm(dv2); dv2.x *= h->frizzanim; dv2.y *= h->frizzanim; dv2.z *= h->frizzanim; } dv.x += dv2.x; dv.y += dv2.y; dv.z += dv2.z; dv.x = dv.x + ( dv.x * .05 ) * MTdrand98( gs ); dv.y = dv.y + ( dv.y * .05 ) * MTdrand98( gs ); dv.z = dv.z + ( dv.z * .05 ) * MTdrand98( gs ); dv.x = -dv.x; dv.y = -dv.y; dv.z = -dv.z; //dv.x -= .5; //dv.y -= .5; //dv.z -= .5; //mk_polymat(pm,h->pid); //inverse(pm,ipm); if ((h->rootfrizz>0.0f)||h->tipfrizz>0.0f||h->flyaway>0.0f||h->mess>0.0f) { float st; VERT dv3; float rf, tf; rf = h->rootfrizz / 2.0f; tf = h->tipfrizz / 2.0f; if( h->slgroup == 4 ) { rf /= 4.0f; tf /= 4.0f; } for( xx = 1; xx < 15; xx++ ) { float qq; qq = ( xx / ( float ) 15.0f ); qq = ( ( float ) 1.0 - qq ) * tf + qq * rf; qq *= ( float ) 3.14 / ( float ) 180.0f; qq *= ( float ) .5; //if (h->its_flyaway) if (fly) qq += h->flyaway*10.0f*( xx / ( float ) 15.0f ); { rotx( mr1, dv.x*qq ); rotz( mr3, dv.z*qq ); roty( mr2, dv.y*qq ); } h->hv[xx].x -= h->hv[0].x; h->hv[xx].y -= h->hv[0].y; h->hv[xx].z -= h->hv[0].z; // h->hv[xx]=vxm(ipm,h->hv[xx]); h->hv[xx] = vxm( mr1, h->hv[xx] ); h->hv[xx] = vxm( mr3, h->hv[xx] ); h->hv[xx] = vxm( mr2, h->hv[xx] ); // h->hv[xx]=vxm(mr3,h->hv[xx]); // h->hv[xx]=vxm(pm,h->hv[xx]); //if (fly) if (fly) { float hm; float ddx,ddy,ddz; hm=h->mess*h->restlength; h->hv[xx].x+=hm*(MTdrand98(gs)-0.5f); h->hv[xx].y+=hm*(MTdrand98(gs)-0.5f); h->hv[xx].z+=hm*(MTdrand98(gs)-0.5f); { h->hv[xx].x*=(1.0f+h->flyaway*1.2f); h->hv[xx].y*=(1.0f+h->flyaway*1.2f); h->hv[xx].z*=(1.0f+h->flyaway*1.2f); } // h->hv[xx].y+=h->mess*MTdrand98(gs)-h->mess/2.0f; // h->hv[xx].z+=h->mess*MTdrand98(gs)-h->mess/2.0f; } h->hv[xx].x += h->hv[0].x; h->hv[xx].y += h->hv[0].y; h->hv[xx].z += h->hv[0].z; } } } } // Gcurpass = oc; // h->hv[14]=h->hv[13]; // return (h); //MTJsrand(gs->lastSeed,gs); // reset the randome gen } //#ifdef crap //#ifdef MAYA3D // this is the older slower one static void camspace_clipit( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ) { int pl; WFTYPE tempp; WFTYPE newpp; WFTYPE tempworld; WFTYPE newworld; int clipoff = 0; int totalp = 0; int totalnewp = 0; int x; float dist; if ( ret->v != NULL ) free_geomWF( ret ); init_geomWF( &tempp ); init_geomWF( &newpp ); init_geomWF( &tempworld ); init_geomWF( &newworld ); tempp.totalverts = 15; tempp.totalfaces = 1; tempp.totalfverts = 15; alloc_geomWF( &tempp ); tempworld.totalverts = 15; tempworld.totalfaces = 1; tempworld.totalfverts = 15; alloc_geomWF( &tempworld ); newpp.totalverts = 15; newpp.totalfaces = 1; newpp.totalfverts = 15; alloc_geomWF( &newpp ); newworld.totalverts = 15; newworld.totalfaces = 1; newworld.totalfverts = 15; alloc_geomWF( &newworld ); tempworld.totalverts = 0; tempworld.totalfaces = 0; tempworld.totalfverts = 0; tempp.totalverts = 0; tempp.totalfaces = 0; tempp.totalfverts = 0; newpp.totalverts = 0; newpp.totalfaces = 0; newpp.totalfverts = 0; newworld.totalverts = 0; newworld.totalfaces = 0; newworld.totalfverts = 0; // stuff the polygon into tempp for ( x = 0; x < 3; x++ ) { tempworld.v[x] = pp.w[x]; tempp.v[x] = pp.p[x]; tempp.color[x] = pp.c[x]; tempp.velocity[x] = pp.v[x]; tempp.facelist[tempp.totalverts] = tempp.totalverts; tempp.totalverts++; } tempp. totalfverts = tempp.totalverts; tempp.totalfaces++; newpp.totalverts = 0; totalp = tempp.totalverts; for( pl = 0; pl <= 4; pl++ ) // cycle through all the clip planes if( clipoff == 0 ) { int xx; int reject = 0; totalp = tempp.totalverts; newpp.totalverts = 0; for( x = 0; x < totalp; x++ ) { int x1; x1 = ( x + 1 ) % ( totalp ); // check for borders; // 0 if( pl == 1 ) { int st1 = 0, st2 = 0; if( tempp.v[x].y >= ys ) st1 = 1; if( tempp.v[x].y < ys ) st1 = 0; if( tempp.v[x1].y >= ys ) st2 = 1; if( tempp.v[x1].y < ys ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) reject++; if( st1 == 0 ) // states are different, ones above the other's below { // the base point is inside this plane newworld.v[newpp.totalverts].x = tempworld.v[x].x; newworld.v[newpp.totalverts].y = tempworld.v[x].y; newworld.v[newpp.totalverts].z = tempworld.v[x].z; newpp.v[newpp.totalverts].x = tempp.v[x].x; newpp.v[newpp.totalverts].y = tempp.v[x].y; newpp.v[newpp.totalverts].z = tempp.v[x].z; newpp.color[newpp.totalverts].x = tempp.color[x].x; newpp.color[newpp.totalverts].y = tempp.color[x].y; newpp.color[newpp.totalverts].z = tempp.color[x].z; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z; newpp.totalverts++; } if( st1 != st2 ) // states are different, one's above the other's below so we'll need to ad an inbetween { // there's an intersection, calculate the point and add it to a stack { float dd, td = 0.0f, perc = 0.0f; // printf ("clipping pl 0\n"); dd = ys - tempp.v[x].y; td = ( tempp.v[x1].y - tempp.v[x].y ); perc = 0.0f; if( td != 0.0f ) perc = dd / td; perc = fabs( perc ); newpp.v[newpp.totalverts].x = tempp.v[x].x + ( tempp.v[x1].x - tempp.v[x].x ) * perc; newpp.v[newpp.totalverts].y = tempp.v[x].y + ( tempp.v[x1].y - tempp.v[x].y ) * perc; newpp.v[newpp.totalverts].z = tempp.v[x].z + ( tempp.v[x1].z - tempp.v[x].z ) * perc; newpp.color[newpp.totalverts].x = tempp.color[x].x + ( tempp.color[x1].x - tempp.color[x].x ) * perc; newpp.color[newpp.totalverts].y = tempp.color[x].y + ( tempp.color[x1].y - tempp.color[x].y ) * perc; newpp.color[newpp.totalverts].z = tempp.color[x].z + ( tempp.color[x1].z - tempp.color[x].z ) * perc; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x + ( tempp.velocity[x1].x - tempp.velocity[x].x ) * perc; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y + ( tempp.velocity[x1].y - tempp.velocity[x].y ) * perc; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z + ( tempp.velocity[x1].z - tempp.velocity[x].z ) * perc; newworld.v[newpp.totalverts].x = tempworld.v[x].x + ( tempworld.v[x1].x - tempworld.v[x].x ) * perc; newworld.v[newpp.totalverts].y = tempworld.v[x].y + ( tempworld.v[x1].y - tempworld.v[x].y ) * perc; newworld.v[newpp.totalverts].z = tempworld.v[x].z + ( tempworld.v[x1].z - tempworld.v[x].z ) * perc; } newpp.totalverts++; } } // check for borders; // 1 if( pl == 2 ) { int st1 = 0, st2 = 0; if( tempp.v[x].x >= xs ) st1 = 1; if( tempp.v[x].x < xs ) st1 = 0; if( tempp.v[x1].x >= xs ) st2 = 1; if( tempp.v[x1].x < xs ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) reject++; if( st1 == 0 ) // states are different, ones above the other's below { // the base point is inside this plane newworld.v[newpp.totalverts].x = tempworld.v[x].x; newworld.v[newpp.totalverts].y = tempworld.v[x].y; newworld.v[newpp.totalverts].z = tempworld.v[x].z; newpp.v[newpp.totalverts].x = tempp.v[x].x; newpp.v[newpp.totalverts].y = tempp.v[x].y; newpp.v[newpp.totalverts].z = tempp.v[x].z; newpp.color[newpp.totalverts].x = tempp.color[x].x; newpp.color[newpp.totalverts].y = tempp.color[x].y; newpp.color[newpp.totalverts].z = tempp.color[x].z; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z; newpp.totalverts++; } if( st1 != st2 ) // states are different, ones above the other's below { // printf ("clipping pl l\n"); { float dd, td = 0.0f, perc = 0.0f; dd = xs - tempp.v[x].x; td = ( tempp.v[x1].x - tempp.v[x].x ); perc = 0.0f; if( td != 0.0f ) perc = dd / td; perc = fabs( perc ); newpp.v[newpp.totalverts].x = tempp.v[x].x + ( tempp.v[x1].x - tempp.v[x].x ) * perc; newpp.v[newpp.totalverts].y = tempp.v[x].y + ( tempp.v[x1].y - tempp.v[x].y ) * perc; newpp.v[newpp.totalverts].z = tempp.v[x].z + ( tempp.v[x1].z - tempp.v[x].z ) * perc; newpp.color[newpp.totalverts].x = tempp.color[x].x + ( tempp.color[x1].x - tempp.color[x].x ) * perc; newpp.color[newpp.totalverts].y = tempp.color[x].y + ( tempp.color[x1].y - tempp.color[x].y ) * perc; newpp.color[newpp.totalverts].z = tempp.color[x].z + ( tempp.color[x1].z - tempp.color[x].z ) * perc; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x + ( tempp.velocity[x1].x - tempp.velocity[x].x ) * perc; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y + ( tempp.velocity[x1].y - tempp.velocity[x].y ) * perc; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z + ( tempp.velocity[x1].z - tempp.velocity[x].z ) * perc; newworld.v[newpp.totalverts].x = tempworld.v[x].x + ( tempworld.v[x1].x - tempworld.v[x].x ) * perc; newworld.v[newpp.totalverts].y = tempworld.v[x].y + ( tempworld.v[x1].y - tempworld.v[x].y ) * perc; newworld.v[newpp.totalverts].z = tempworld.v[x].z + ( tempworld.v[x1].z - tempworld.v[x].z ) * perc; } // there's an intersection, calculate the point and add it to a stack newpp.totalverts++; } } // check for borders; // 2 if( pl == 3 ) { int st1 = 0, st2 = 0; if( tempp.v[x].y < yl ) st1 = 1; if( tempp.v[x].y >= yl ) st1 = 0; if( tempp.v[x1].y < yl ) st2 = 1; if( tempp.v[x1].y >= yl ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) reject++; if( st1 == 0 ) // states are different, ones above the other's below { // the base point is inside this plane newworld.v[newpp.totalverts].x = tempworld.v[x].x; newworld.v[newpp.totalverts].y = tempworld.v[x].y; newworld.v[newpp.totalverts].z = tempworld.v[x].z; newpp.v[newpp.totalverts].x = tempp.v[x].x; newpp.v[newpp.totalverts].y = tempp.v[x].y; newpp.v[newpp.totalverts].z = tempp.v[x].z; newpp.color[newpp.totalverts].x = tempp.color[x].x; newpp.color[newpp.totalverts].y = tempp.color[x].y; newpp.color[newpp.totalverts].z = tempp.color[x].z; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z; newpp.totalverts++; } if( st1 != st2 ) // states are different, ones above the other's below { // there's an intersection, calculate the point and add it to a stack float dd, td = 0.0f, perc = 0.0f; // printf ("clipping pl 2\n"); dd = yl - tempp.v[x].y; td = ( tempp.v[x1].y - tempp.v[x].y ); // dd=tempp.v[x].y-yl; // td=(tempp.v[x1].y-tempp.v[x].y); if( td != 0.0f ) perc = dd / td; perc = fabs( perc ); newpp.v[newpp.totalverts].x = tempp.v[x].x + ( tempp.v[x1].x - tempp.v[x].x ) * perc; newpp.v[newpp.totalverts].y = tempp.v[x].y + ( tempp.v[x1].y - tempp.v[x].y ) * perc; newpp.v[newpp.totalverts].z = tempp.v[x].z + ( tempp.v[x1].z - tempp.v[x].z ) * perc; newpp.color[newpp.totalverts].x = tempp.color[x].x + ( tempp.color[x1].x - tempp.color[x].x ) * perc; newpp.color[newpp.totalverts].y = tempp.color[x].y + ( tempp.color[x1].y - tempp.color[x].y ) * perc; newpp.color[newpp.totalverts].z = tempp.color[x].z + ( tempp.color[x1].z - tempp.color[x].z ) * perc; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x + ( tempp.velocity[x1].x - tempp.velocity[x].x ) * perc; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y + ( tempp.velocity[x1].y - tempp.velocity[x].y ) * perc; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z + ( tempp.velocity[x1].z - tempp.velocity[x].z ) * perc; newworld.v[newpp.totalverts].x = tempworld.v[x].x + ( tempworld.v[x1].x - tempworld.v[x].x ) * perc; newworld.v[newpp.totalverts].y = tempworld.v[x].y + ( tempworld.v[x1].y - tempworld.v[x].y ) * perc; newworld.v[newpp.totalverts].z = tempworld.v[x].z + ( tempworld.v[x1].z - tempworld.v[x].z ) * perc; // there's an intersection, calculate the point and add it to a stack newpp.totalverts++; } } // check for borders; // 3 if( pl == 4 ) { int st1 = 0, st2 = 0; if( tempp.v[x].x < xl ) st1 = 1; if( tempp.v[x].x >= xl ) st1 = 0; if( tempp.v[x1].x < xl ) st2 = 1; if( tempp.v[x1].x >= xl ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) reject++; if( st1 == 0 ) // states are different, ones above the other's below { // the base point is inside this plane newworld.v[newpp.totalverts].x = tempworld.v[x].x; newworld.v[newpp.totalverts].y = tempworld.v[x].y; newworld.v[newpp.totalverts].z = tempworld.v[x].z; newpp.v[newpp.totalverts].x = tempp.v[x].x; newpp.v[newpp.totalverts].y = tempp.v[x].y; newpp.v[newpp.totalverts].z = tempp.v[x].z; newpp.color[newpp.totalverts].x = tempp.color[x].x; newpp.color[newpp.totalverts].y = tempp.color[x].y; newpp.color[newpp.totalverts].z = tempp.color[x].z; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z; newpp.totalverts++; } if( st1 != st2 ) // states are different, ones above the other's below { // printf ("clipping pl 3\n"); { // there's an intersection, calculate the point and add it to a stack float dd, td, perc = 0.0f; dd = xl - tempp.v[x].x; td = ( tempp.v[x1].x - tempp.v[x].x ); perc = 0.0f; if( td != 0.0f ) perc = dd / td; perc = fabs( perc ); newpp.v[newpp.totalverts].x = tempp.v[x].x + ( tempp.v[x1].x - tempp.v[x].x ) * perc; newpp.v[newpp.totalverts].y = tempp.v[x].y + ( tempp.v[x1].y - tempp.v[x].y ) * perc; newpp.v[newpp.totalverts].z = tempp.v[x].z + ( tempp.v[x1].z - tempp.v[x].z ) * perc; newpp.color[newpp.totalverts].x = tempp.color[x].x + ( tempp.color[x1].x - tempp.color[x].x ) * perc; newpp.color[newpp.totalverts].y = tempp.color[x].y + ( tempp.color[x1].y - tempp.color[x].y ) * perc; newpp.color[newpp.totalverts].z = tempp.color[x].z + ( tempp.color[x1].z - tempp.color[x].z ) * perc; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x + ( tempp.velocity[x1].x - tempp.velocity[x].x ) * perc; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y + ( tempp.velocity[x1].y - tempp.velocity[x].y ) * perc; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z + ( tempp.velocity[x1].z - tempp.velocity[x].z ) * perc; newworld.v[newpp.totalverts].x = tempworld.v[x].x + ( tempworld.v[x1].x - tempworld.v[x].x ) * perc; newworld.v[newpp.totalverts].y = tempworld.v[x].y + ( tempworld.v[x1].y - tempworld.v[x].y ) * perc; newworld.v[newpp.totalverts].z = tempworld.v[x].z + ( tempworld.v[x1].z - tempworld.v[x].z ) * perc; } newpp.totalverts++; } } // check for borders; // nearclip // 4 if( pl == 0 ) { int st1 = 0, st2 = 0; float dr1 = 0.0f, dr2 = 0.0f; VERT pln; VERT vc1, vc2; VERT nrm; VERT ca, ba; float cad, bad; nrm.x = current_cam->view[0][2]; nrm.y = current_cam->view[1][2]; nrm.z = current_cam->view[2][2]; pln.x = current_cam->wpos.x + nrm.x * current_cam->zoom * .01; pln.y = current_cam->wpos.y + nrm.y * current_cam->zoom * .01; pln.z = current_cam->wpos.z + nrm.z * current_cam->zoom * .01; vc1.x = tempworld.v[x].x - pln.x; vc1.y = tempworld.v[x].y - pln.y; vc1.z = tempworld.v[x].z - pln.z; vc1 = Vnorm( vc1 ); dr1 = VDot( vc1, nrm ); vc2.x = tempworld.v[x1].x - pln.x; vc2.y = tempworld.v[x1].y - pln.y; vc2.z = tempworld.v[x1].z - pln.z; vc2 = Vnorm( vc2 ); dr2 = VDot( vc2, nrm ); if( dr1 <= 0 ) st1 = 1; if( dr1 > 0 ) st1 = 0; if( dr2 <= 0 ) st2 = 1; if( dr2 > 0 ) st2 = 0; if( ( st1 == 1 ) && ( st2 == 1 ) ) reject++; // if (st1==1) //printf ("clip\n"); if( st1 == 0 ) // states are different, ones above the other's below { // the base point is inside this plane newworld.v[newpp.totalverts].x = tempworld.v[x].x; newworld.v[newpp.totalverts].y = tempworld.v[x].y; newworld.v[newpp.totalverts].z = tempworld.v[x].z; newpp.v[newpp.totalverts].x = tempp.v[x].x; newpp.v[newpp.totalverts].y = tempp.v[x].y; newpp.v[newpp.totalverts].z = tempp.v[x].z; newpp.color[newpp.totalverts].x = tempp.color[x].x; newpp.color[newpp.totalverts].y = tempp.color[x].y; newpp.color[newpp.totalverts].z = tempp.color[x].z; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z; newpp.totalverts++; } if( st1 != st2 ) // states are different, ones above the other's below { // there's an intersection, calculate the point and add it to a stack float dd, td = 0.0f, perc = 0.0f; //printf ("clippit\n"); ca.x = pln.x - tempworld.v[x].x; ca.y = pln.y - tempworld.v[x].y; ca.z = pln.z - tempworld.v[x].z; ba.x = tempworld.v[x1].x - tempworld.v[x].x; ba.y = tempworld.v[x1].y - tempworld.v[x].y; ba.z = tempworld.v[x1].z - tempworld.v[x].z; //ca=Vnorm(ca); //ba=Vnorm(ba); cad = VDot( ca, nrm ); bad = VDot( ba, nrm ); if( bad != 0 ) perc = cad / bad; perc = fabs( perc ); // perc= (1.0-perc); // printf ("intersect %f\n",perc); //perc= - perc; newworld.v[newpp.totalverts].x = tempworld.v[x].x + ( tempworld.v[x1].x - tempworld.v[x].x ) * perc; newworld.v[newpp.totalverts].y = tempworld.v[x].y + ( tempworld.v[x1].y - tempworld.v[x].y ) * perc; newworld.v[newpp.totalverts].z = tempworld.v[x].z + ( tempworld.v[x1].z - tempworld.v[x].z ) * perc; // wait I think I need to get a new projection on this point newpp.v[newpp.totalverts] = world2cam1( current_cam, newworld.v[newpp.totalverts] ); // newpp.v[newpp.totalverts].x=tempp.v[x].x+(tempp.v[x1].x-tempp.v[x].x)*perc; // newpp.v[newpp.totalverts].y=tempp.v[x].y+(tempp.v[x1].y-tempp.v[x].y)*perc; // newpp.v[newpp.totalverts].z=tempp.v[x].z+(tempp.v[x1].z-tempp.v[x].z)*perc; newpp.color[newpp.totalverts].x = tempp.color[x].x + ( tempp.color[x1].x - tempp.color[x].x ) * perc; newpp.color[newpp.totalverts].y = tempp.color[x].y + ( tempp.color[x1].y - tempp.color[x].y ) * perc; newpp.color[newpp.totalverts].z = tempp.color[x].z + ( tempp.color[x1].z - tempp.color[x].z ) * perc; newpp.velocity[newpp.totalverts].x = tempp.velocity[x].x + ( tempp.velocity[x1].x - tempp.velocity[x].x ) * perc; newpp.velocity[newpp.totalverts].y = tempp.velocity[x].y + ( tempp.velocity[x1].y - tempp.velocity[x].y ) * perc; newpp.velocity[newpp.totalverts].z = tempp.velocity[x].z + ( tempp.velocity[x1].z - tempp.velocity[x].z ) * perc; newpp.totalverts++; } } // done checking lateral borders // stuff newp into tempp } // x (points) if( reject > 3 ) clipoff = 1; for( xx = 0; xx < newpp.totalverts; xx++ ) { tempworld.v[xx] = newworld.v[xx]; tempp.v[xx] = newpp.v[xx]; tempp.color[xx] = newpp.color[xx]; tempp.velocity[xx] = newpp.velocity[xx]; } tempp.totalverts = newpp.totalverts; } // pl ret->totalverts = newpp.totalverts; ret->totalfaces = 1; ret->totalfverts = newpp.totalfverts; alloc_geomWF( ret ); for( x = 0; x < newpp.totalverts; x++ ) { ret->v[x] = newpp.v[x]; ret->color[x] = newpp.color[x]; ret->velocity[x] = newpp.velocity[x]; } // stuff tempp into ret free_geomWF( &newpp ); free_geomWF( &tempp ); free_geomWF( &newworld ); free_geomWF( &tempworld ); } //#endif //#endif //#endif static void camspace_clipLine( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */ ) { int inCount; int pl; int clipoff = 0; int totalp = 0; int x; VERT nrm; VERT pln; float zoomFactor; POLYDAT outPP; nrm.x = current_cam->view[0][2]; nrm.y = current_cam->view[1][2]; nrm.z = current_cam->view[2][2]; zoomFactor = current_cam->zoom * 0.01f; pln.x = current_cam->wpos.x + nrm.x * zoomFactor; pln.y = current_cam->wpos.y + nrm.y * zoomFactor; pln.z = current_cam->wpos.z + nrm.z * zoomFactor; for ( x = 0; x < 2; x++ ) { outPP.w[x] = pp->w[x]; outPP.wv[x] = pp->wv[x]; outPP.c[x] = pp->c[x]; outPP.p[x] = pp->p[x]; outPP.rad[x] = pp->rad[x]; } { int outCount = 0; int xx; int reject = 0; for( x = 0; x < 2; x++ ) { float dd, td, perc; int st1, st2; int x1; x1 = ( x + 1 ) % 2; // 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 ) { reject++; } else { if( !st1 ) { outPP.w[outCount] = pp->w[x]; outPP.wv[outCount] = pp->wv[x]; outPP.c[outCount] = pp->c[x]; outPP.p[outCount] = pp->p[x]; outPP.rad[outCount] = pp->rad[x]; outCount++; } 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; outPP.w[outCount].x = pp->w[x].x + ( pp->w[x1].x - pp->w[x].x ) * perc; outPP.w[outCount].y = pp->w[x].y + ( pp->w[x1].y - pp->w[x].y ) * perc; outPP.w[outCount].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 outPP.p[outCount] = world2cam1( current_cam, outPP.w[outCount] ); outPP.c[outCount].x = pp->c[x].x + ( pp->c[x1].x - pp->c[x].x ) * perc; outPP.c[outCount].y = pp->c[x].y + ( pp->c[x1].y - pp->c[x].y ) * perc; outPP.c[outCount].z = pp->c[x].z + ( pp->c[x1].z - pp->c[x].z ) * perc; outPP.v[outCount].x = pp->v[x].x + ( pp->v[x1].x - pp->v[x].x ) * perc; outPP.v[outCount].y = pp->v[x].y + ( pp->v[x1].y - pp->v[x].y ) * perc; outPP.v[outCount].z = pp->v[x].z + ( pp->v[x1].z - pp->v[x].z ) * perc; outPP.rad[outCount] = pp->rad[x] + ( pp->rad[x1] - pp->rad[x] ) * perc; outCount++; } } } } // x (points) } { int st0 = 0, st1 = 0; int done = 0; if( outPP.p[0].x < xl ) st0 = 1; if( outPP.p[1].x < xl ) st1 = 1; if( st0 && st1 ) { outPP.p[0].x = xl - 1; outPP.p[1].x = xl - 1; outPP.p[0].y = yl - 1; outPP.p[1].y = yl - 1; done = 1; } if( done == 0 ) { if( st0 != st1 ) // ok we gotta clip { if( st1 ) // clipping st1 { float perc; VERT delt; delt.x = outPP.p[1].x - outPP.p[0].x; delt.y = outPP.p[1].y - outPP.p[0].y; delt.z = outPP.p[1].z - outPP.p[0].z; perc = ( xl - outPP.p[0].x ) / ( delt.x ); outPP.p[1].x = outPP.p[0].x + perc * delt.x; outPP.p[1].y = outPP.p[0].y + perc * delt.y; outPP.p[1].z = outPP.p[0].z + perc * delt.z; delt.x = outPP.w[1].x - outPP.w[0].x; delt.y = outPP.w[1].y - outPP.w[0].y; delt.z = outPP.w[1].z - outPP.w[0].z; outPP.w[1].x = outPP.w[0].x + perc * delt.x; outPP.w[1].y = outPP.w[0].y + perc * delt.y; outPP.w[1].z = outPP.w[0].z + perc * delt.z; delt.x = outPP.c[1].x - outPP.c[0].x; delt.y = outPP.c[1].y - outPP.c[0].y; delt.z = outPP.c[1].z - outPP.c[0].z; outPP.c[1].x = outPP.c[0].x + perc * delt.x; outPP.c[1].y = outPP.c[0].y + perc * delt.y; outPP.c[1].z = outPP.c[0].z + perc * delt.z; delt.x = outPP.rad[1] - outPP.rad[0]; outPP.rad[1] = outPP.rad[0] + perc * delt.x; } if( st0 ) // clipping st0 { float perc; VERT delt; delt.x = outPP.p[0].x - outPP.p[1].x; delt.y = outPP.p[0].y - outPP.p[1].y; delt.z = outPP.p[0].z - outPP.p[1].z; perc = ( xl - outPP.p[1].x ) / ( delt.x ); outPP.p[0].x = outPP.p[1].x + perc * delt.x; outPP.p[0].y = outPP.p[1].y + perc * delt.y; outPP.p[0].z = outPP.p[1].z + perc * delt.z; delt.x = outPP.w[0].x - outPP.w[1].x; delt.y = outPP.w[0].y - outPP.w[1].y; delt.z = outPP.w[0].z - outPP.w[1].z; outPP.w[0].x = outPP.w[1].x + perc * delt.x; outPP.w[0].y = outPP.w[1].y + perc * delt.y; outPP.w[0].z = outPP.w[1].z + perc * delt.z; delt.x = outPP.c[0].x - outPP.c[1].x; delt.y = outPP.c[0].y - outPP.c[1].y; delt.z = outPP.c[0].z - outPP.c[1].z; outPP.c[0].x = outPP.c[1].x + perc * delt.x; outPP.c[0].y = outPP.c[1].y + perc * delt.y; outPP.c[0].z = outPP.c[1].z + perc * delt.z; delt.x = outPP.rad[0] - outPP.rad[1]; outPP.rad[0] = outPP.rad[1] + perc * delt.x; } } } } { int st0 = 0, st1 = 0; int done = 0; if( outPP.p[0].x >= xs ) st0 = 1; if( outPP.p[1].x >= xs ) st1 = 1; if( st0 && st1 ) { outPP.p[0].x = xl - 1; outPP.p[1].x = xl - 1; outPP.p[0].y = yl - 1; outPP.p[1].y = yl - 1; done = 1; } if( done == 0 ) { if( st0 != st1 ) // ok we gotta clip { if( st1 ) // clipping st1 { float perc; VERT delt; delt.x = outPP.p[1].x - outPP.p[0].x; delt.y = outPP.p[1].y - outPP.p[0].y; delt.z = outPP.p[1].z - outPP.p[0].z; perc = ( xs - outPP.p[0].x ) / ( delt.x ); outPP.p[1].x = outPP.p[0].x + perc * delt.x; outPP.p[1].y = outPP.p[0].y + perc * delt.y; outPP.p[1].z = outPP.p[0].z + perc * delt.z; delt.x = outPP.w[1].x - outPP.w[0].x; delt.y = outPP.w[1].y - outPP.w[0].y; delt.z = outPP.w[1].z - outPP.w[0].z; outPP.w[1].x = outPP.w[0].x + perc * delt.x; outPP.w[1].y = outPP.w[0].y + perc * delt.y; outPP.w[1].z = outPP.w[0].z + perc * delt.z; delt.x = outPP.c[1].x - outPP.c[0].x; delt.y = outPP.c[1].y - outPP.c[0].y; delt.z = outPP.c[1].z - outPP.c[0].z; outPP.c[1].x = outPP.c[0].x + perc * delt.x; outPP.c[1].y = outPP.c[0].y + perc * delt.y; outPP.c[1].z = outPP.c[0].z + perc * delt.z; delt.x = outPP.rad[1] - outPP.rad[0]; outPP.rad[1] = outPP.rad[0] + perc * delt.x; } if( st0 ) // clipping st0 { float perc; VERT delt; delt.x = outPP.p[0].x - outPP.p[1].x; delt.y = outPP.p[0].y - outPP.p[1].y; delt.z = outPP.p[0].z - outPP.p[1].z; perc = ( xs - outPP.p[1].x ) / ( delt.x ); outPP.p[0].x = outPP.p[1].x + perc * delt.x; outPP.p[0].y = outPP.p[1].y + perc * delt.y; outPP.p[0].z = outPP.p[1].z + perc * delt.z; delt.x = outPP.w[0].x - outPP.w[1].x; delt.y = outPP.w[0].y - outPP.w[1].y; delt.z = outPP.w[0].z - outPP.w[1].z; outPP.w[0].x = outPP.w[1].x + perc * delt.x; outPP.w[0].y = outPP.w[1].y + perc * delt.y; outPP.w[0].z = outPP.w[1].z + perc * delt.z; delt.x = outPP.c[0].x - outPP.c[1].x; delt.y = outPP.c[0].y - outPP.c[1].y; delt.z = outPP.c[0].z - outPP.c[1].z; outPP.c[0].x = outPP.c[1].x + perc * delt.x; outPP.c[0].y = outPP.c[1].y + perc * delt.y; outPP.c[0].z = outPP.c[1].z + perc * delt.z; delt.x = outPP.rad[0] - outPP.rad[1]; outPP.rad[0] = outPP.rad[1] + perc * delt.x; } } } } { int st0 = 0, st1 = 0; int done = 0; if( outPP.p[0].y < yl ) st0 = 1; if( outPP.p[1].y < yl ) st1 = 1; if( st0 && st1 ) { outPP.p[0].x = xl - 1; outPP.p[1].x = xl - 1; outPP.p[0].y = yl - 1; outPP.p[1].y = yl - 1; done = 1; } if( done == 0 ) { if( st0 != st1 ) // ok we gotta clip { if( st1 ) // clipping st1 { float perc; VERT delt; delt.x = outPP.p[1].x - outPP.p[0].x; delt.y = outPP.p[1].y - outPP.p[0].y; delt.z = outPP.p[1].z - outPP.p[0].z; perc = ( yl - outPP.p[0].y ) / ( delt.y ); outPP.p[1].x = outPP.p[0].x + perc * delt.x; outPP.p[1].y = outPP.p[0].y + perc * delt.y; outPP.p[1].z = outPP.p[0].z + perc * delt.z; delt.x = outPP.w[1].x - outPP.w[0].x; delt.y = outPP.w[1].y - outPP.w[0].y; delt.z = outPP.w[1].z - outPP.w[0].z; outPP.w[1].x = outPP.w[0].x + perc * delt.x; outPP.w[1].y = outPP.w[0].y + perc * delt.y; outPP.w[1].z = outPP.w[0].z + perc * delt.z; delt.x = outPP.c[1].x - outPP.c[0].x; delt.y = outPP.c[1].y - outPP.c[0].y; delt.z = outPP.c[1].z - outPP.c[0].z; outPP.c[1].x = outPP.c[0].x + perc * delt.x; outPP.c[1].y = outPP.c[0].y + perc * delt.y; outPP.c[1].z = outPP.c[0].z + perc * delt.z; delt.x = outPP.rad[1] - outPP.rad[0]; outPP.rad[1] = outPP.rad[0] + perc * delt.x; } if( st0 ) // clipping st0 { float perc; VERT delt; delt.x = outPP.p[0].x - outPP.p[1].x; delt.y = outPP.p[0].y - outPP.p[1].y; delt.z = outPP.p[0].z - outPP.p[1].z; perc = ( yl - outPP.p[1].y ) / ( delt.y ); outPP.p[0].x = outPP.p[1].x + perc * delt.x; outPP.p[0].y = outPP.p[1].y + perc * delt.y; outPP.p[0].z = outPP.p[1].z + perc * delt.z; delt.x = outPP.w[0].x - outPP.w[1].x; delt.y = outPP.w[0].y - outPP.w[1].y; delt.z = outPP.w[0].z - outPP.w[1].z; outPP.w[0].x = outPP.w[1].x + perc * delt.x; outPP.w[0].y = outPP.w[1].y + perc * delt.y; outPP.w[0].z = outPP.w[1].z + perc * delt.z; delt.x = outPP.c[0].x - outPP.c[1].x; delt.y = outPP.c[0].y - outPP.c[1].y; delt.z = outPP.c[0].z - outPP.c[1].z; outPP.c[0].x = outPP.c[1].x + perc * delt.x; outPP.c[0].y = outPP.c[1].y + perc * delt.y; outPP.c[0].z = outPP.c[1].z + perc * delt.z; delt.x = outPP.rad[0] - outPP.rad[1]; outPP.rad[0] = outPP.rad[1] + perc * delt.x; } } } } { int st0 = 0, st1 = 0; int done = 0; if( outPP.p[0].y >= ys ) st0 = 1; if( outPP.p[1].y >= ys ) st1 = 1; if( st0 && st1 ) { outPP.p[0].x = xl - 1; outPP.p[1].x = xl - 1; outPP.p[0].y = yl - 1; outPP.p[1].y = yl - 1; done = 1; } if( done == 0 ) { if( st0 != st1 ) // ok we gotta clip { if( st1 ) // clipping st1 { float perc; VERT delt; delt.x = outPP.p[1].x - outPP.p[0].x; delt.y = outPP.p[1].y - outPP.p[0].y; delt.z = outPP.p[1].z - outPP.p[0].z; perc = ( ys - outPP.p[0].y ) / ( delt.y ); outPP.p[1].x = outPP.p[0].x + perc * delt.x; outPP.p[1].y = outPP.p[0].y + perc * delt.y; outPP.p[1].z = outPP.p[0].z + perc * delt.z; delt.x = outPP.w[1].x - outPP.w[0].x; delt.y = outPP.w[1].y - outPP.w[0].y; delt.z = outPP.w[1].z - outPP.w[0].z; outPP.w[1].x = outPP.w[0].x + perc * delt.x; outPP.w[1].y = outPP.w[0].y + perc * delt.y; outPP.w[1].z = outPP.w[0].z + perc * delt.z; delt.x = outPP.c[1].x - outPP.c[0].x; delt.y = outPP.c[1].y - outPP.c[0].y; delt.z = outPP.c[1].z - outPP.c[0].z; outPP.c[1].x = outPP.c[0].x + perc * delt.x; outPP.c[1].y = outPP.c[0].y + perc * delt.y; outPP.c[1].z = outPP.c[0].z + perc * delt.z; delt.x = outPP.rad[0] - outPP.rad[1]; outPP.rad[0] = outPP.rad[1] + perc * delt.x; } if( st0 ) // clipping st0 { float perc; VERT delt; delt.x = outPP.p[0].x - outPP.p[1].x; delt.y = outPP.p[0].y - outPP.p[1].y; delt.z = outPP.p[0].z - outPP.p[1].z; perc = ( ys - outPP.p[1].y ) / ( delt.y ); outPP.p[0].x = outPP.p[1].x + perc * delt.x; outPP.p[0].y = outPP.p[1].y + perc * delt.y; outPP.p[0].z = outPP.p[1].z + perc * delt.z; delt.x = outPP.w[0].x - outPP.w[1].x; delt.y = outPP.w[0].y - outPP.w[1].y; delt.z = outPP.w[0].z - outPP.w[1].z; outPP.w[0].x = outPP.w[1].x + perc * delt.x; outPP.w[0].y = outPP.w[1].y + perc * delt.y; outPP.w[0].z = outPP.w[1].z + perc * delt.z; delt.x = outPP.c[0].x - outPP.c[1].x; delt.y = outPP.c[0].y - outPP.c[1].y; delt.z = outPP.c[0].z - outPP.c[1].z; outPP.c[0].x = outPP.c[1].x + perc * delt.x; outPP.c[0].y = outPP.c[1].y + perc * delt.y; outPP.c[0].z = outPP.c[1].z + perc * delt.z; delt.x = outPP.rad[1] - outPP.rad[0]; outPP.rad[1] = outPP.rad[0] + perc * delt.x; } } } } memcpy( pp, &outPP, sizeof( POLYDAT ) ); } static int draw_line2new( POLYDAT pp, int layer, unsigned char lum ) { int x; int success = 0; float y; int a, b; float y1; int same = 0; float maxy = -99999, miny = 99999; int imaxy, iminy; VERT vec1, vec2; VERT cvec1, cvec2; VERT bas1, bas2; VERT cbas1, cbas2; VERT p1, p2, c1, c2; VERT zero; int pageres; int GSclipx0, GSclipx1, GSclipy0, GSclipy1; int GSxres, GSyres; float rd1, rd2; float tim = 0.0f; int offscreen = 0; float linear; if ( TILEMODE == 6 ) { current_cam = &tilebuff; } rd1 = pp.rad[0]; rd2 = pp.rad[1]; GSxres = current_cam->xres * GLOBALSAMP; GSyres = current_cam->yres * GLOBALSAMP; // if (pleft.xxres * current_cam->yres; if( TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( float ) GLOBALSAMP *( float ) GLOBALSAMP; } if( itsalight != 1 ) for( x = 0; x < 2; x++ ) { if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[cursamp * 4].x; pp.p[x].y += campass[cursamp * 4].y; } if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight == 2 ) { pp.p[x].x += calibrateX; pp.p[x].y += calibrateY; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( TILEMODE != 0 ) for( x = 0; x < 2; 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( itsalight != 1 ) cursamp = layer; tim = 0.0f; //if (0==1) //if (TILEMODE!=2) if( !( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) ) { float td; int tt; float sss[7]; float delta[7]; // 0-dx,1-dy,2-dz,3-dred,4-dgreen,5-dblue,6-dradius; // all the deltas delta[0] = pp.p[1].x - pp.p[0].x; delta[1] = pp.p[1].y - pp.p[0].y; delta[2] = pp.p[1].z - pp.p[0].z; delta[3] = pp.c[1].x - pp.c[0].x; delta[4] = pp.c[1].y - pp.c[0].y; delta[5] = pp.c[1].z - pp.c[0].z; delta[6] = rd2 - rd1; sss[0] = pp.p[0].x; sss[1] = pp.p[0].y; sss[2] = pp.p[0].z; sss[3] = pp.c[0].x; sss[4] = pp.c[0].y; sss[5] = pp.c[0].z; sss[6] = rd1; td = ( float ) sqrt( delta[0] * delta[0] + delta[1] * delta[1] ); if( td > 0 ) for( tt = 0; tt < 7; tt++ ) delta[tt] /= td; for( linear = 0; linear <= td; linear += 1.0f ) { int t; int xx, add, yy; for( yy = ( int ) ( sss[1] - sss[6] ); yy <= ( int ) ( sss[1] + sss[6] ); yy++ ) { int yclip = 1; int baseadd = 0; int gbaseadd = 0; y = yy; if( TILEMODE == 0 ) { int scanl; scanl = ( int ) yy *current_cam->xres; baseadd = scanl + layer * ( pageres ); gbaseadd = scanl + layer * ( pageres ); } if( TILEMODE != 0 ) { int gclpy; int lp; lp = layer * pageres; gclpy = ( int ) ( yy - GSclipy0 ) * alltiles.sx * GLOBALSAMP; baseadd = gclpy + lp; gbaseadd = gclpy + lp; } y1 = y; if( ( TILEMODE != 0 ) && ( ( y >= GSclipy0 ) && ( y < GSclipy1 ) ) ) yclip = 0; if( ( TILEMODE == 0 ) && ( ( y >= Gclipy0 ) && ( y < Gclipy1 ) ) ) yclip = 0; if( yclip == 0 ) for( xx = ( int ) ( sss[0] - sss[6] ); xx <= ( int ) ( sss[0] + sss[6] ); xx++ ) { int tt; int clipit = 0; VERT pc; tt = xx; pc.x = xx; pc.y = yy; pc.z = sss[2]; if( itsalight != 2 ) // we're doing a light if( itsalight > 0 ) if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) // we're doing a tile if( !( ( tt >= GSclipx0 ) && ( tt <= GSclipx1 ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) if( current_cam != &LWcam ) if( !( ( tt >= 0 ) && ( tt < GSxres ) ) ) clipit = 1; // we're doing tiles - but also clipping to the canvas if( TILEMODE == 0 ) // again - not at all sure what this is about - a light? if( current_cam != &LWcam ) if( !( ( tt >= 0 ) && ( tt < current_cam->xres ) ) ) clipit = 1; // lets draw a pixel if( clipit == 0 ) { float y2; int x2; int ok; int pixoff = 0; int aa4 = 1; float ftt, fy; float geomz = 1000000.0f; ok = 1; x2 = xx; y2 = yy; if( TILEMODE > 0 ) x2 = x2 - GSclipx0; if( TILEMODE > 0 ) y2 = y2 - GSclipy0; if( TILEMODE == 6 ) current_cam = &tilebuff; if( current_cam->geombuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( ( int ) current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = current_cam->geombuff[gbaseadd + x2]; if( ( TILEMODE == 0 ) ) aa4 = ( int ) y2 *current_cam->xres + x2; if( ( TILEMODE != 0 ) ) aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; ok = 1; if( baseadd + x2 >= 0 ) if( ( int ) current_cam->zbound > baseadd + x2 ) { if( current_cam->zbuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 2 ) if( pc.z > current_cam->zbuff[baseadd + x2] ) ok = 0; } if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( pc.z > geomz - .000000001 ) ok = 0; aa4 += ( pageres ) * layer; aa4 *= 4; if( TILEMODE == 0 ) if( ( current_cam == &LWcam ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) { ok = 0; } if( ( itsalight > 0 ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) { ok = 0; } if( TILEMODE != 0 ) if( ( current_cam == &LWcam ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( xx < GSclipx0 ) || ( xx >= GSclipx1 ) ) ) { ok = 0; } if( ok ) { success += 1; if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 3 ) { if( itsalight == 2 ) if( current_cam->geombuff ) { if( gbaseadd + x2 >= 0 ) if( ( int ) current_cam->gbound > gbaseadd + x2 ) current_cam->geombuff[gbaseadd + x2] = pc.z; } if( itsalight != 2 ) if( ( int ) current_cam->zbound > baseadd + x2 ) if( current_cam->zbuff ) if( baseadd + x2 >= 0 ) current_cam->zbuff[baseadd + x2] = pc.z; #ifdef showmetheocclusions if( TILEMODE == 6 ) if( itsalight == 2 ) { unsigned char * cppt; // printf ("plot\n"); cc.x = 255; cc.y = 255; cc.z = 255; if( current_cam->ibuff ) if( aa4 >= 0 ) if( current_cam->ibound > aa4 + 4 ) { cppt = ¤t_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; } // current_cam->ibuff[aa4]=(unsigned char)(cc.x); // current_cam->ibuff[aa4+1]=(unsigned char)(cc.y); // current_cam->ibuff[aa4+2]=(unsigned char)(cc.z); // current_cam->ibuff[aa4+3]=(unsigned char) 255; // current_cam->lumbuff[baseadd+x1]=(unsigned char) (lum); // come back } #endif if( TILEMODE == 6 ) if( itsalight == 0 ) if( current_cam->ibuff ) { unsigned char * cppt; VERT cc; cc.x = sss[3]; cc.y = sss[4]; cc.z = sss[5]; // printf ("plot\n"); if( aa4 >= 0 ) if( ( int ) current_cam->ibound > aa4 + 4 ) { cppt = ¤t_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 ) cc.z; cppt++; *cppt = ( unsigned char ) 255; // current_cam->ibuff[aa4]=(unsigned char)(cc.x); // current_cam->ibuff[aa4+1]=(unsigned char)(cc.y); // current_cam->ibuff[aa4+2]=(unsigned char)(cc.z); // current_cam->ibuff[aa4+3]=(unsigned char) 255; // current_cam->lumbuff[baseadd+x1]=(unsigned char) (lum); // come back } } } } // ok } } // end xx } for( t = 0; t < 7; t++ ) sss[t] += delta[t]; } // end linear } return ( success ); } static float getzNEW2( VERT gg, int ll, int passno, int lxr, int lxr2, int lgy ); static VERT cast_shadows_lgt_simpleTEST( VERT worldPt, int lgt ) { VERT shad; int i; float cx, cy; 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].trace == 0 ) { float maxp = 0; int x, y; for ( x = 0; x < totalhairfiles; x++ ) for ( y = 0; y < 5; y++ ) if ( Gshavep[x].passes[y] > maxp ) maxp = Gshavep[x].passes[y]; MAXPASSES = maxp; if ( ( totallights > 0 ) && ( LWlight[lgt].zbuff != NULL ) ) { SELF_SHARP = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( ( Gclipz == 0 ) && ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) SELF_SHARP; int numSamples; float skip; camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if ( skip > 3 ) skip = 3; // skip=4-skip; 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 ); // for (p=0;p<4;p++) p = 0; { int lxr2, lxr, lgy; // jitt=ptt[p]; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lxr = LWlight[lgt].xres; lxr2 = lxr * lxr; for ( j = camPt.y - SELF_SHARP; j <= camPt.y + SELF_SHARP; j += skip ) { lgy = lxr * j; for( i = camPt.x - SELF_SHARP; i <= camPt.x + SELF_SHARP; i += skip ) { float zz2; jitt.x = i; jitt.y = j; /// zz2 = getzGEOMNEW(jitt, lgt,0); if ( ( jitt.x >= 0 ) && ( jitt.x < LWlight[lgt].xres - 1 ) ) for ( q = 0; q < MAXPASSES; q++ ) { numSamples++; { float zz; zz = getzNEW2( jitt, lgt, q, lxr, lxr2, lgy ); if ( ( jitt.z <= zz ) ) //&& (jitt.z < zz2)) // if ((jitt.z < zz) && (jitt.z < zz2)) { shad.x += 1.0f; // shad.y += 1.0f; // shad.z += 1.0f; } } #ifdef C4D // else { // shad.x += 1.0f; // shad.y += 1.0f; // shad.z += 1.0f; } #endif } } } if( numSamples != 0 ) shad.x /= ( float ) ( numSamples ); // shad.y /= (float)(numSamples); // shad.z /= (float)(numSamples); lum[p] = shad.x; } // { // float xxx,xxx1; // xxx=lum[0]*(1.0-remx)+lum[1]*remx; // xxx1=lum[3]*(1.0-remx)+lum[2]*remx; // shad.x=xxx*(1.0-remy)+xxx1*remy; // } shad.y = shad.x; shad.z = shad.x; } } } else // (totallights == 0) || (LWlight[lgt].zbuff == NULL) { float cone = 1.0f; shad.x = shad.y = shad.z = cone; } } 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 float getzNEW2( VERT gg, int ll, int passno, int lxr, int lxr2, int lgy ) { float ret = 1000000.0f; if ( !LWlight[ll].blank ) { int add; int ggx = ( int ) gg.x; add = ggx + lgy; add += lxr2 * passno; ret = LWlight[ll].zbuff[add]; } return ( ret ); } int checkzclip( VERT a, VERT b ) { int ret = 0; VERT2 tm; VERT bb[8]; int x; bb[0].x = a.x; bb[0].y = a.y; bb[0].z = a.z; bb[1].x = b.x; bb[1].y = a.y; bb[1].z = a.z; bb[2].x = b.x; bb[2].y = b.y; bb[2].z = a.z; bb[3].x = a.x; bb[3].y = b.y; bb[3].z = a.z; bb[4].x = a.x; bb[4].y = a.y; bb[4].z = b.z; bb[5].x = b.x; bb[5].y = a.y; bb[5].z = b.z; bb[6].x = b.x; bb[6].y = b.y; bb[6].z = b.z; bb[7].x = a.x; bb[7].y = b.y; bb[7].z = b.z; for( x = 0; x < 8; x++ ) { tm.x = bb[x].x; tm.y = bb[x].y; tm.z = bb[x].z; tm = cam2world( current_cam, tm ); if( tm.clip == 1 ) ret++; } return ( ret ); } static int tag_a_curve2( WFTYPE * wf, CURVEINFO * h, int cs ) { int success = 0; WFTYPE fh; WFTYPE hh; int totalhv = 0; float rad; float lastrad; VERT2 tm; int x; float d; int last = 0; int slg = 0; int stp; VERT lastaa; float * fhwidth = NULL; int docurve = 0; int * clip = NULL; VERT * dvert2 = NULL; float hss; VERT bound1, bound2; VERT low, hi; int * smallish; int totaltri = 0; int too_big=0; bound1.x = 99999; bound1.y = 99999; bound1.z = 99999; bound2.x = -99999; bound2.y = -99999; bound2.z = -99999; low = bound1; hi = bound2; if ( wf->totalverts > 0 ) { smallish = ( int * ) malloc( wf->totalverts * sizeof( int ) ); clip = ( int * ) malloc( wf->totalverts * sizeof( int ) ); fhwidth = ( float * ) malloc( wf->totalverts * sizeof( float ) ); 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; if ( h->cutlength != 0 ) //if (h->killme==0) { float gs; gs = 1.0f / ( float ) GLOBALSAMP; if ( head >= 0 ) if ( h->mtl == head ) slg = 0; if ( beard >= 0 ) if ( h->mtl == beard ) slg = 1; if ( eyebrow >= 0 ) if ( h->mtl == eyebrow ) slg = 2; if ( eyelash >= 0 ) if ( h->mtl == eyelash ) slg = 3; if ( splines >= 0 ) if ( h->mtl == splines ) slg = 4; // h->ambient=sliders[7][slg].value*h->slider[7]; //printf ("cs = %d LOCAL_PASSES[%d] = %d\n",cs,slg,LOCAL_PASSES[slg]);fflush(stdout); // cs = cs % LOCAL_PASSES[slg]; cs=0; stp = 1; if ( global_segs == 5 ) stp = 10; //rad=(float)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 = world2cam( current_cam, tm ); tm.x += 1.0f; ///(float)current_cam->xres; //tm.y=0; //tm.z=0; //tm=vxmp(current_cam->iview,tm); tm = cam2world( 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; for ( x = 0; x < wf->totalverts; x++ ) { float r1; float r2; int docurve = 1; r2 = ( float ) ( ( ( wf->totalverts - 1 ) - ( x ) ) / ( float ) ( wf->totalverts - 1 ) ) * h->baserad; // +h->thickness*sliders[20][h->slgroup].value*.00045); r2 += ( ( float ) ( x ) / ( ( float ) ( wf->totalverts - 1 ) ) ) // *sliders[20][h->slgroup].value* * h->tiprad; r2 *= rad; smallish[x] = 0; if ( itsalight != 1 ) if ( r2 < gs ) { r2 = gs; // smallish[x] = 1; } if ( itsalight == 1 ) if( r2 < 0.05f ) { r2 = 0.05f; // smallish[x] = 1; } if (r2>40) too_big=1; { // 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 = world2cam( current_cam, aaa ); 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]; 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 ((TILEMODE!=6)||(itsalight==1)) //if ((TILEMODE!=6)||(itsalight==1)) //if (itsalight==0) //docurve=0; //if (check_curve(h,&fh)) docurve=1; if (too_big==0) if( docurve == 1 ) { // apply the fog before switching to cam coords if( 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 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++ ) { 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; 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++ ) { int qq; POLYDAT tri; int doit = 0; int va,vb; va=x; vb=x+1; 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( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) // if( ( ( itsalight == 3 ) && ( success == 0 ) ) || ( itsalight != 3 ) ) // doit = 1; // if( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) // doit = 1; doit=0; if ((clip[x]==0)||(clip[x+1]==0)) doit=1; if( doit ) { int x3; 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; 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]; wperp.x = perp.x * sz1; wperp.y = perp.y * sz1; wperp.z = perp.z * sz1; waa = wf->v[a]; wperp2.x = perp2.x * sz2; wperp2.y = perp2.y * sz2; wperp2.z = perp2.z * sz2; wbb = wf->v[b]; wperp = cam2world1( current_cam, wperp ); wperp2 = cam2world1( 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]; 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]; 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]; 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]; totaltri++; // GLOBAL_CLIPIT = 0; // success+= // draw_poly( // tri, // cs, // 255); add bounds code { VERT2 velOPEN, velCLOSE, vel; int qq; float s; VERT zero; POLYDAT pp; current_cam = &LWcamtable[0]; for( x3 = 0; x3 < 3; x3++ ) { VERT2 tmpv; tmpv.x = tri.p[x3].x; tmpv.y = tri.p[x3].y; tmpv.z = tri.p[x3].z; tmpv = cam2world( current_cam, tmpv ); tri.p[x3].x = tmpv.x; tri.p[x3].y = tmpv.y; tri.p[x3].z = tmpv.z; } pp = tocam( current_cam, tri ); for( qq = 0; qq < 3; qq++ ) { VERT a, b,vel2; a = pp.p[qq]; b=a; b.x+=pp.v[qq].x; b.y+=pp.v[qq].y; b.z+=pp.v[qq].z; // printf ("velocity = %f %f %f\n",tri.v[qq].x,tri.v[qq].y,tri.v[qq].z);fflush(stdout); // current_cam = &LWcamtable[Gmotion_samp - 1]; // close // b = world2cam1( current_cam, b); current_cam = &LWcamtable[0]; // a=world2cam1(current_cam,a); // b=world2cam1(current_cam,b); if( bound1.x > a.x ) bound1.x = a.x; if( bound1.x > b.x ) bound1.x = b.x; if( bound2.x < a.x ) bound2.x = a.x; if( bound2.x < b.x ) bound2.x = b.x; if( bound1.y > a.y ) bound1.y = a.y; if( bound1.y > b.y ) bound1.y = b.y; if( bound2.y < a.y ) bound2.y = a.y; if( bound2.y < b.y ) bound2.y = b.y; if( bound1.z > a.z ) bound1.z = a.z; if( bound1.z > b.z ) bound1.z = b.z; if( bound2.z < a.z ) bound2.z = a.z; if( bound2.z < b.z ) bound2.z = b.z; } if( bound1.x < low.x ) low.x = bound1.x; if( bound1.y < low.y ) low.y = bound1.y; if( bound1.z < low.z ) low.z = bound1.z; if( bound1.x > hi.x ) hi.x = bound1.x; if( bound1.y > hi.y ) hi.y = bound1.y; if( bound1.z > hi.z ) hi.z = bound1.z; if( bound2.x < low.x ) low.x = bound2.x; if( bound2.y < low.y ) low.y = bound2.y; if( bound2.z < low.z ) low.z = bound2.z; if( bound2.x > hi.x ) hi.x = bound2.x; if( bound2.y > hi.y ) hi.y = bound2.y; if( bound2.z > hi.z ) hi.z = bound2.z; } 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]; 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]; 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]; 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]; totaltri++; // GLOBAL_CLIPIT = 0; // printf ("fh velocity[%d] = %f %f %f\n",b,fh.velocity[b].x,fh.velocity[b].y,fh.velocity[b].z); /// success+= // draw_poly( // tri, // cs, // 255 // ); add bounds code { VERT2 velOPEN, velCLOSE, vel; int qq; float s; POLYDAT pp; current_cam = &LWcamtable[0]; for( x3 = 0; x3 < 3; x3++ ) { VERT2 tmpv; tmpv.x = tri.p[x3].x; tmpv.y = tri.p[x3].y; tmpv.z = tri.p[x3].z; tmpv = cam2world( current_cam, tmpv ); tri.p[x3].x = tmpv.x; tri.p[x3].y = tmpv.y; tri.p[x3].z = tmpv.z; } pp = tocam( current_cam, tri ); for( qq = 0; qq < 3; qq++ ) { VERT a, b,vel2; a = pp.p[qq]; b=a; b.x+=pp.v[qq].x; b.y+=pp.v[qq].y; b.z+=pp.v[qq].z; current_cam = &LWcamtable[Gmotion_samp - 1]; // close // b = world2cam1( current_cam, b); current_cam = &LWcamtable[0]; if( bound1.x > a.x ) bound1.x = a.x; if( bound1.x > b.x ) bound1.x = b.x; if( bound2.x < a.x ) bound2.x = a.x; if( bound2.x < b.x ) bound2.x = b.x; if( bound1.y > a.y ) bound1.y = a.y; if( bound1.y > b.y ) bound1.y = b.y; if( bound2.y < a.y ) bound2.y = a.y; if( bound2.y < b.y ) bound2.y = b.y; if( bound1.z > a.z ) bound1.z = a.z; if( bound1.z > b.z ) bound1.z = b.z; if( bound2.z < a.z ) bound2.z = a.z; if( bound2.z < b.z ) bound2.z = b.z; } if( bound1.x < low.x ) low.x = bound1.x; if( bound1.y < low.y ) low.y = bound1.y; if( bound1.z < low.z ) low.z = bound1.z; if( bound1.x > hi.x ) hi.x = bound1.x; if( bound1.y > hi.y ) hi.y = bound1.y; if( bound1.z > hi.z ) hi.z = bound1.z; if( bound2.x < low.x ) low.x = bound2.x; if( bound2.y < low.y ) low.y = bound2.y; if( bound2.z < low.z ) low.z = bound2.z; if( bound2.x > hi.x ) hi.x = bound2.x; if( bound2.y > hi.y ) hi.y = bound2.y; if( bound2.z > hi.z ) hi.z = bound2.z; } } } } } free_geomWF( &perphair ); } } } free( fhwidth ); free( clip ); free( smallish ); free( dvert2 ); free_geomWF( &fh ); free_geomWF( &hh ); if( checkzclip( low, hi ) != 8 ) { // printf ("DIAG: low %f %f high %f %f \n",low.x,low.y,hi.x,hi.y);fflush(stdout); // added a 1 pixel border to be sure 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, totaltri,cs ); } } return ( success ); } static int draw_poly2newZ( POLYDAT pp, int layer, unsigned char lum ) { int triangles = 0; int x; int success = 0; float y; int a, b; float y1; int same = 0; float maxy = -99999, miny = 99999; int imaxy, iminy; VERT vec1, vec2; VERT bas1, bas2; VERT p1, p2, c1, c2; VERT zero; int pageres; float tim = 0.0f; int offscreen = 0; int equal = 0; int GSclipx0, GSclipx1, GSclipy0, GSclipy1; int GSxres, GSyres; // if ( itsalight != 1 ) // layer = 0; GSxres = current_cam->xres * GLOBALSAMP; GSyres = current_cam->yres * GLOBALSAMP; // if (pleft.xxres * current_cam->yres; if ( TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( float ) GLOBALSAMP *( float ) GLOBALSAMP; } if ( itsalight != 1 ) for ( x = 0; x < 4; x++ ) { if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight != 2 ) // we don't want to jitter occlusions { pp.p[x].x += campass[cursamp * 4].x; pp.p[x].y += campass[cursamp * 4].y; } if( TILEMODE != 3 ) if( TILEMODE != 4 ) if( itsalight == 2 ) { pp.p[x].x += calibrateX; pp.p[x].y += calibrateY; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( 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( itsalight != 1 ) // for( x = 0; x < 4; x++ ) // { // if( TILEMODE != 3 ) // if( TILEMODE != 4 ) // if( 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( itsalight != 1 ) cursamp = layer; tim = 0.0f; //if (0==1) //if (TILEMODE!=2) if( ( TILEMODE > 0 ) && ( 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( !( ( TILEMODE > 0 ) && ( 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 (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( itsalight == 1 ) if( imaxy > current_cam->yres - 1 ) imaxy = 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( TILEMODE == 0 ) { int scanl; scanl = ( int ) y *current_cam->xres; baseadd = scanl;// + layer * ( pageres ); gbaseadd = scanl;// + layer * ( pageres ); } if( TILEMODE != 0 ) { int gclpy; int lp; lp = layer * pageres; gclpy = ( int ) ( y - GSclipy0 ) * 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[cursamp].y; ////- if( ( TILEMODE != 0 ) && ( ( y >= GSclipy0 ) && ( y < GSclipy1 ) ) ) yclip = 0; ////- // if ((TILEMODE==0)&&((y>=Gclipy0)&&(y= Gclipy0 ) && ( y < 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 ) pright.x; //if (itsalight==1) baseadd=0; //if (TILEMODE==0) // if ((pright.x-pleft.x)xres) clipx=0; //if (TILEMODE>0) // if ((pright.x-pleft.x)xres*GLOBALSAMP) clipx=0; ////- for( tt = ( float ) pleft.x; tt <= ( float ) ( qq2 ); tt += 1.0f ) { int clipit = 0; ////- if( itsalight != 2 ) if( itsalight > 0 ) if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; if( TILEMODE == 0 ) ////- if( current_cam == &LWcam ) ////- if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) ////- if( !( ( tt >= GSclipx0 ) && ( tt <= GSclipx1 ) ) ) clipit = 1; ////- if( TILEMODE == 0 ) ////- if( current_cam != &LWcam ) ////- if( !( ( tt >= 0 ) && ( tt < current_cam->xres ) ) ) clipit = 1; ////- if( TILEMODE != 0 ) ////- if( 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( TILEMODE > 0 ) x2 = x2 - GSclipx0; if( TILEMODE > 0 ) y2 = y2 - GSclipy0; 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; // plot it ok = 1; // if (TILEMODE==1) ok=1; if( TILEMODE == 0 ) if( ( ( y2 < Gclipy0 ) || ( y2 >= Gclipy1 ) ) ) { ok = 0; } if( TILEMODE == 0 ) if( ( ( x2 < Gclipx0 ) || ( x2 >= Gclipx1 ) ) ) { ok = 0; } // x2 and y2 were >= if( ( TILEMODE != 0 ) && ( ( y2 < 0 ) || ( y2 >= GSyres ) ) ) { ok = 0; } if( ( 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( TILEMODE == 6 ) current_cam = &tilebuff; if( current_cam->geombuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( ( int ) current_cam->gbound > gbaseadd + x2 ) if( gbaseadd + x2 >= 0 ) geomz = current_cam->geombuff[gbaseadd + x2]; if( ( TILEMODE == 0 ) ) aa4 = ( int ) y2 *current_cam->xres + x2; if( ( TILEMODE != 0 ) ) aa4 = ( int ) ( y2 ) * alltiles.sx * GLOBALSAMP + x2; ok = 1; if( baseadd + x2 >= 0 ) if( ( int ) current_cam->zbound > baseadd + x2 ) { if( current_cam->zbuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 2 ) if( pc.z > current_cam->zbuff[baseadd + x2] ) ok = 0; } //if (itsalight!=2) if( itsalight != 1 ) // we don't want to occlude with geom on a light pass if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( pc.z > geomz - .000000001 ) ok = 0; aa4 += ( pageres ) * layer; aa4 *= 4; if( TILEMODE == 1 ) ok = 1; ////- if( TILEMODE == 0 ) ////- if( ( current_cam == &LWcam ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) ////- { ok = 0; } ////- if( itsalight != 2 ) if( ( itsalight > 0 ) && ( ( y < Gclipy0 ) || ( y >= Gclipy1 ) ) ) { ok = 0; } if( TILEMODE != 0 ) ////- if( ( current_cam == &LWcam ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) ////- { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( y < GSclipy0 ) || ( y >= GSclipy1 ) ) ) ////- { ok = 0; } ////- if( ( TILEMODE != 0 ) && ( ( x1 < GSclipx0 ) || ( x1 >= GSclipx1 ) ) ) ////- { ok = 0; } // printf ("tilemode=%d\n",TILEMODE); // if ((TILEMODE>0)&&(TILEMODE<6)) ok =0; // if (itsalight==2) ok=1; if( ok ) { success += 1; if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 3 ) { if( itsalight == 2 ) if( current_cam->geombuff ) { if( gbaseadd + x2 >= 0 ) if( ( int ) current_cam->gbound > gbaseadd + x2 ) current_cam->geombuff[gbaseadd + x2] = pc.z; // if (current_cam== &LWcam) // current_cam->ibuff[aa4]=255; } if( itsalight != 2 ) if( ( int ) current_cam->zbound > baseadd + x2 ) if( current_cam->zbuff ) if( baseadd + x2 >= 0 ) current_cam->zbuff[baseadd + x2] = pc.z; #ifdef showmetheocclusions if( TILEMODE == 6 ) if( itsalight == 2 ) { unsigned char * cppt; // printf ("plot\n"); cc.x = 255; cc.y = 255; cc.z = 255; if( current_cam->ibuff ) if( aa4 >= 0 ) if( current_cam->ibound > aa4 + 4 ) { cppt = ¤t_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; } // current_cam->ibuff[aa4]=(unsigned char)(cc.x); // current_cam->ibuff[aa4+1]=(unsigned char)(cc.y); // current_cam->ibuff[aa4+2]=(unsigned char)(cc.z); // current_cam->ibuff[aa4+3]=(unsigned char) 255; // current_cam->lumbuff[baseadd+x1]=(unsigned char) (lum); // come back } #endif } } // ok } // plot } // pair interp } // loop } // variable decl } // variable decl } // y>0 ykillme = 0; if( h->mtl == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // 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] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); h->scruffle= (float ) (sliders[55][slg].value * h->slider[55]); //fprintf (stdout,"MTcolor_a_hair h->randomize %f",h->randomize);fflush(stdout); tint.x = ( sliders[9][slg].value ) / 255.0f; tint.y = ( sliders[10][slg].value ) / 255.0f; tint.z = ( sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( sliders[18][slg].value ) / 255.0f; tint1.z = ( 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 ) < ( sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = sliders[13][slg].value / 255.0f; tnt.y = sliders[14][slg].value / 255.0f; tnt.z = 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 = 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 = ( sliders[39][slg].value / 100.0f ) * h->slider[39]; //rv*=.5f; 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 = 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 = ( 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 ((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 void MTcolor_a_hairSOFT( 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 == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // 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->killme = 0; //MTmix100(gs)(); mix110 { int xx; for( xx = 0; xx < 5; xx++ ) MTdrand98( gs ); } // if( dmapp.x < drand98( ) ) if( dmapp.x * dmapp.x < MTdrand98( gs ) ) h->killme = 1; h->thickness = h->slider[20] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = ( llnmap.x + llnmap.y + llnmap.z ) / 3.0f; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ 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 void MTcolor_a_hairROOT( 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 == head ) slg = 0; if( h->mtl == beard ) slg = 1; if( h->mtl == eyebrow ) slg = 2; if( h->mtl == eyelash ) slg = 3; if( h->mtl == splines ) slg = 4; h->slgroup = slg; // drand59 dmapp.x *= h->slider[28]; // density llnmap.x *= h->slider[29]; h->killme = 0; if ((sliders[25][slg].value > 0.0f)&&(h->slider[25]==0.0f)) h->killme=1; // for (xx=0;xx<30;xx++) { float tmp; tmp=drand98(); } // MTmix100(gs)(); { int xx; for( xx = 0; xx < 5; xx++ ) MTdrand98( gs ); } if( dmapp.x * dmapp.x < MTdrand98( gs ) ) // if( dmapp.x < drand98( ) ) h->killme = 1; h->killme = 0; h->thickness = h->slider[20] * sliders[20][slg].value * 3.0f; h->thicknesstip = h->slider[37] * sliders[37][slg].value * 3.0f; h->cutlength = llnmap.x; // h->cutlength*=h->slider[29] h->slgroup = slg; h->diffuse = sliders[6][slg].value * h->slider[6]; if( h->diffuse > 1.0f ) h->diffuse = 1.0f; h->spec = sliders[4][slg].value * h->slider[4]; h->kspec = sliders[5][slg].value * h->slider[5]; h->ambient = sliders[7][slg].value; //*h->slider[7]; h->tipfrizz = sliders[24][slg].value * h->slider[24] * 5.0f; h->rootfrizz = sliders[0][slg].value * h->slider[0] * 5.0f; h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->frizzfreqX = sliders[1][slg].value * h->slider[1]; h->frizzfreqY = sliders[30][slg].value * h->slider[30]; h->frizzfreqZ = sliders[31][slg].value * h->slider[31]; h->frizzanim = sliders[32][slg].value * h->slider[32]; h->animspeed = sliders[33][slg].value * h->slider[33] * 2.0f; h->dreadtip = sliders[27][slg].value * h->slider[27]; h->dreadroot = sliders[26][slg].value * h->slider[26]; h->dreadcount = ( float ) ( int ) (sliders[25][slg].value * h->slider[25]); h->clumpfreq = sliders[1][slg].value * h->slider[1]; h->kink = sliders[2][slg].value * h->slider[2]; h->kinkroot = sliders[38][slg].value * h->slider[38]; h->kinkfreqX = sliders[3][slg].value * h->slider[3]; h->kinkfreq = sliders[3][slg].value * h->slider[3]; h->multasp = sliders[44][slg].value * h->slider[44]; h->offset = sliders[45][slg].value * h->slider[45]; h->aspect = sliders[46][slg].value * h->slider[46]; h->kinkfreqY = sliders[34][slg].value * h->slider[34]; h->kinkfreqZ = sliders[35][slg].value * h->slider[35]; h->randscale = sliders[36][slg].value * h->slider[36]; var = 1; // var=2.0*drand98()*sliders[12][slg].value/100.0f;//+ h->mess = sliders[47][slg].value * h->slider[47]; h->flyaway = sliders[48][slg].value * h->slider[48]; h->clump_strength = sliders[49][slg].value * h->slider[49]; h->clump_color_strength = sliders[51][slg].value * h->slider[51]; h->clump_rot_strength = sliders[50][slg].value * h->slider[50]; h->clump_rot_offset = sliders[52][slg].value * h->slider[52]; h->randomize= (float ) (sliders[53][slg].value * h->slider[53]); h->clump_flatness= (float ) (sliders[54][slg].value * h->slider[54]); tint.x = ( sliders[9][slg].value ) / 255.0f; tint.y = ( sliders[10][slg].value ) / 255.0f; tint.z = ( sliders[11][slg].value ) / 255.0f; tint.x *= h->slider[9]; tint.y *= h->slider[10]; tint.z *= h->slider[11]; tint1.x = ( sliders[17][slg].value ) / 255.0f; // this is the root color tint1.y = ( sliders[18][slg].value ) / 255.0f; tint1.z = ( 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 ) < ( sliders[16][slg].value / 100.0f ) * h->slider[16] ) { VERT tnt; tnt.x = sliders[13][slg].value / 255.0f; tnt.y = sliders[14][slg].value / 255.0f; tnt.z = 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); //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 = 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 - ( 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 = 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.0 - ( hue1 ) ) + ( rr * ( hue1 ) ); tint.y = ( tint.y ) * ( 1.0 - ( hue1 ) ) + ( gg * ( hue1 ) ); tint.z = ( tint.z ) * ( 1.0 - ( hue1 ) ) + ( bb * ( hue1 ) ); rv = 1.0 - ( sliders[39][slg].value / 100.0f ) * h->slider[39]; 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; for( x = 0; x < 15; x++ ) { 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; } }