// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 // drawbuff static int draw_line2( POLYDAT pp, int layer, unsigned char lum ); float illum_box( float inz, int lgt, int lx, int ly, int hx, int hy ); float illum_boxGEOM( float inz, int lgt, int lx, int ly, int hx, int hy ); static void makenormals( void ); //static VERT edge_color[1000][2]; // making these global will cause multithread problems //static VERT edge_pos[1000][2]; #include "newrender.c" static int global_pass = 0; #include static void shade_a_hair( RENDERHAIR * ); static void draw_geomWF( WFTYPE * geom, int cs ) { POLYDAT tri; int ll, x, y; cs = 0; tri.v[0].x = 0; tri.v[0].y = 0; tri.v[0].z = 0; tri.v[1].x = 0; tri.v[1].y = 0; tri.v[1].z = 0; tri.v[2].x = 0; tri.v[2].y = 0; tri.v[2].z = 0; tri.v[3].x = 0; tri.v[3].y = 0; tri.v[3].z = 0; tri.v[4].x = 0; tri.v[4].y = 0; tri.v[4].z = 0; //printf("occlude\n"); //for (x=0;xtotalverts;x++) SHAVEcoord_convertTOSHAVE(&geom->v[x]); //for (x=0;xtotalverts;x++) geom->v[x].z *= -1.0f; if( itsalight == 2 ) // for (ll=0;lltotalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[2] = geom->v[geom->facelist[pp]]; tri.v[2] = geom->velocity[geom->facelist[pp]]; tri.w[2] = geom->v[geom->facelist[pp]]; tri.wv[2] = geom->velocity[geom->facelist[pp]]; draw_poly3d( tri, cs, ( unsigned char ) 0 ); } } } if( itsalight == 2 ) // for (ll=0;lltotalfaces=%f\n",geom->totalfaces); for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.c[y - geom->face_start[x]].x = 0; tri.c[y - geom->face_start[x]].y = 0; tri.c[y - geom->face_start[x]].z = 0; tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); } //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif #ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); #endif } } if( itsalight == 0 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[t].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[t]); } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[2].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[2]); //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } } //for (cs=0;cstotalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); tri.c[y - geom->face_start[x]].x = 255.0f; tri.c[y - geom->face_start[x]].y = 255.0f; tri.c[y - geom->face_start[x]].z = 255.0f; } //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } if( itsalight == 3 ) { // current_cam=&LWcam; for( x = 0; x < geom->totalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] > 3 ) { GhairID = x; for( y = geom->face_start[x] + 1; y < geom->face_end[x] - 1; y++ ) { int pp; int t; for( t = 0; t < 2; t++ ) { pp = y + t; if( pp >= geom->face_end[x] ) pp -= ( geom->face_end[x] - geom->face_start[x] ); tri.c[t].x = 0; tri.c[t].y = 0; tri.c[t].z = 0; tri.p[t] = geom->v[geom->facelist[pp]]; tri.v[t] = geom->velocity[geom->facelist[pp]]; tri.w[t] = geom->v[geom->facelist[pp]]; tri.wv[t] = geom->velocity[geom->facelist[pp]]; // tri.p[t].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[t]); } pp = geom->face_start[x]; tri.c[2].x = 0; tri.c[2].y = 0; tri.c[2].z = 0; tri.p[2] = geom->v[geom->facelist[pp]]; tri.v[2] = geom->velocity[geom->facelist[pp]]; tri.w[2] = geom->v[geom->facelist[pp]]; tri.wv[2] = geom->velocity[geom->facelist[pp]]; // tri.p[2].z= -geom->v[geom->facelist[pp]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[2]); //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } } //for (cs=0;cstotalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { GhairID = x; for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.p[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; tri.w[y - geom->face_start[x]] = geom->v[geom->facelist[y]]; tri.wv[y - geom->face_start[x]] = geom->velocity[geom->facelist[y]]; // tri.p[y-geom->face_start[x]].z= -geom->v[geom->facelist[y]].z; // SHAVEcoord_convertTOSHAVE(&tri.p[y-geom->face_start[x]]); tri.c[y - geom->face_start[x]].x = 255.0f; tri.c[y - geom->face_start[x]].y = 255.0f; tri.c[y - geom->face_start[x]].z = 255.0f; } //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom->v[x]); //for (x=0;xtotalverts;x++) geom->v[x].z *= -1.0f; } static void draw_geom( FREEZETYPE * geom, int cs ) { POLYDAT tri; int ll, x, y; //getMAXPASSES(); ///oversamp=MAXPASSES; /// destroy_buffers(); /// mkIMAGEbuffer(&LWcam); /// mkDEPTHbuffers(&LWcam); /// for (ll=0;lltotalfaces; x++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) { tri.p[y - geom->face_start[x]] = geom->v[facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[facelist[y]]; //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } //for (cs=0;cstotalfaces; x++ ) for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) if( geom->face_end[x] - geom->face_start[x] == 3 ) { tri.p[y - geom->face_start[x]] = geom->v[facelist[y]]; tri.v[y - geom->face_start[x]] = geom->velocity[facelist[y]]; tri.c[y - geom->face_start[x]].x = 255; tri.c[y - geom->face_start[x]].y = 255; tri.c[y - geom->face_start[x]].z = 255; //#ifdef RENDERLW draw_poly3d( tri, cs, ( unsigned char ) 0 ); //#endif //#ifndef RENDERLW // draw_poly3d(tri,0,(unsigned char)0); //#endif } } } static void LWdraw_geom( int cs ) { FREEZETYPE geom; int x; geom.totalverts = Dtotalverts + 5; geom.totalfaces = Dtotalfaces + 5; geom.totalfverts = Dtotalfverts + 5; alloc_geom( &geom ); geom.totalverts = Dtotalverts; geom.totalfaces = Dtotalfaces; geom.totalfverts = Dtotalfverts; for( x = 0; x < Dtotalverts; x++ ) { geom.Rrvcolor[x] = 255.0f; geom.Rgvcolor[x] = 255.0f; geom.Rbvcolor[x] = 255.0f; geom.rvcolor[x] = 255.0f; geom.gvcolor[x] = 255.0f; geom.bvcolor[x] = 255.0f; geom.v[x] = Dv[x]; geom.vn[x] = Dvn[x]; } for( x = 0; x < Dtotalfverts; x++ ) geom.facelist[x] = Dfacelist[x]; for( x = 0; x < Dtotalfaces; x++ ) { geom.face_start[x] = Dface_start[x]; geom.face_end[x] = Dface_end[x]; } relight_geom( &geom ); draw_geom( &geom, cs ); free_geom( &geom ); } double drand98( void ); // float drand49(void); // vxmp static float topseudo( Matrix m, VERT vv, float izoom ) { float w; float nn[3]; VERT r; nn[0] = vv.x; nn[1] = vv.y; nn[2] = vv.z; r.x = ( nn[0] * m[0][0] ) + ( nn[1] * m[1][0] ) + ( nn[2] * m[2][0] ) + m[3][0]; r.y = ( nn[0] * m[0][1] ) + ( nn[1] * m[1][1] ) + ( nn[2] * m[2][1] ) + m[3][1]; r.z = ( nn[0] * m[0][2] ) + ( nn[1] * m[1][2] ) + ( nn[2] * m[2][2] ) + m[3][2]; w = ( nn[0] * m[0][3] ) + ( nn[1] * m[1][3] ) + ( nn[2] * m[2][3] ) + m[3][3]; w = ( vv.z + izoom ) / w; return ( w ); } static VERT vxmp2( Matrix m, VERT vv ) { float w; float nn[3]; VERT r; nn[0] = vv.x; nn[1] = vv.y; nn[2] = vv.z; r.x = ( nn[0] * m[0][0] ) + ( nn[1] * m[1][0] ) + ( nn[2] * m[2][0] ) + m[3][0]; r.y = ( nn[0] * m[0][1] ) + ( nn[1] * m[1][1] ) + ( nn[2] * m[2][1] ) + m[3][1]; r.z = ( nn[0] * m[0][2] ) + ( nn[1] * m[1][2] ) + ( nn[2] * m[2][2] ) + m[3][2]; w = ( nn[0] * m[0][3] ) + ( nn[1] * m[1][3] ) + ( nn[2] * m[2][3] ) + m[3][3]; if( w != 0.0 ) { r.x /= w; r.y /= w; r.z /= w; } return ( r ); } static VERT2 vxmp3( Matrix m, VERT vv, float e ) { float w; VERT2 r; r.x = ( vv.x * m[0][0] ) + ( vv.y * m[1][0] ) + ( vv.z * m[2][0] ) + m[3][0]; r.y = ( vv.x * m[0][1] ) + ( vv.y * m[1][1] ) + ( vv.z * m[2][1] ) + m[3][1]; r.z = ( vv.x * m[0][2] ) + ( vv.y * m[1][2] ) + ( vv.z * m[2][2] ) + m[3][2]; w = ( vv.x * m[0][3] ) + ( vv.y * m[1][3] ) + ( vv.z * m[2][3] ) + m[3][3]; if( w != 0.0 ) { r.x /= w; r.y /= w; r.z /= w; } Gclipz = 0; r.clip = 0; r.clipz = 0; #ifndef RENDERLW if( w > 0 ) { r.clip = 1; r.clipz = 1; Gclipz = 1; } #endif #ifdef RENDERLW #endif return ( r ); } static float Jdither( void ); static float Jdither( void ) { return ( 1.0 ); } static VERT lastcc; static float distance( VERT a, VERT b ); static void render_line2( RENDERHAIR h, int a, int b, float sz1, float sz2 ) { } //#endif RENDERLW// RENDERLW //#endif static void doframe( void ) { int x; if( first_dyn == 1 ) { int x1, x2; for( x1 = 0; x1 < totalverts; x1++ ) for( x2 = 0; x2 < 15; x2++ ) hair[x1].lasthv[x2] = hair[x1].hv[x2]; } if( first_dyn == 1 ) { int x1, x2; for( x1 = 0; x1 < total_splines; x1++ ) for( x2 = 0; x2 < 15; x2++ ) Slasthair[x1].hv[x2] = Shair[x1].hv[x2]; first_dyn = 0; } if( !first_dyn ) dodyn( ); for( x = 0; x < totalverts; x++ ) { int t; for( t = 0; t < 15; t++ ) { hair[x].lasthv[t] = hair[x].hv[t]; // is this it? (shouldn't normally be here) // thishair[x]=hair[x]; } } for( x = 0; x < total_splines; x++ ) { Slasthair[x] = Shair[x]; // is this it? (shouldn't normally be here) Sthishair[x] = Shair[x]; } } static void precalc_shadow( RENDERHAIR * h, RENDERHAIR * bh ) { int x, y, z; RENDERHAIR blur; int bhit[56]; for( y = 0; y < totallights; y++ ) if( LWlight[y].xres > 0 ) { for( x = 0; x < 56; x += 1 ) { if( Gtrace == 0 ) bh[y].color[x] = Gilluminate( h->hv[x], y, h->ambient ); } bh[y].color[55] = bh[y].color[54]; } if( h->ambient > 0 ) for( z = 0; z < totallights; z++ ) if( LWlight[z].xres > 0 ) { for( y = 0; y < 56; y++ ) { blur.color[y].x = 0; blur.color[y].y = 0; blur.color[y].z = 0; } for( y = 0; y < 56; y++ ) bhit[y] = 0; for( x = 0; x < 3; x++ ) { for( y = 0; y < 56; y++ ) { int ii; ii = ( x - 1 ) + y; if( ii < 1 ) ii = 1; if( ii > 56 - 1 ) ii = 56 - 1; blur.color[y].x += bh[z].color[ii].x; blur.color[y].y += bh[z].color[ii].y; blur.color[y].z += bh[z].color[ii].z; bhit[y]++; } } for( y = 0; y < 56; y++ ) { blur.color[y].x = blur.color[y].x / ( float ) bhit[y]; blur.color[y].y = blur.color[y].y / ( float ) bhit[y]; blur.color[y].z = blur.color[y].z / ( float ) bhit[y]; bh[z].color[y] = blur.color[y]; } } } static void shade_a_hair( RENDERHAIR * h ) //RENDERHAIR h; { int x; VERT H; VERT eye; int l; VERT tint; int slg; RENDERHAIR tmpcolor; RENDERHAIR *tmpshad; int counter = 0; VERT lg; tmpshad = ( RENDERHAIR * ) malloc( totallights * sizeof( RENDERHAIR ) ); precalc_shadow( h, tmpshad ); //h=color_a_hair(h); for( x = 0; x < 60; x++ ) { tmpcolor.color[x].x = 0; tmpcolor.color[x].y = 0; tmpcolor.color[x].z = 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]; if( h->restlength > 0 ) for( l = 0; l < totallights; l++ ) { //if (LWlight[l].zbuff) if( LWlight[l].xlight == 0 ) // if( LWlight[l].xres != 00 ) if( LWlight[l].wind == 0 ) { VERT fcolor; float vv[3]; if( h->restlength > 0 ) for( x = 0; x < 56; x += 1 ) { VERT a, uv; VERT lum; float shd; VERT norm; float spec; int trigger = 0; double tmpp[3]; double tmpd[3], tmpc[3]; tmpp[0] = h->hv[x].x; tmpp[1] = h->hv[x].y; tmpp[2] = h->hv[x].z; if( x != 0 ) { vv[0] = ( h->hv[x].x - h->hv[x - 1].x ); vv[1] = ( h->hv[x].y - h->hv[x - 1].y ); vv[2] = ( h->hv[x].z - h->hv[x - 1].z ); } else { vv[0] = ( h->hv[1].x - h->hv[0].x ); vv[1] = ( h->hv[1].y - h->hv[0].y ); vv[2] = ( h->hv[1].z - h->hv[0].z ); } { VERT tmpv; tmpv.x = vv[0]; tmpv.y = vv[1]; tmpv.z = vv[2]; tmpv = Vnorm( tmpv ); vv[0] = tmpv.x; vv[1] = tmpv.y; vv[2] = tmpv.z; } tmpd[0] = ( double ) vv[0]; tmpd[1] = ( double ) vv[1]; tmpd[2] = ( double ) vv[2]; tmpc[0] = 1.0f; tmpc[1] = 1.0f; tmpc[2] = 1.0f; tmpd[0] = LWlight[l].wpos.x - h->hv[x].x; tmpd[1] = LWlight[l].wpos.y - h->hv[x].y; tmpd[2] = LWlight[l].wpos.z - h->hv[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]; // if (lum.xambient); //// shad.y+=(1.0f-h->ambient); //// shad.z+=(1.0f-h->ambient); } // if (shad.x1.0) shad.x=1.0f; // if (shad.y>1.0) shad.y=1.0f; // if (shad.z>1.0) shad.z=1.0f; lum.x = shad.x; lum.y = shad.y; lum.z = shad.z; //if (lum.x>1.0) printf("lum.x=%f\n",lum.x); } } if( x != 0 ) { vv[0] = ( h->hv[x].x - h->hv[x - 1].x ); vv[1] = ( h->hv[x].y - h->hv[x - 1].y ); vv[2] = ( h->hv[x].z - h->hv[x - 1].z ); } else { vv[0] = ( h->hv[1].x - h->hv[0].x ); vv[1] = ( h->hv[1].y - h->hv[0].y ); vv[2] = ( h->hv[1].z - h->hv[0].z ); } norm.x = -vv[0]; norm.y = -vv[1]; norm.z = -vv[2]; // norm.x= vv[0]; // norm.y= vv[1]; // norm.z= vv[2]; norm = Vnorm( norm ); eye.x = LWcam.wpos.x - h->hv[x].x; eye.y = LWcam.wpos.y - h->hv[x].y; eye.z = LWcam.wpos.z - h->hv[x].z; lg.x = lg.x; lg.y = lg.y; lg.z = lg.z; // lg.z ok? #ifndef RENDERLW //eye.x = - eye.x; //eye.y = - eye.y; //eye.z = - eye.z; #endif // eye=vxm(LWcam.iview,eye); eye = Vnorm( eye ); uv.x = lg.x; uv.y = lg.y; uv.z = lg.z; uv = Vnorm( uv ); a = Vcross( uv, norm ); a = Vnorm( a ); norm = Vcross( a, norm ); norm = Vnorm( norm ); { float shd2 = 0.0f; norm.x = -norm.x; norm.y = -norm.y; norm.z = -norm.z; shd = 0.0f; shd2 = ( VDot( norm, lg ) ); if( shd2 > 0 ) shd += shd2; norm.x = -norm.x; norm.y = -norm.y; norm.z = -norm.z; shd2 = ( VDot( norm, lg ) ); if( shd2 > 0 ) shd += shd2; // if (shd>1.0f) shd=1.0f; } // shd=1; // shd= -shd; // if (shd<0) shd= -shd; //// if (shd<0) shd= 0; ///// why this? shd*=shd; // if (shd>1.0) shd= 1.00; H.x = ( eye.x + lg.x ) / 2.0f; H.y = ( eye.y + lg.y ) / 2.0f; H.z = ( eye.z + lg.z ) / 2.0f; //H=eye; //H=vxm(LWcam.iview,H); H = Vnorm( H ); { float spec2; spec2 = VDot( norm, H ); if( spec2 < 0 ) spec2 = 0; spec = pow( spec2, 1.0 / ( 3.0 * ( .101 - h->kspec ) ) ); norm.x = -norm.x; norm.y = -norm.y; norm.z = -norm.z; spec2 = VDot( norm, H ); if( spec2 < 0 ) spec2 = 0; norm.x = -norm.x; norm.y = -norm.y; norm.z = -norm.z; spec += pow( spec2, 1.0 / ( 3.0 * ( .101 - h->kspec ) ) ); // if (spec>1.0f) spec=1.0f; } //spec*=2.0f; spec *= h->spec; // spec= -spec; if( spec < 0 ) spec = 0; // if ( _isnan(shd)) shd=1; if( shd < 0 ) shd = 0; shd *= h->diffuse; shd += ( 1.0f - h->diffuse ); tint.x = h->color[x].x; tint.y = h->color[x].y; tint.z = h->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); } // if (fcolor.x>1) fcolor.x=1; // if (fcolor.y>1) fcolor.y=1; // if (fcolor.z>1) fcolor.z=1; // if (fcolor.x<0) fcolor.x=0; // if (fcolor.y<0) fcolor.y=0; // if (fcolor.z<0) fcolor.z=0; if( LWlight[l].xlight == 0 ) if( LWlight[l].wind == 0 ) // if ( (!_isnan(fcolor.x)) // &&(!_isnan(fcolor.y)) // &&(!_isnan(fcolor.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.0 ) tmpcolor.color[x].x = 1.0f; if( tmpcolor.color[x].y > 1.0 ) tmpcolor.color[x].y = 1.0f; if( tmpcolor.color[x].z > 1.0 ) tmpcolor.color[x].z = 1.0f; } } // x } // iff } // total lights for( x = 0; x < 56; x++ ) { h->color[x].x = tmpcolor.color[x].x * 255; h->color[x].y = tmpcolor.color[x].y * 255; h->color[x].z = tmpcolor.color[x].z * 255; } // return(h); Nfree( tmpshad ); } // --------------------------- // -------------------- static float getz( VERT gg, int ll ) { int lxr = ( int ) LWlight[ll].xres; float ret = 1000000.0f; if( ( lxr != 0 ) && ( LWlight[ll].zbuff != NULL ) ) { int add; int ggy = ( int ) gg.y; int ggx = ( int ) gg.x; add = ggx + lxr * ggy; if( add > 0 ) { int lxr2; // = lxr * lxr; lxr2 = LWlight[ll].zbound; if( add < lxr2 ) { static int om = 0; static float qq = 0.0f; static int qq1 = 0; // if (Gdeep_shadows == 0) // om = GextrasampLIGHT; // else // we no longer support non-deep shadow modes om = GextrasampLIGHT * ( MAXPASSES - 1 ); qq = drand98( ) * ( float ) om; // %%% Why do this? 'om' is already in the range. qq1 = ( int ) ( qq ) + GextrasampLIGHT; // // Shouldn't this be: // // if (qq1 >= om) qq1 = om - 1; // // ? // if( qq1 > om ) qq1 = om; add += lxr2 * qq1; ret = LWlight[ll].zbuff[add]; } } } return ( ret ); } static float getzNEW( VERT gg, int ll, int dd ) { int lxr = ( int ) LWlight[ll].xres; float ret = 1000000.0f; if( ( lxr != 0 ) && ( LWlight[ll].zbuff != NULL ) ) { int add; int ggy = ( int ) gg.y; int ggx = ( int ) gg.x; add = ggx + lxr * ggy; if( add > 0 ) { static int lxr2; // = lxr * lxr; lxr2 = LWlight[ll].xrsq; if( add < lxr2 ) { // dd*=GextrasampLIGHT; add += lxr2 * dd; ret = LWlight[ll].zbuff[add]; } } } return ( ret ); } static float getzGEOM( VERT gg, int ll ) { float ret = ( float ) 1000000.0f; int lxr; lxr = ( int ) LWlight[ll].xres; if( ( lxr != 0 ) && ( LWlight[ll].geombuff != NULL ) ) { int add = ( int ) gg.x + lxr * ( int ) gg.y; if( add > 0 ) { int lxr2 = lxr * lxr; // lxr2=LWlight[ll].zbound; if( add < lxr2 ) { ret = LWlight[ll].geombuff[add]; } } } return ret; } static float getzGEOMNEW( VERT gg, int ll, int dd ) { float ret = ( float ) 1000000.0f; int lxr; lxr = ( int ) LWlight[ll].xres; if( ( lxr != 0 ) && ( LWlight[ll].geombuff != NULL ) ) { int add = ( int ) gg.x + lxr * ( int ) gg.y; if( add > 0 ) { int lxr2; //= lxr * lxr; // lxr2=LWlight[ll].gbound; if( add < lxr * lxr ) { // if ((Gtrace == 0) && (Gdeep_shadows == 1)) // { // int om = GextrasampLIGHT; // float qq = drand98() * (float)om; // int qq1 = (int)(qq); // if (qq1 >= om) qq1 = om - 1; // // if (qq1 > 0) add += lxr2 * qq1; // } /// add += lxr2 * dd; // no deep buffer on the geom ret = LWlight[ll].geombuff[add]; } } } return ret; } static float getz2( VERT gg, int ll ) { int lxr; int add; float ret = 0; int ggy, ggx; ggx = ( int ) gg.x; ggy = ( int ) gg.y; lxr = ( int ) LWlight[ll].xres; add = ggx + lxr * ggy; if( ( add > 0 ) && ( add < ( int ) LWlight[ll].zbound ) ) ret = 0; if( !LWlight[ll].blank ) if( lxr != 00 ) { if( add < ( int ) LWlight[ll].zbound ); if( gg.z <= LWlight[ll].zbuff[add] ) ret = 1; } return ( ret ); } static float getzTURNER( VERT gg, int ll ) { int lxr; int add; float ss; float ret = 0.0f; float sh1 = 0, sh2 = 0, sh3 = 0, sh4 = 0; int ggy, ggx; int x; ss = floor( SELF_SHARP ); if( ss < 1 ) ss = 1; ss = 1; for( x = 0; x < ss; x++ ) { ggx = ( int ) gg.x + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ); ggy = ( int ) gg.y + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ); lxr = ( int ) LWlight[ll].xres; add = ggx + lxr * ggy; if( ( add > 0 ) && ( add < lxr * lxr ) ) if( lxr != 00 ) { // add+=qpassnumber*lxr*lxr; if( gg.z <= LWlight[ll].zbuff[add] ) sh1 = 1.0f; } ggx = ( int ) gg.x + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ) + 1; ggy = ( int ) gg.y + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ); lxr = ( int ) LWlight[ll].xres; add = ggx + lxr * ggy; if( ( add > 0 ) && ( add < lxr * lxr ) ) if( lxr != 00 ) { // add+=qpassnumber*lxr*lxr; if( gg.z <= LWlight[ll].zbuff[add] ) sh2 = 1.0f; } ggx = ( int ) gg.x + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ) + 1; ggy = ( int ) gg.y + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ) + 1; lxr = ( int ) LWlight[ll].xres; add = ggx + lxr * ggy; if( ( add > 0 ) && ( add < lxr * lxr ) ) if( lxr != 00 ) { // add+=qpassnumber*lxr*lxr; if( gg.z <= LWlight[ll].zbuff[add] ) sh3 = 1.0f; } ggx = ( int ) gg.x + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ); ggy = ( int ) gg.y + ( int ) ( drand98( ) * ss / 2.0f - ss / 4.0 ) + 1; lxr = ( int ) LWlight[ll].xres; add = ggx + lxr * ggy; if( ( add > 0 ) && ( add < lxr * lxr ) ) if( lxr != 00 ) { // add+=qpassnumber*lxr*lxr; if( gg.z <= LWlight[ll].zbuff[add] ) sh4 = 1.0f; } // now interpolate { float rm; float z1, z2; rm = gg.x - floor( gg.x ); z1 = sh1 * ( 1.0f - rm ) + sh2 * rm; z2 = sh4 * ( 1.0f - rm ) + sh3 * rm; rm = gg.y - floor( gg.y ); ret += z1 * ( 1.0f - rm ) + z2 * ( rm ); } } if( floor( ss ) != 0 ) { ret /= ( float ) floor( ss ); } return ( ret ); } static float GOODgetz( VERT gg, int ll ) { int iu, iv; float fu, fv; int add1, add2, add3, add4; { int base; int lxr; // lyr=LWlight[ll].yres; float iz1, iz2, iz = 0; fu = ( float ) ( gg.x ); fv = ( float ) ( gg.y ); lxr = LWlight[ll].xres; if( lxr != 00 ) { // base= iu+iv*LWlight[ll].xres; iu = ( int ) floor( fu ); iv = ( int ) floor( fv ); fu -= ( float ) iu; fv -= ( float ) iv; // fu=1.0f-fu; // fv=1.0f-fv; base = iu + iv * lxr; add1 = base; add2 = base + lxr; add3 = base + 1; add4 = base + lxr + 1; iz1 = LWlight[ll].zbuff[add1] * ( 1.0f - fv ) + LWlight[ll].zbuff[add2] * fv; iz2 = LWlight[ll].zbuff[add3] * ( 1.0f - fv ) + LWlight[ll].zbuff[add4] * fv; iz = iz1 * ( 1.0f - fu ) + iz2 * fu; } return ( ( float ) iz ); } // else return(1000000.0); } static float SHAVEgetz( VERT gg, int ll ) { int iu, iv; float fu, fv; int add1, add2, add3, add4; if( LWlight[ll].zbuff != NULL ) { int base; int lxr; float iz1, iz2, iz; gg.x *= LWlight[ll].xres; gg.y *= LWlight[ll].yres; // lyr=LWlight[ll].yres; fu = ( float ) ( gg.x ); fv = ( float ) ( gg.y ); lxr = LWlight[ll].xres; // base= iu+iv*LWlight[ll].xres; iu = ( int ) floor( fu ); iv = ( int ) floor( fv ); fu -= iu; fv -= iv; // fu=1.0f-fu; // fv=1.0f-fv; base = iu + iv * lxr; add1 = base; add2 = base + lxr; add3 = base + 1; add4 = base + lxr + 1; if( add1 < ( int ) LWlight[ll].zbound ); if( add2 < ( int ) LWlight[ll].zbound ); if( add3 < ( int ) LWlight[ll].zbound ); if( add4 < ( int ) LWlight[ll].zbound ); iz1 = LWlight[ll].zbuff[add1] * ( 1.0f - fv ) + LWlight[ll].zbuff[add2] * fv; iz2 = LWlight[ll].zbuff[add3] * ( 1.0f - fv ) + LWlight[ll].zbuff[add4] * fv; iz = iz1 * ( 1.0f - fu ) + iz2 * fu; return ( ( float ) iz ); } // else return(1000000.0); } static float drand50( int ); // -------------------------------- static VERT cast_shadows_lgt( VERT worldPt, int lgt ) { VERT shad; shad.x = 0; shad.y = 0; shad.z = 0; #ifndef NOLIB if( LWlight[lgt].xres > 0 ) { VERT2 camPt; int i; float m = ( float ) SELF_SHARP * 4.0f; VERT jitt; VERT tcol; tcol = Gilluminate( worldPt, lgt, 1.0 ); camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; for( i = 0; i < 4; i++ ) { jitt.x = ( drand98( ) - .5 ) * m + camPt.x; jitt.y = ( drand98( ) - .5 ) * m + camPt.y; if( ( jitt.x >= 0 ) && ( jitt.y >= 0 ) && ( jitt.y < LWlight[lgt].yres - 1 ) && ( jitt.x < LWlight[lgt].xres - 1 ) ) { float zz; zz = getz( jitt, lgt ); if( jitt.z < zz ) // 1.29 { shad.x += tcol.x; shad.y += tcol.y; shad.z += tcol.z; } } } shad.x /= 4.0f; shad.y /= 4.0f; shad.z /= 4.0f; } #endif return ( shad ); } static float SHAVEcast_shadows( VERT in ) { float bshad = 0; float outbound = 0; int tsh = 0; // total shads float shad = 0; VERT2 tmp; VERT tmpv; int ll; for( ll = 0; ll < totallights; ll++ ) if( LWlight[ll].xres != 00 ) { int i; float ox, oy, oz; float mx, my; tsh++; tmp.x = in.x; tmp.y = in.y; tmp.z = in.z; shad = 0; if( LWlight[ll].xres != 000 ) { tmp = world2cam( &LWlight[ll], tmp ); ox = tmp.x; oy = tmp.y; oz = ( int ) tmp.z; mx = ( float ) LWlight[ll].xres / 650.0f; my = ( float ) LWlight[ll].yres / 650.0f; // mz=(float)LWlight[ll].yres/550.0f; mx = 10; my = 10; for( i = 0; i < MAXPASSES * 2; i++ ) { tmp.x = ( ( drand98( ) - .5 ) ); tmp.y = ( ( drand98( ) - .5 ) ); tmp.x *= mx; tmp.y *= my; tmp.x += ox; tmp.y += oy; if( ( tmp.x >= 0 ) && ( tmp.y >= 0 ) && ( tmp.y < 1 ) && ( tmp.x < 1 ) ) { float zz; tmpv.x = tmp.x; tmpv.y = tmp.y; tmpv.z = tmp.z; zz = SHAVEgetz( tmpv, ll ); if( tmp.z - .000000035 * BOUNDLENGTH > zz ) shad += 1; } else outbound = 1; } } //shad/=(float)(PASSES*2); if( shad > 1.0 ) shad = 1.0f; bshad += shad; } // !=NULL // bshad/=(float)(totallights-totalwindlights); shad = 1 - bshad; if( outbound == 1 ) shad = 1; if( tsh == 0 ) shad = 1; return ( shad ); } static Matrix CurrentMatrix; static void renderdepth( void ) { } //float get_shadow_pix(float xx, float yy, float zz) //{ // return(xx); //} static float get_shadow_pix( float xx, float yy, float zz ) // screen xx and yy + zbuff { int ll; float ret; int it = 0; int ix, iy; int i; float iter = 1; float acc; float amb = ( float ) .1; VERT t, nt; t.z = 0.0f; ix = ( int ) xx; iy = ( int ) yy; ret = 0; acc = 0; for( ll = 0; ll < totallights; ll++ ) { // if (LWlight[ll].zbuff) { t.x = xx; t.y = yy; t.x = ( t.x / ( float ) LWcam.xres ); t.y = ( t.y / ( float ) LWcam.yres ); t.z = ( float ) ( zz ); //// t=vxmp2(LWcam.iview,t); // cam2world // t=vxmp2(LWlight[ll].view,t); //world2light //// t=vxmp2(LWcam.view,t); //t.x+=LWlight[ll].sx; //t.y+=LWlight[ll].sy; // t.x+=1; // t.y+=1; // t.x/=2.0f; // t.y/=2.0f; acc = 0; for( i = 0; i < iter; i++ ) { float lz; nt = t; // nt.x+=(drand98()-.5)*.0015; // nt.y+=(drand98()-.5)*.0035; // nt.z+=(drand98()-.5)*.0035; // nt.x/=LWlight[ll].xres; // nt.y/=LWlight[ll].yres; lz = getz( nt, ll ); // ret=lz; if( lz < ( t.z ) ) // xxxx it's in shadow acc += 1.0f; } } } // ret=acc/(float)(iter*totallights); return ( t.z ); } static VERT cast_shadows( VERT in ) { int i; VERT bshad; VERT tlit; float outbound = 0; VERT total_lit; int tsh = 0; // total shads VERT shad; VERT tmp; int ll; float pss; pss = SELF_SHARP * 3; // pss*=170; pss *= 10; if( pss < 1 ) pss = 1; tlit.x = 0; tlit.y = 0; tlit.z = 0; total_lit.x = 0; total_lit.y = 0; total_lit.z = 0; // if (minsamps!=samps) pss=8; for( ll = 0; ll < totallights; ll++ ) if( LWlight[ll].xlight == 0 ) { VERT wpt2; double tmpp[3], tmpc[3], tmpd[3]; wpt2 = in; { VERT vec; vec.x = LWlight[ll].wpos.x - wpt2.x; vec.y = LWlight[ll].wpos.y - wpt2.y; vec.z = LWlight[ll].wpos.z - wpt2.z; // vec=Vnorm(vec); wpt2.x += .00000211 * vec.x; wpt2.y += .00000211 * vec.y; wpt2.z += .00000211 * vec.z; } tmpp[0] = wpt2.x; tmpp[1] = wpt2.y; tmpp[2] = wpt2.z; tmpc[0] = 0; tmpc[1] = 0; tmpc[2] = 0; // junk=(*Gsa->illuminate)(LWlight[ll].id,tmpp,tmpd,tmpc); //#ifndef RENDERLW { VERT tpos, tcol; tpos.x = tmpp[0]; tpos.y = tmpp[1]; tpos.z = tmpp[2]; tcol = Gilluminate( tpos, ll, 1.0 ); tmpc[0] = tcol.x; tmpc[1] = tcol.y; tmpc[2] = tcol.z; } //#endif lighthit[ll].x = ( float ) tmpc[0]; //-ambient[0]; lighthit[ll].y = ( float ) tmpc[1]; //-ambient[1]; lighthit[ll].z = ( float ) tmpc[2]; //-ambient[2]; //if (LWlight[ll].xlight==0) { //total_lit.x+=lighthit[ll].x; //total_lit.y+=lighthit[ll].y; //total_lit.z+=lighthit[ll].z; total_lit.x += LWlight[ll].color.x; total_lit.y += LWlight[ll].color.y; total_lit.z += LWlight[ll].color.z; } } global_tlit = total_lit; bshad.x = 0; bshad.y = 0; bshad.z = 0; //for (pass=0;pass= 0 ) && ( tmp.y >= 0 ) && ( tmp.y < LWlight[ll].yres - 1 ) && ( tmp.x < LWlight[ll].xres - 1 ) ) { float zz = 0; if( SELF_SHARP < 2 ) zz = getzTURNER( tmp, ll ); if( SELF_SHARP >= 2 ) zz = getz2( tmp, ll ); if( LWlight[ll].wind == 0 ) { shad.x += zz * ( lighthit[ll].x ); shad.y += zz * ( lighthit[ll].y ); shad.z += zz * ( lighthit[ll].z ); if( zz < 1 ) inshad = 1; //if (((lighthit[ll].x+lighthit[ll].y+lighthit[ll].z)>.1)&&(zz>.3)) // { // shad.x+=LWlight[ll].color.x; // shad.y+=LWlight[ll].color.y; // shad.z+=LWlight[ll].color.z; // // } } } // outbound } // zbuff } // passes } // !xlight { shad.x /= ( float ) ( pss ); shad.y /= ( float ) ( pss ); shad.z /= ( float ) ( pss ); bshad.x += shad.x; bshad.y += shad.y; bshad.z += shad.z; } } // lightloop shad = bshad; { VERT tmpshad; tmpshad = shad; /// tmpshad.x=total_lit.x-shad.x; /// tmpshad.y=total_lit.y-shad.y; /// tmpshad.z=total_lit.z-shad.z; tmpshad.x *= ( 1.0f - global_shadow_density ); tmpshad.y *= ( 1.0f - global_shadow_density ); tmpshad.z *= ( 1.0f - global_shadow_density ); // tmpshad.x+=ambient[0]; // tmpshad.y+=ambient[1]; // tmpshad.z+=ambient[2]; tmpshad.x += shad.x; tmpshad.y += shad.y; tmpshad.z += shad.z; //shad=tmpshad; //shad.x*=global_shadow_density; //shad.y*=global_shadow_density; //shad.z*=global_shadow_density; } global_tlit = total_lit; if( shad.x < 0 ) shad.x = 0; if( shad.y < 0 ) shad.y = 0; if( shad.z < 0 ) shad.z = 0; if( shad.x > 1 ) shad.x = 1; if( shad.y > 1 ) shad.y = 1; if( shad.z > 1 ) shad.z = 1; return ( shad ); } static VERT shave_illuminate( VERT in, int ll, VERT vnn ) //VERT shave_illuminate(VERT in,VERT lvec,VERT lcolor); { int i; VERT bshad; VERT tlit; float outbound = 0; VERT total_lit; int tsh = 0; // total shads VERT shad; VERT tmp; float pss; pss = SELF_SHARP * 10; // pss*=SELF_SHARP; if( pss < 2 ) pss = 2; tlit.x = 0; tlit.y = 0; tlit.z = 0; total_lit.x = 0; total_lit.y = 0; total_lit.z = 0; // if (minsamps!=samps) pss=8; if( LWlight[ll].radiosity != 1 ) if( LWlight[ll].caustics != 1 ) { VERT wpt2; double tmpp[3]; double tmpd[3], tmpc[3]; // int junk; VERT vec; wpt2 = in; { // float dd; // vec.x=LWlight[ll].wpos.x-wpt2.x; // vec.y=LWlight[ll].wpos.y-wpt2.y; // vec.z=LWlight[ll].wpos.z-wpt2.z; vec = vnn; vec = Vnorm( vec ); // wpt2.x+=.000002f*vec.x; // wpt2.y+=.000002f*vec.y; // wpt2.z+=.000002f*vec.z; } vnn = Vnorm( vnn ); tmpp[0] = wpt2.x + vnn.x * .01 * restBOUNDLENGTH; tmpp[1] = wpt2.y + vnn.y * .01 * restBOUNDLENGTH; tmpp[2] = wpt2.z + vnn.z * .01 * restBOUNDLENGTH; // tmpp[0]=(double)wpt2.x; // tmpp[1]=(double)wpt2.y; // tmpp[2]=(double)wpt2.z; tmpc[0] = 0; tmpc[1] = 0; tmpc[2] = 0; tmpd[0] = ( double ) ( LWlight[ll].wpos.x - ( float ) tmpp[0] ); tmpd[1] = ( double ) ( LWlight[ll].wpos.y - ( float ) tmpp[1] ); tmpd[2] = ( double ) ( LWlight[ll].wpos.z - ( float ) tmpp[2] ); #ifndef RENDERLW { VERT tpos, tcol; tpos.x = tmpp[0]; tpos.y = tmpp[1]; tpos.z = tmpp[2]; tmpd[0] = LWlight[ll].wpos.x - tpos.x; tmpd[1] = LWlight[ll].wpos.y - tpos.y; tmpd[2] = LWlight[ll].wpos.z - tpos.z; tcol = Gilluminate( tpos, ll, 1.0 ); tmpc[0] = tcol.x; tmpc[1] = tcol.y; tmpc[2] = tcol.z; } #endif #ifdef RENDERLW { int junk; VERT dr; dr.x = ( float ) tmpd[0]; dr.y = ( float ) tmpd[1]; dr.z = ( float ) tmpd[2]; //dr=Vnorm(dr); //tmpp[0]+=(double)(dr.x*.0001); //tmpp[1]+=(double)(dr.y*.0001); //tmpp[2]+=(double)(dr.z*.0001); junk = ( *Gsa->illuminate ) ( LWlight[ll].id, tmpp, tmpd, tmpc ); } #endif lighthit[ll].x = ( float ) tmpc[0]; lighthit[ll].y = ( float ) tmpc[1]; lighthit[ll].z = ( float ) tmpc[2]; lightdirection.x = ( float ) tmpd[0]; lightdirection.y = ( float ) tmpd[1]; lightdirection.z = ( float ) tmpd[2]; lightdirection = Vnorm( lightdirection ); //if (LWlight[ll].xlight==0) { //total_lit.x+=lighthit[ll].x; //total_lit.y+=lighthit[ll].y; //total_lit.z+=lighthit[ll].z; total_lit.x += LWlight[ll].color.x; total_lit.y += LWlight[ll].color.y; total_lit.z += LWlight[ll].color.z; } } global_tlit = total_lit; bshad.x = 0; bshad.y = 0; bshad.z = 0; //for (pass=0;pass= 0 ) && ( tmp.y >= 0 ) && ( tmp.y < LWlight[ll].yres - 1 ) && ( tmp.x < LWlight[ll].xres - 1 ) ) { float zz; if( SELF_SHARP < 2 ) zz = getzTURNER( tmp, ll ); if( SELF_SHARP >= 2 ) zz = getz2( tmp, ll ); if( LWlight[ll].wind == 0 ) { if( zz < 1 ) Ginshad = 1; shad.x += zz * ( lighthit[ll].x ); shad.y += zz * ( lighthit[ll].y ); shad.z += zz * ( lighthit[ll].z ); //if (((lighthit[ll].x+lighthit[ll].y+lighthit[ll].z)>.1)&&(zz>.3)) // { // shad.x+=LWlight[ll].color.x; // shad.y+=LWlight[ll].color.y; // shad.z+=LWlight[ll].color.z; // // } } } // outbound else { shad.x += lighthit[ll].x; shad.y += lighthit[ll].y; shad.z += lighthit[ll].z; } } // zbuff } // passes } // !xlight { shad.x /= ( float ) ( pss ); shad.y /= ( float ) ( pss ); shad.z /= ( float ) ( pss ); bshad.x += shad.x; bshad.y += shad.y; bshad.z += shad.z; } } // lightloop shad = bshad; global_tlit = total_lit; if( LWlight[ll].radiosity == 1 ) if( LWlight[ll].caustics == 1 ) { shad.x = 0; shad.y = 0; shad.z = 0; } if( LWlight[ll].xlight == 1 ) { // shad=lighthit[ll]; } return ( shad ); } static int draw_poly( POLYDAT pp, int layer, unsigned char lum ); static int draw_poly3d( POLYDAT tri, int cs, unsigned char lum ) { int success = 0; VERT2 aaa, bbb, ccc; VERT aa, bb, cc; float s; int x; // GLOBAL_CLIPIT = 0; for( x = 0; x < 3; x++ ) { tri.p[x].z *= -1.0f; tri.v[x].z *= -1.0f; tri.alpha[x] = 1.0f; SHAVEcoord_convertTOSHAVE( &tri.p[x] ); // hack!! SHAVEcoord_convertTOSHAVE( &tri.v[x] ); // hack!! tri.w[x] = tri.p[x]; tri.wv[x] = tri.v[x]; } s = ( float ) current_cam->yres / 2.0f; aaa.x = tri.p[0].x; aaa.y = tri.p[0].y; aaa.z = tri.p[0].z; /// aaa=vxmp3(current_cam->view,tri.p[0],current_cam->zoom); aaa = world2cam( current_cam, aaa ); aa.x = aaa.x; aa.y = aaa.y; aa.z = aaa.z; // aa.x=(aa.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // aa.y=((float)current_cam->yres/2.0 - aa.y * s +.5); // aa.z=aaa.z; bbb.x = tri.p[1].x; bbb.y = tri.p[1].y; bbb.z = tri.p[1].z; // bbb=vxmp3(current_cam->view,tri.p[1],current_cam->zoom); bbb = world2cam( current_cam, bbb ); bb.x = bbb.x; bb.y = bbb.y; bb.z = bbb.z; // bb.x=(bb.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // bb.y=((float)current_cam->yres/2.0 - bb.y * s +.5); // bb.z=bbb.z; ccc.x = tri.p[2].x; ccc.y = tri.p[2].y; ccc.z = tri.p[2].z; // bbb=vxmp3(current_cam->view,tri.p[1],current_cam->zoom); ccc = world2cam( current_cam, ccc ); cc.x = ccc.x; cc.y = ccc.y; cc.z = ccc.z; // cc.x=(cc.x * s /(float) current_cam->aspect + (float)current_cam->xres / (float)2 + .5); // cc.y=((float)current_cam->yres/2.0 - cc.y * s +.5); // cc.z=ccc.z; tri.p[0] = aa; tri.p[1] = bb; tri.p[2] = cc; tri.p[3] = aa; success = 0; // GLOBAL_CLIPIT = 0; // if( ( aaa.clip + bbb.clip + ccc.clip ) != 0 ) // GLOBAL_CLIPIT = 1; { int dm; dm = itsalight; if( dm == 1 ) { itsalight = 1; success = draw_poly( tri, cs, lum ); // 0 } if( dm == 3 ) { itsalight = 3; success = draw_poly( tri, cs, lum ); // 0 } if( dm == 0 ) { { int qq; itsalight = 0; // for (x=0;x #include //#include "polyscan/poly.h" static POLYDAT tocam( LIGHTINFO * cam, POLYDAT pp ) { int x; POLYDAT oldpp; POLYDAT pp1, pp2; // memcpy(&oldpp,&pp,sizeof(POLYDAT)); for( x = 0; x < 3; x++ ) { pp.w[x] = pp.p[x]; pp.wv[x] = pp.v[x]; } if( cam != &LWcam ) if( TILEMODE != 6 ) { for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = world2cam( cam, tmpv ); pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } for( x = 0; x < 3; x++ ) { VERT2 tmpv; VERT2 zero; zero.x = 0.0f; zero.y = 0.0f; zero.z = 0.0f; tmpv.x = pp.v[x].x; tmpv.y = pp.v[x].y; tmpv.z = pp.v[x].z; tmpv = world2cam( cam, tmpv ); zero = world2cam( cam, zero ); pp.v[x].x = tmpv.x - zero.x; pp.v[x].y = tmpv.y - zero.y; pp.v[x].z = tmpv.z - zero.z; } } if( ( cam == &LWcam ) || ( TILEMODE == 6 ) ) { for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = world2cam( &LWCamOPEN, tmpv ); pp1.p[x].x = tmpv.x; pp1.p[x].y = tmpv.y; pp1.p[x].z = tmpv.z; } for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x + pp.v[x].x; tmpv.y = pp.p[x].y + pp.v[x].y; tmpv.z = pp.p[x].z + pp.v[x].z; tmpv = world2cam( &LWCamCLOSE, tmpv ); pp2.p[x].x = tmpv.x; pp2.p[x].y = tmpv.y; pp2.p[x].z = tmpv.z; pp.p[x] = pp1.p[x]; } for( x = 0; x < 3; x++ ) { pp.v[x].x = pp2.p[x].x - pp1.p[x].x; pp.v[x].y = pp2.p[x].y - pp1.p[x].y; pp.v[x].z = pp2.p[x].z - pp1.p[x].z; } } return ( pp ); } static int draw_line( POLYDAT pp, int layer, unsigned char lum ) { int x; int ll; int success = 0; int clipped = 0; POLYDAT pp1; // GLOBAL_CLIPIT = 0; for( x = 0; x < 2; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = cam2world( current_cam, tmpv ); if( tmpv.clip > 0 ) clipped++; /// if (tmpv.clip) GLOBAL_CLIPIT=1; pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } pp1 = tocam( current_cam, pp ); pp1.rad[0] = pp.rad[0]; pp1.rad[1] = pp.rad[1]; //if (clipped==0) if( ( itsalight == 0 ) ) if( ( current_cam == &LWcam ) || ( TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { ll = x; cursamp = x; success += draw_line2( pp1, ll, lum ); } //if (clipped==0) if( TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( itsalight == 1 ) for( x = 0; x < 1; x++ ) { draw_line2( pp1, 0, 0 ); } return ( success ); } static int draw_poly( POLYDAT pp, int layer, unsigned char lum ) { int x; int ll; int success = 0; POLYDAT pp1; // GLOBAL_CLIPIT = 0; for( x = 0; x < 3; x++ ) { VERT2 tmpv; tmpv.x = pp.p[x].x; tmpv.y = pp.p[x].y; tmpv.z = pp.p[x].z; tmpv = cam2world( current_cam, tmpv ); // if( tmpv.clip ) // GLOBAL_CLIPIT = 1; pp.p[x].x = tmpv.x; pp.p[x].y = tmpv.y; pp.p[x].z = tmpv.z; } pp1 = tocam( current_cam, pp ); // printf ("pp1 velocity= %f %f %f\n",pp1.v[0].x,pp1.v[0].y,pp1.v[0].z); // if ((itsalight==0)||(itsalight==2)) if( ( itsalight == 0 ) ) if( ( current_cam == &LWcam ) || ( TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; ll = x; cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_poly2( pp1, ll, lum ); } if( itsalight == 2 ) if( ( current_cam == &LWcam ) || ( TILEMODE == 6 ) ) for( x = 0; x < Gmotion_samp; x++ ) { // current_cam->cursamp=x; // current_cam->lwtime=x; // x = layer; // Was Gcurrent_time ll = x; cursamp = x; // if (itsalight==2) // printf ("drawing occlusions \n"); success += draw_poly2( pp1, ll, lum ); } if( TILEMODE == 0 ) if( Gdeep_shadows == 1 ) if( ( itsalight == 2 ) ) if( current_cam != &LWcam ) for( x = 0; x < GextrasampLIGHT; x++ ) { ll = Gmotion_samp + x; //.. ll=x; cursamp = x; draw_poly2( pp1, x, lum ); } if( TILEMODE == 0 ) if( Gdeep_shadows == 0 ) if( ( itsalight == 2 ) ) if( current_cam != &LWcam ) for( x = 0; x < 1; x++ ) { // ll=layer*Gmotion_samp+x; ll = x; cursamp = x; draw_poly2( pp1, layer, lum ); } if( itsalight == 3 ) // we're tagging tiles for( x = 0; x < Gmotion_samp; x++ ) { // x = layer; cursamp = x; success += draw_poly2( pp1, x, lum ); } if( TILEMODE == 0 ) // if( Gdeep_shadows == 1 ) if( itsalight == 1 ) // for (x=0;x0) draw_a_clumpCP2( h, cs ); } if( itsalight == 1 ) { draw_a_clumpCP2( h, cs ); } } static int draw_a_clumpCP2( RENDERHAIR * h, int cs ) { int success = 0; RENDERHAIR fh; RENDERHAIR hh; int totalhv = 0; float rad; float lastrad; VERT2 tm; int x; float d; int last = 0; int slg = 0; int stp; VERT lastaa; int clip[80]; float hss; //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]; stp = 1; if( global_segs == 5 ) stp = 10; rad = ( float ) restBOUNDLENGTH / 1500.0f; tm.x = h->hv[0].x; tm.y = h->hv[0].y; tm.z = h->hv[0].z; //tm=vxmp(current_cam->view,tm); tm = world2cam( current_cam, tm ); h->segs = global_segs; tm.x += 1.0 / ( float ) current_cam->xres; //tm.y=0; //tm.z=0; //tm=vxmp(current_cam->iview,tm); tm = cam2world( current_cam, tm ); tm.x -= h->hv[0].x; tm.y -= h->hv[0].y; tm.z -= h->hv[0].z; d = fsqrt( 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 == 0 ) if( totallights != 0 ) shade_a_hair( h ); last = 0; lastrad = ( h->thickness ); hss = h->segs * h->cutlength; //#ifndef EXTERNAL_COLLISION if( itsalight == 0 ) //if (cs==0) for( x = 0; x < hss; x++ ) { VERT tmpv; h->color[x].x /= 255.0f; h->color[x].y /= 255.0f; h->color[x].z /= 255.0f; tmpv = h->hv[x]; tmpv.z = -tmpv.z; // hack SHAVEcoord_convertFROMSHAVE( &tmpv ); hh.color[x] = h->color[x]; if( DOING_SWATCH == 0 ) h->color[x] = SHAVEapply_atmosphere( tmpv, h->color[x] ); SHAVEcoord_convertTOSHAVE( &tmpv ); h->color[x].x *= 255.0f; h->color[x].y *= 255.0f; h->color[x].z *= 255.0f; if( h->color[x].x > 255.0 ) h->color[x].x = 255.0f; if( h->color[x].y > 255.0 ) h->color[x].y = 255.0f; if( h->color[x].z > 255.0 ) h->color[x].z = 255.0f; if( h->color[x].x < 0.0 ) h->color[x].x = 0.0f; if( h->color[x].y < 0.0 ) h->color[x].y = 0.0f; if( h->color[x].z < 0.0 ) h->color[x].z = 0.0f; } //#endif lastrad *= rad; for( x = 0; x < hss; x++ ) { float r1; float r2; r2 = ( float ) ( ( hss ) - ( x + 1 ) ) / ( ( float ) hss ) // *sliders[20][h->slgroup].value* * h->thickness; // +h->thickness*sliders[20][h->slgroup].value*.00045); r2 += ( float ) ( ( x + 1 ) ) / ( ( float ) hss ) // *sliders[20][h->slgroup].value* * h->thicknesstip; r2 *= rad; r1 = lastrad; { // float s; VERT2 aaa; VERT aa; aaa.x = h->hv[x].x; aaa.y = h->hv[x].y; aaa.z = h->hv[x].z; aaa = world2cam( current_cam, aaa ); aa.x = aaa.x; aa.y = aaa.y; aa.z = aaa.z; if( r1 < .01f ) r1 = .01f; if( ( fsqrt( ( aa.x - lastaa.x ) * ( aa.x - lastaa.x ) + ( aa.y - lastaa.y ) * ( aa.y - lastaa.y ) ) > 2.55 ) || ( x == ( ( h->segs ) * h->cutlength ) - 1 ) ) { clip[totalhv] = ( int ) aaa.clip; fh.hv[totalhv] = aa; fh.velocity[totalhv] = h->velocity[x]; // printf("%f ",fh.velocity[totalhv].x); lastaa = aa; fh.width[totalhv] = r1; fh.color[totalhv] = h->color[x]; lastrad = r2; totalhv++; } } } // // { unsigned char lum; RENDERHAIR perphair; VERT zero; zero.x = 0; zero.y = 0; zero.z = 0; for( x = 0; x < 80; x++ ) { perphair.hv[x] = zero; } lum = ( unsigned char ) ( h->ambient * 255.0 ); 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;} aa = fh.hv[va]; bb = fh.hv[vb]; vec.x = bb.x - aa.x; vec.y = bb.y - aa.y; vec.z = 0; vec = Vnorm( vec ); { VERT perp; // VERT perp2; perp.x = vec.y; perp.y = -vec.x; perphair.hv[x].x += perp.x; perphair.hv[x].y += perp.y; perphair.hv[x].z += 1.0f; } } for( x = 1; x < totalhv; x++ ) { VERT vec; VERT aa, bb; int va, vb; va = x - 1; vb = x; if( va < 0 ) { va = 0; vb = 1; } aa = fh.hv[va]; bb = fh.hv[vb]; vec.x = bb.x - aa.x; vec.y = bb.y - aa.y; vec.z = 0; vec = Vnorm( vec ); { VERT perp; // VERT perp2; perp.x = vec.y; perp.y = -vec.x; perphair.hv[x].x += perp.x; perphair.hv[x].y += perp.y; perphair.hv[x].z += 1.0f; } } for( x = 0; x < totalhv; x++ ) { if( perphair.hv[x].z != 0 ) { perphair.hv[x].x /= perphair.hv[x].z; perphair.hv[x].y /= perphair.hv[x].z; perphair.hv[x].z = 0; perphair.hv[x] = Vnorm( perphair.hv[x] ); } } for( x = 0; x < totalhv - 1; x++ ) { POLYDAT tri; if( ( ( itsalight == 3 ) && ( success == 0 ) ) || ( itsalight != 3 ) ) // if ((clip[x]==0)||(clip[x+1]==0)) { int a, b; VERT aa, bb; float sz1, sz2; VERT perp, perp2; perp = perphair.hv[x]; perp2 = perphair.hv[x + 1]; sz1 = fh.width[x]; sz2 = fh.width[x + 1]; aa = fh.hv[x]; bb = fh.hv[x + 1]; a = x; b = x + 1; //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.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.c[1] = fh.color[a]; tri.v[1] = fh.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.c[2] = fh.color[b]; tri.v[2] = fh.velocity[b]; // GLOBAL_CLIPIT = 0; success += draw_poly( tri, cs, lum ); 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.c[0] = fh.color[a]; tri.v[0] = fh.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.c[1] = fh.color[b]; tri.v[1] = fh.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.c[2] = fh.color[b]; tri.v[2] = fh.velocity[b]; // GLOBAL_CLIPIT = 0; success += draw_poly( tri, cs, lum ); } } } } } return ( success ); } //fndef RENDERLW //ndif static float calculate_light_cone( VERT in, int lgt, float hambient, VERT * rawcone ) { float cone1 = 0.0f; float cone = 0.0f; VERT shad, jitt, jitt2; VERT2 tmp, tmp2; float self_sharp_z = 0; // int add; int i; int ii; float cx, cy; float ox, oy, oz; float mx = 0, my = 0, mz = 0; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; LIGHTINFO tmplg; // int junk; double tmpc[3]; //in.z *= -1; //SHAVEcoord_convertTOSHAVE(&in); cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; //Gclipz=0; // if (LWlight[lgt].zbuff) if( LWlight[lgt].type == 1 ) { float midx, midy; float ddd; float ddx, ddy, ddz; int oldxres, oldyres; tmplg=LWlight[lgt]; memcpy(tmplg.view,LWlight[lgt].view,sizeof(Matrix)); memcpy(tmplg.iview,LWlight[lgt].iview,sizeof(Matrix)); oldxres = LWlight[lgt].xres; oldyres = LWlight[lgt].xres; // if( oldxres == 0 ) // { tmplg.xres = 100; tmplg.yres = 100; // } tmp.x = in.x; tmp.y = in.y; tmp.z = in.z; tmp = world2cam( &tmplg, tmp ); //Gclipz=0; if( tmp.clipz == 0 ) { float ftpx; ftpx = ( ( float ) LWlight[lgt].fuzz / ( float ) LWlight[lgt].xres ); midx = ( float ) LWlight[lgt].xres / 2.0f; midy = ( float ) LWlight[lgt].xres / 2.0f; ddx = tmp.x - midx; ddy = tmp.y - midy; cone = 1.0f; ddd = ( float ) fsqrt( ( ddx * ddx ) + ( ddy * ddy ) ); if( midx > 0.0f ) ddd /= ( float ) midx; //ddd/=2.0f; // half fov?? if( ddd >= .99f - ftpx ) cone = 0.0f; if( ddd < 0.55f ) cone = 1.0f; if( ( ddd >= 0.55f ) && ( ddd < 1.0f - ftpx ) ) { ddd -= 0.55f; ddd *= ( ( 1.0f - ftpx ) / .45f ); if( ddd < 0.0f ) ddd = 0.0f; // ddd=1.0f-ddd; ddd = ( 1.0f - ftpx ) - ddd; cone = ddd; } } // if( oldxres == 0 ) // { // LWlight[lgt].xres = 0; // LWlight[lgt].yres = 0; // } } //if (LWlight[lgt].zbuff) if( LWlight[lgt].isroot ) if( LWlight[lgt].type == 0 ) { float midx, midy; float ddd; float ddx, ddy, ddz; int oldxres, oldyres; tmplg=LWlight[lgt]; oldxres = LWlight[lgt].xres; oldyres = LWlight[lgt].xres; memcpy(tmplg.view,LWlight[lgt].view,sizeof(Matrix)); memcpy(tmplg.iview,LWlight[lgt].iview,sizeof(Matrix)); // if( oldxres == 0 ) // { tmplg.xres = 100; tmplg.yres = 100; // } tmp.x = in.x; tmp.y = in.y; tmp.z = in.z; tmp = world2cam( &tmplg, tmp ); //Gclipz=0; if( tmp.clipz == 0 ) { cone = 1.0f; } // if( oldxres == 0 ) // { // LWlight[lgt].xres = 0; // LWlight[lgt].yres = 0; // } } shad.x = 0.0f; shad.y = 0.0f; shad.z = 0.0f; if( totallights == 0 ) cone = 1.0f; //#ifdef crap if( LWlight[lgt].isroot ) { in.z *= -1; SHAVEcoord_convertFROMSHAVE( &in ); if( DOING_SWATCH == 0 ) cone = SHAVEapply_falloff( lgt, in, cone ); SHAVEcoord_convertTOSHAVE( &in ); in.z *= -1; } //#endif if( LWlight[lgt].isroot ) if( cone > 0.0f ) if( ( LWlight[lgt].zbuff ) || ( LWlight[lgt].trace ) ) { int i; float cx, cy; VERT worldPt; worldPt = in; shad.x = 0; shad.y = 0; shad.z = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; if( LWlight[lgt].trace == 0 ) { if( LWlight[lgt].xres > 0 ) if( ( totallights > 0 ) && ( LWlight[lgt].zbuff != NULL ) ) { float lx, ly, hx, hy; float sharp; sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if( ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt = 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; // come back { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); // for (p=0;p<4;p++) // no aa? p = 0; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; if( lx < 0 ) lx = 0; if( lx > lxr ) lx = lxr; ly = camPt.y - sharp; if( ly < 0 ) ly = 0; if( ly > lyr ) ly = lyr; hx = camPt.x + sharp; if( hx < 0 ) hx = 0; if( hx > lxr ) hx = lxr; hy = camPt.y + sharp; if( hy < 0 ) ly = 0; if( hy > lyr ) hy = lyr; if( lx == hx ) shad.x = 0.0f; if( ly == hy ) shad.x = 0.0f; if( camPt.clipz == 0 ) shad.x = illum_boxGEOM( jitt.z, lgt, lx, ly, hx, hy ); else shad.x = 0.0f; if( lxr == 0 ) shad.x = 1.0f; } shad.y = shad.x; shad.z = shad.x; } } if( LWlight[lgt].xres == 0 ) { shad.x = 1.0; shad.y = 1.0; shad.z = 1.0; } } else // Gtrace != 0 if( LWlight[lgt].trace ) { VOXSAMP vsamp; VERT rdir; rdir.x = LWlight[lgt].wpos.x - worldPt.x; rdir.y = LWlight[lgt].wpos.y - worldPt.y; rdir.z = LWlight[lgt].wpos.z - worldPt.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, worldPt, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; shad.x = shad.y = shad.z = ( 1.0f - vsamp.opacity ) * 0.75f + 0.25f; } calibrateX = cx; calibrateY = cy; } else { if( LWlight[lgt].isroot ) if( LWlight[lgt].xres == 0 ) { shad.x = 1.0; shad.y = 1.0; shad.z = 1.0; } } //#endif if( LWlight[lgt].isroot == 1 ) { LWlight[lgt].conefalloff = cone; LWlight[lgt].coneillum = shad; } if( !LWlight[lgt].isroot ) { cone = LWlight[lgt].conefalloff; shad = LWlight[lgt].coneillum; } cone1 = cone * shad.x; if( ( LWlight[lgt].xres > 0 ) && ( LWlight[lgt].zbuff == NULL ) ) { cone = 1.0f; shad.x = 1.0f; cone1 = 1.0f; } shad.x = ( shad.x + LWlight[lgt].shadowcolor.x * ( 1.0 - shad.x ) ) * ( hambient ) + ( 1.0f - hambient ); shad.y = ( shad.y + LWlight[lgt].shadowcolor.y * ( 1.0 - shad.y ) ) * ( hambient ) + ( 1.0f - hambient ); shad.z = ( shad.z + LWlight[lgt].shadowcolor.z * ( 1.0 - shad.z ) ) * ( hambient ) + ( 1.0f - hambient ); rawcone->x = cone * shad.x; rawcone->y = cone * shad.y; rawcone->z = cone * shad.z; // cone *= shad.x; bad calibrateX = cx; calibrateY = cy; // cone=0.0f; // bad return ( cone1 ); } static VERT cast_shadows_lgt_simplePLUSGEOM( VERT worldPt, int lgt ) { VERT shad; shad.x = 0; shad.y = 0; shad.z = 0; SELF_SHARP = LWlight[lgt].fuzz * ( ( float ) LWlight[lgt].xres / 600.0f ); if( LWlight[lgt].xres != 0 ) { VERT2 camPt; float cone = 1.0f; int i; float m = ( float ) SELF_SHARP; int numSamples; VERT jitt; camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt = world2cam( &LWlight[lgt], camPt ); if( camPt.clip == 0 ) { if( freeze.totalverts > 0 ) numSamples = 4; else numSamples = 10; jitt.z = camPt.z; for( i = 0; i < numSamples; i++ ) { jitt.x = ( drand98( ) - .5 ) * m + camPt.x; jitt.y = ( drand98( ) - .5 ) * m + camPt.y; #ifdef C4D if( ( jitt.x >= 0 ) && ( jitt.x < LWlight[lgt].xres - 1 ) && ( jitt.y >= 0 ) && ( jitt.y < LWlight[lgt].yres - 1 ) ) #endif { float zz; zz = getz( jitt, lgt ); if( jitt.z < zz ) // 1.29 { 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 } shad.x /= ( float ) ( numSamples ); shad.y /= ( float ) ( numSamples ); shad.z /= ( float ) ( numSamples ); shad.x *= cone; shad.y *= cone; shad.z *= cone; } } return shad; } extern void MAYAmake_view_matrix( Matrix vm, VERT vv, VERT nn, VERT wpos, float fov ) { float e; VERT rr; VERT uu; nn = Vnorm( nn ); vv = Vnorm( vv ); uu = Vcross( nn, vv ); // original uu = Vnorm( uu ); vv = Vcross( uu, nn ); // the original!! //uu.x*= -1; //uu.y*= -1; //uu.z*= -1; rr = wpos; e = 1.0 / tan( fov * 6.283 / 360.0 ); //rr.x-=e*nn.x; //rr.y-=e*nn.y; //rr.z-=e*nn.z; vm[0][0] = ( float ) uu.x; vm[0][1] = ( float ) vv.x; vm[0][2] = ( float ) nn.x; vm[1][0] = ( float ) uu.y; vm[1][1] = ( float ) vv.y; vm[1][2] = ( float ) nn.y; vm[2][0] = ( float ) uu.z; vm[2][1] = ( float ) vv.z; vm[2][2] = ( float ) nn.z; vm[3][0] = ( float ) -VDot( rr, uu ); vm[3][1] = ( float ) -VDot( rr, vv ); vm[3][2] = ( float ) -VDot( rr, nn ) + e; vm[0][3] = ( float ) ( -nn.x / e ); vm[1][3] = ( float ) ( -nn.y / e ); vm[2][3] = ( float ) ( -nn.z / e ); vm[3][3] = ( float ) ( 1.0 + ( ( float ) VDot( rr, nn ) - e ) / ( float ) e ); } void MAYAinit_scene( void ) { int x; float zr = 0.0f; // NaN = zr / zr; NaN = 0.0f; alltiles.dice = 3; facelistSP = NULL; //init_geomWF(&Guv); for( x = 0; x < 400; x++ ) hairfiles[x].data = NULL; for( x = 0; x < 400; x++ ) hairstate[x].data = NULL; // for( x = 0; x < 400; x++ ) // { // Gindex_stack[x]=NULL; // Gkd_stack[x]=NULL; // } init_buffers( ); init_subdiv( ); init_poly_vox( ); nullify_maps( ); init_noise( ); for( x = 0; x < 60; x++ ) init_geomWF( &Guv_sets[x] ); for( x = 0; x < 60; x++ ) Guv_link[x] = -1; Guv_totalsets = 0; global_lastID = -1; } void MAYAclear_scene( void ) { int x; lsSHAVEID = -1; freevox( ); if( totalhairfiles > 0 ) { for( x = 0; x < totalhairfiles; x++ ) { if( hairfiles[x].data ) free( hairfiles[x].data ); hairfiles[x].data=NULL; } for( x = 0; x < totalhairfiles; x++ ) { if( hairstate[x].data ) free( hairstate[x].data ); hairstate[x].data=NULL; // if (Gindex_stack[x]) free(Gindex_stack[x]); // if (Gkd_stack[x]) kd_free(Gkd_stack[x]); } hairfiles[x].size = 0; hairfiles[x].pos = 0; hairstate[x].size = 0; hairstate[x].pos = 0; } destroy_buffers( ); totalhairfiles = 0; totallights = 0; } static unsigned char *Limage[400]; int MAYAadd_light( float r, float g, float b, Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip, float fuzz, int shadsamps, float shadr, float shadg, float shadb, int trace, int type ) { float e; Matrix ivm; int x, y; int id; oversamp = 1; id = totallights; //if (totalhairfiles==0) printf ("ERROR : You MUST add all the hairfiles before adding lights"); //wpos.x= -wpos.x; //wpos.y= -wpos.y; if( GLOBAL_VERBOSE ) { printf( "add_light - light:%d fuzz:%f shadsamps:%d\n", totallights, fuzz, shadsamps ); printf( "wpos = %f %f %f fov = %f\n", wpos.x, wpos.y, wpos.z, fov ); printf( "restBOUNDLENGTH = %f\n", restBOUNDLENGTH ); } init_noise( ); srand( 0 ); Jsrand( 0 ); // for( x = 0; x < 255; x++ ) { // LWlight[x].ibuff = NULL; // LWlight[x].zbuff = NULL; // LWlight[x].Gzbuff = NULL; // LWlight[x].lumbuff = NULL; // LWlight[x].geombuff = NULL; } LWlight[totallights].type = type; LWlight[totallights].fuzz = fuzz; LWlight[totallights].shadsamps = shadsamps; // LWlight[totallights].trace = 0; // default - no tracing LWlight[totallights].trace = trace; inverse( vm, ivm ); for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWlight[totallights].view[x][y] = vm[x][y]; for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWlight[totallights].iview[x][y] = ivm[x][y]; LWlight[totallights].wpos = wpos; LWlight[totallights].xres = xres; LWlight[totallights].yres = xres; // LWlight[totallights].yres=yres; LWlight[totallights].aspect = aspect; LWlight[totallights].nearclip = nearClip; LWlight[totallights].aspect = 1.0f; LWlight[totallights].caustics = 0; LWlight[totallights].radiosity = 0; LWlight[totallights].wind = 0; LWlight[totallights].xlight = 0; e = 1.0 / tan( fov * 6.283 / 360.0 ); LWlight[totallights].zoom = e; // if (name[0]=='w') LWlight[totallights].wind=1; if( LWlight[totallights].wind == 1 ) { LWlight[totallights].xres = 0; // not illuminating LWlight[totallights].yres = 0; // it's a wind light } // LWlight[totallights].zbuff = NULL; // LWlight[totallights].Gzbuff = NULL; // LWlight[totallights].ibuff = NULL; // LWlight[totallights].lumbuff = NULL; // LWlight[totallights].geombuff = NULL; LWlight[totallights].xrsq = LWlight[totallights].xres * LWlight[totallights].xres; // LWlight[totallights].name=name; // LWlight[totallights].filename=outfilename; // if (LWlight[totallights].xres>0) // mkDEPTHbuffer(&LWlight[totallights]); // no image buffer for lights // if (LWlight[totallights].xres>0) // mkIMAGEbuffer(&LWlight[totallights]); LWlight[totallights].color.x = r; LWlight[totallights].color.y = g; LWlight[totallights].color.z = b; LWlight[totallights].shadowcolor.x = shadr; LWlight[totallights].shadowcolor.y = shadg; LWlight[totallights].shadowcolor.z = shadb; // printf("adding light %f %f %f\n",r,g,b); //Limage[totallights]= image; totallights++; return ( id ); } void MAYAset_cameraOPEN( Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip ) { float e; Matrix ivm; int x, y; inverse( vm, ivm ); for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWCamOPEN.view[x][y] = vm[x][y]; for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWCamOPEN.iview[x][y] = ivm[x][y]; LWCamOPEN.wpos = wpos; LWCamOPEN.xres = xres; LWCamOPEN.yres = yres; LWCamOPEN.aspect = aspect; LWCamOPEN.caustics = 0; LWCamOPEN.radiosity = 0; LWCamOPEN.nearclip = nearClip; LWCamOPEN.wind = 0; memcpy( LWcam.view, LWCamOPEN.view, sizeof( LWCamOPEN.view ) ); memcpy( LWcam.iview, LWCamOPEN.iview, sizeof( LWCamOPEN.iview ) ); LWcam.caustics = 0; LWcam.wind = 0; LWcam.radiosity = 0; LWcam.zbuff = NULL; LWcam.Gzbuff = NULL; LWcam.geombuff = NULL; LWcam.ibuff = NULL; // LWcam.name="Camera"; // LWcam.filename=outfilename; // LWcam.sx=drand49()*1.0f-.5; // LWcam.sy=drand49()*1.0f-.5; // LWcam.sx=0; // LWcam.sy=0; LWcam.xres = ( int ) LWCamOPEN.xres; LWcam.yres = ( int ) LWCamOPEN.yres; LWcam.aspect = ( float ) LWCamOPEN.aspect; LWcam.nearclip = ( float ) LWCamOPEN.nearclip; //if (fov!=0) e = 1.0 / tan( fov * 6.283 / 360.0 ); //else e=0; LWcam.zoom = e; LWCamOPEN.zoom = e; } void MAYAset_cameraCLOSE( Matrix vm, VERT wpos ) { Matrix ivm; int x, y; int maxp = 0; inverse( vm, ivm ); for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWCamCLOSE.view[x][y] = vm[x][y]; for( y = 0; y < 4; y++ ) for( x = 0; x < 4; x++ ) LWCamCLOSE.iview[x][y] = ivm[x][y]; LWCamCLOSE.wpos = wpos; LWCamCLOSE.xres = LWCamOPEN.xres; LWCamCLOSE.yres = LWCamOPEN.yres; LWCamCLOSE.aspect = LWCamOPEN.aspect; LWCamCLOSE.caustics = 0; LWCamCLOSE.radiosity = 0; LWCamCLOSE.wind = 0; LWcam.geombuff = NULL; LWcam.ibuff = NULL; LWcam.zbuff = NULL; LWcam.Gzbuff = NULL; // LWcam.name="Camera"; // LWcam.sx=drand49()*1.0f-.5; // LWcam.sy=drand49()*1.0f-.5; // LWcam.sx=0; // LWcam.sy=0; LWcam.xres = ( int ) LWCamOPEN.xres; LWcam.yres = ( int ) LWCamOPEN.yres; LWcam.aspect = ( float ) LWCamOPEN.aspect; LWcam.nearclip = ( float ) LWCamOPEN.nearclip; 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; //oversamp=1; // mkIMAGEbuffer(&LWcam); // mkDEPTHbuffers(&LWcam); } void MAYAadd_hairOPEN( MEMFILE * hairdataREST, MEMFILE * Ihairstate ) { long x, y; global_lastID = -1; hairfiles[totalhairfiles].size = hairdataREST->size; hairstate[totalhairfiles].size = ( long ) Ihairstate->size; hairstate[totalhairfiles].pos = 0; hairstate[totalhairfiles].ID = hairdataREST->ID; hairstate[totalhairfiles].time = hairdataREST->time; hairfiles[totalhairfiles].pos = 0; hairfiles[totalhairfiles].ID = hairdataREST->ID; hairfiles[totalhairfiles].time = Ihairstate->time; // hairfiles[totalhairfiles].time = hairdataREST->time; hairfiles[totalhairfiles].data = ( char * ) malloc( 100 + hairdataREST->size * sizeof( char ) ); for( x = 0; x < hairfiles[totalhairfiles].size; x++ ) hairfiles[totalhairfiles].data[x] = hairdataREST->data[x]; hairstate[totalhairfiles].data = ( char * ) malloc( Ihairstate->size * sizeof( char ) + 100 ); for( x = 0; x < hairstate[totalhairfiles].size; x++ ) hairstate[totalhairfiles].data[x] = Ihairstate->data[x]; RW_CONTEXT = RW_LOCAL; hairdataREST->pos = 0; read_hair( hairdataREST ); hairdataREST->pos = 0; if( 0 == 1 ) if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) { hair[x].lasthv[y] = hair[x].resthv[y]; hair[x].hv[y] = hair[x].resthv[y]; } if( 0 == 1 ) if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) { Slasthair[x].hv[y] = Sresthair[x].hv[y]; Sthishair[x].hv[y] = Sresthair[x].hv[y]; } { // int x,y; Ihairstate->pos = 0; //printf ("reading state info\n"); for( x = 0; x < 5; x++ ) { if( total_slgfaces[x] > 0 ) if( LOCAL_PASSES[x] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[x]; } read_state_machine( Ihairstate ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) hair[x].lasthv[y] = hair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Slasthair[x].hv[y] = Sthishair[x].hv[y]; hairstate[totalhairfiles].pos = 0; hairfiles[totalhairfiles].time = Ihairstate->time; write_state_machine( &hairstate[totalhairfiles] ); } //printf("done\n"); RW_CONTEXT = RW_DISK; ///for (x=0;x<5;x++) //{ //Gshavep[totalhairfiles].haircount[x]=LOCAL_CNT[x]; //Gshavep[totalhairfiles].passes[x]=LOCAL_PASSES[x]; //} } void MAYAadd_hairCLOSE( MEMFILE * Ohairstate, SHAVEPARMS * shavep ) { int x; hairstate[totalhairfiles].pos = 0; hairfiles[totalhairfiles].pos = 0; RW_CONTEXT = RW_LOCAL; // read_hair( &hairfiles[totalhairfiles] ); if( hairstate[totalhairfiles].size == Ohairstate->size ) { global_lastID = -1; memcpy( &Gshavep[totalhairfiles], shavep, sizeof( SHAVEPARMS ) ); RW_CONTEXT = RW_LOCAL; //printf ("reading hair info (for close)\n"); // read_hair( &hairfiles[totalhairfiles] ); MAYAset_parms( shavep ); #ifdef diagnose_trouble fprintf(stdout,"ID = %d clumps = %d add_hairCLOSE\n",SHAVEID,Gclumps);fflush(stdout); #endif { int x, y; BASEHAIR *TMPhair = NULL; BASEHAIR *TMPspline = NULL; //printf ("reading state info (for close)\n"); read_state_machine( &hairstate[totalhairfiles] ); if( totalverts > 0 ) TMPhair = ( BASEHAIR * ) malloc( totalverts * sizeof( BASEHAIR ) ); if( total_splines > 0 ) TMPspline = ( BASEHAIR * ) malloc( total_splines * sizeof( BASEHAIR ) ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) TMPhair[x].hv[y] = hair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) TMPspline[x].hv[y] = Sthishair[x].hv[y]; read_state_machine( Ohairstate ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) hair[x].lasthv[y] = TMPhair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Slasthair[x].hv[y] = TMPspline[x].hv[y]; hairstate[totalhairfiles].pos = 0; write_state_machine( &hairstate[totalhairfiles] ); if( totalverts > 0 ) Nfree( TMPhair ); if( total_splines > 0 ) Nfree( TMPspline ); } } hairstate[totalhairfiles].pos = 0; write_state_machine( &hairstate[totalhairfiles] ); memcpy( &Gshavep[totalhairfiles], shavep, sizeof( SHAVEPARMS ) ); for( x = 0; x < 5; x++ ) { Gshavep[totalhairfiles].haircount[x] = LOCAL_CNT[x]; Gshavep[totalhairfiles].shadowHaircount[x] = LOCAL_SHADCNT[x]; Gshavep[totalhairfiles].passes[x] = LOCAL_PASSES[x]; Gshavep[totalhairfiles].segs[x] = LOCAL_SEGS[x]; } for( x = 0; x < 60; x++ ) Gshavep[totalhairfiles].uv_link[x] = Guv_link[x]; //SHAVEID=totalhairfiles; // xcxcxc totalhairfiles++; RW_CONTEXT = RW_DISK; } static void clear_buffers( void ) { int x, y; int es; es = Gmotion_samp; #ifndef RENDERLW // for (y=0;y 0 ) if( LOCAL_PASSES[yy] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[yy]; } for( yy = 0; yy < totalverts; yy++ ) for( zz = 0; zz < 15; zz++ ) { hair[yy].velocity[zz].x = hair[yy].hv[zz].x - hair[yy].lasthv[zz].x; hair[yy].velocity[zz].y = hair[yy].hv[zz].y - hair[yy].lasthv[zz].y; hair[yy].velocity[zz].z = hair[yy].hv[zz].z - hair[yy].lasthv[zz].z; hair[yy].hv[zz] = hair[yy].lasthv[zz]; } for( yy = 0; yy < total_splines; yy++ ) { for( zz = 0; zz < 15; zz++ ) { Shair[yy].hv[zz] = Slasthair[yy].hv[zz]; Shair[yy].velocity[zz].x = Sthishair[yy].hv[zz].x - Slasthair[yy].hv[zz].x; Shair[yy].velocity[zz].y = Sthishair[yy].hv[zz].y - Slasthair[yy].hv[zz].y; Shair[yy].velocity[zz].z = Sthishair[yy].hv[zz].z - Slasthair[yy].hv[zz].z; } } hairfiles[xx].pos = 0; hairstate[xx].pos = 0; RW_CONTEXT = oldContext; GnodeID = xx; // this is a stack ID not a hair ID } static void push_lightbuffs( int tobuf ) { int x, y, z; int add1, add2; for( y = 0; y < totallights; y++ ) if( LWlight[y].zbuff != NULL ) for( z = 0; z < GextrasampLIGHT; z++ ) if( Gdeep_shadows == 1 ) { add2 = LWlight[y].xres * LWlight[y].xres * GextrasampLIGHT * tobuf; for( x = 0; x < LWlight[y].xres * LWlight[y].xres * GextrasampLIGHT; x++ ) { int tb; tb = x + add2; if( tb < ( int ) LWlight[y].zbound ) LWlight[y].zbuff[tb] = LWlight[y].zbuff[x]; } } } static void pop_lightbuffs( int tobuf ) { int x, y; int add1, add2; for( y = 0; y < totallights; y++ ) if( LWlight[y].zbuff != NULL ) if( Gdeep_shadows == 1 ) { add2 = LWlight[y].xres * LWlight[y].xres * tobuf; for( x = 0; x < LWlight[y].xres * LWlight[y].xres; x++ ) { int tb; tb = x + add2; if( tb < ( int ) LWlight[y].zbound ) LWlight[y].zbuff[x] = LWlight[y].zbuff[tb]; } } } extern void SHAVEdestroy_buffers( void ) { int n; destroy_buffers( ); for (n=0;n<255;n++) { LWlight[n].xres = 0; LWlight[n].ibound = 0; LWlight[n].gbound = 0; LWlight[n].zbound = 0; } } static LIGHTINFO interp_view( LIGHTINFO cam1, LIGHTINFO cam2, float ee ) { LIGHTINFO out; int x, y; memcpy( &out, &cam1, sizeof( LIGHTINFO ) ); for( x = 0; x < 4; x++ ) for( y = 0; y < 4; y++ ) { out.view[x][y] = cam1.view[x][y] * ( 1.0f - ee ) + cam2.view[x][y] * ( ee ); } inverse( out.view, out.iview ); out.wpos.x = cam1.wpos.x * ( 1.0f - ee ) + cam2.wpos.x * ee; out.wpos.y = cam1.wpos.y * ( 1.0f - ee ) + cam2.wpos.y * ee; out.wpos.z = cam1.wpos.z * ( 1.0f - ee ) + cam2.wpos.z * ee; out.aspect = cam1.aspect * ( 1.0f - ee ) + cam2.aspect * ee; out.zoom = cam1.zoom * ( 1.0f - ee ) + cam2.zoom * ee; return ( out ); } int MAYArender_frame( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int deep_shadows ) { int x, y, AA, xx; int pass; int mb; int est = 0; float avgz = 0.0f; int *acimage = NULL; int *acimage2 = NULL; WFTYPE geom; init_noise( ); init_geomWF( &geom ); Gdeep_shadows = deep_shadows; Glow_mem = 0; if( clipx0 < 0 ) clipx0 = 0; if( clipy0 < 0 ) clipy0 = 0; if( clipx1 > LWcam.xres - 1 ) clipx1 = LWcam.xres - 1; if( clipy1 > LWcam.yres - 1 ) clipy1 = LWcam.yres - 1; Gclipx0 = clipx0; Gclipx1 = clipx1; Gclipy0 = clipy0; Gclipy1 = clipy1; global_progress = 0; reset_faces( ); for( x = 0; x < antialiasing; x++ ) { float ee; ee = ( float ) x / ( float ) antialiasing; LWcamtable[x] = interp_view( LWCamOPEN, LWCamCLOSE, ee ); } if( GLOBAL_VERBOSE ) printf( "clearing output buffers\n" ); for( x = 0; x < LWcam.xres * ( LWcam.yres ) * 4; x++ ) image[x] = 0; for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) zbuff[x] = 1000000.0f; if( GLOBAL_VERBOSE ) printf( "allocating accumulation buffers\n" ); acimage = ( int * ) malloc( ( LWcam.xres + 1 ) * ( LWcam.yres + 1 ) * 4 * sizeof( int ) ); acimage2 = ( int * ) malloc( ( LWcam.xres + 1 ) * ( LWcam.yres + 1 ) * 4 * sizeof( int ) ); if( acimage2 == NULL ) { Nfree( acimage ); Glow_mem = 1; if( GLOBAL_VERBOSE ) printf( "**** ERROR **** out of memory, allocating accumulating buffer\n" ); } if( GLOBAL_VERBOSE ) printf( "clearing accumulation buffers\n" ); if( Glow_mem == 0 ) { for( x = 0; x < LWcam.xres * LWcam.yres * 4; x++ ) acimage[x] = 0; for( x = 0; x < LWcam.xres * LWcam.yres * 4; x++ ) acimage2[x] = 0; //if (MBsampling<1) MBsampling=1; if( antialiasing < 1 ) antialiasing = 1; OPENGL_DRAW = 0; { char tmp[255]; sprintf( tmp, "SHAVE render version %s (c) 2019 Epic Games, US Patent 6720962\n", version_info ); if( GLOBAL_VERBOSE ) printf( "%s", tmp ); } if( GLOBAL_VERBOSE ) printf( "----------------------------------------------------\n" ); //printf ("initializing volume data\n"); //VXinit_bound (&ddt); //printf ("done\n"); if( GLOBAL_VERBOSE ) printf( "MAXPASSES = %d\n", MAXPASSES ); if( GLOBAL_VERBOSE ) printf( "allocating geometry\n" ); geom.totalverts = geom_open->totalverts; geom.totalfaces = geom_open->totalfaces; geom.totalfverts = geom_open->totalfverts; ambient[0] = 0; ambient[1] = 0; ambient[2] = 0; alloc_geomWF( &geom ); rand48_seed = 0; for( x = 0; x < geom_open->totalfaces; x++ ) { geom.face_start[x] = geom_open->face_start[x]; geom.face_end[x] = geom_open->face_end[x]; } for( x = 0; x < geom_open->totalfverts; x++ ) geom.facelist[x] = geom_open->facelist[x]; for( x = 0; x < geom_open->totalverts; x++ ) { geom.v[x] = geom_open->v[x]; geom.velocity[x].x = geom_close->v[x].x - geom_open->v[x].x; geom.velocity[x].y = geom_close->v[x].y - geom_open->v[x].y; geom.velocity[x].z = geom_close->v[x].z - geom_open->v[x].z; } // if (GLOBAL_VERBOSE) //printf ("motion blur sampling = %d\n",MBsampling); if( GLOBAL_VERBOSE ) printf( "over sampling = %d\n", antialiasing ); oversamp = 1; Gmotion_samp = antialiasing; GextrasampLIGHT = 1; if( GLOBAL_VERBOSE ) printf( "memflag = %d\n", Glow_mem ); //fflush(stdout); LWcam = LWCamOPEN; // remember to interpolate this stuff if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "making image buffer (cam)\n" ); //fflush(stdout); if( Glow_mem == 0 ) mkIMAGEbuffer( &LWcam ); if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "making depth buffers (cam)\n" ); //fflush(stdout); if( Glow_mem == 0 ) mkDEPTHbuffers( &LWcam ); if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "making depth buffers (lights)\n" ); //fflush(stdout); if( Glow_mem == 0 ) for( x = 0; x < totallights; x++ ) if( LWlight[x].xres > 0 ) mkDEPTHbuffer( &LWlight[x] ); //oversamp=antialiasing; if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "estimating passes\n" ); //fflush(stdout); // estimate number of callbacks for progress bar if( Glow_mem == 0 ) for( xx = 0; xx < totalhairfiles; xx++ ) { fetch_hair( xx, 0.0 ); if( total_slgfaces[0] ) est += LOCAL_CNT[0]; if( total_slgfaces[1] ) est += LOCAL_CNT[1]; if( total_slgfaces[2] ) est += LOCAL_CNT[2]; if( total_slgfaces[3] ) est += LOCAL_CNT[3]; if( total_splines ) est += LOCAL_CNT[4]; } est += ( est * totallights ); ///est*=MBsampling; est *= ( MAXPASSES ); avgz = 1000000.0f; //est/=100; estimated_total = est; if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "rendering light buffers\n" ); //fflush(stdout); if( Glow_mem == 0 ) { float tt; mb=0; tt = ( ( float ) mb / ( float ) 1 ); for( pass = 0; pass < MAXPASSES; pass++ ) if( ( Gdeep_shadows == 1 ) || ( ( Gdeep_shadows == 0 ) && ( pass == 0 ) ) ) { int yy; for( yy = 0; yy < totallights; yy++ ) if( LWlight[yy].zbuff != NULL ) if( LWlight[yy].xres > 0 ) for( x = 0; x < LWlight[yy].xres * LWlight[yy].yres; x++ ) LWlight[yy].zbuff[x] = 1000000.0f; TILEMODE=0; itsalight = 2; for( x = 0; x < totallights; x++ ) { current_cam = &LWlight[x]; draw_geomWF( &geom, 0 ); } for( xx = 0; xx < totalhairfiles; xx++ ) { itsalight = 1; fetch_hair( xx, tt ); if( freeze.totalverts == 0 ) draw_lotsHAIROLD( pass ); else { WFdraw_lotsINST( pass ); } } push_lightbuffs( ( pass ) + 1 ); } } if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "rendering image buffers\n" ); if( Glow_mem == 0 ) { float tt; mb=0; for( x = 0; x < LWcam.xres * LWcam.yres * 4; x++ ) acimage[x] = 0; tt = 0; if( GLOBAL_VERBOSE ) printf( "drawing hair\n" ); if( Glow_mem == 0 ) for( pass = 0; pass < MAXPASSES; pass++ ) { int yy; LWcam.sx = campass[mb].x; LWcam.sy = campass[mb].y; for( x = 0; x < 4 * LWcam.xres * LWcam.yres * Gmotion_samp; x++ ) LWcam.ibuff[x] = 0; for( x = 0; x < LWcam.xres * LWcam.yres * Gmotion_samp; x++ ) LWcam.zbuff[x] = 1000000.0f; for( x = 0; x < LWcam.xres * LWcam.yres * Gmotion_samp; x++ ) LWcam.geombuff[x] = 1000000.0f; current_cam = &LWcam; itsalight = 2; draw_geomWF( &geom, 0 ); if( Glow_mem == 0 ) for( xx = 0; xx < totalhairfiles; xx++ ) { itsalight = 0; fetch_hair( xx, tt ); if( freeze.totalverts == 0 ) draw_lotsHAIROLD( pass ); else WFdraw_lotsINST( pass ); } if( Glow_mem == 0 ) for( x = 0; x < LWcam.xres; x++ ) for( y = 0; y < ( LWcam.yres ); y++ ) { int q; int add, add2; int rr = 0, gg = 0, bb = 0, aa = 0; avgz = 999999.0f; q = x + y * LWcam.xres; for( xx = 0; xx < 1; // hack - this is wrong:Gmotion_samp; xx++ ) { int rr1, gg1, bb1, aa1; add2 = q + ( LWcam.xres * LWcam.yres * xx ); add = q * 4 + ( LWcam.xres * LWcam.yres * xx * 4 ); rr1 = ( int ) ( LWcam.ibuff[add] ); gg1 = ( int ) ( LWcam.ibuff[add + 1] ); bb1 = ( int ) ( LWcam.ibuff[add + 2] ); aa1 = ( int ) ( LWcam.ibuff[add + 3] ); if( rr1 > 255 ) rr1 = 255; if( gg1 > 255 ) gg1 = 255; if( bb1 > 255 ) bb1 = 255; if( aa1 > 255 ) aa1 = 255; rr += rr1; gg += gg1; bb += bb1; aa += aa1; if( LWcam.zbuff[add2] < 999998.0f ) { VERT2 con; VERT wpt; con.x = ( float ) x; con.y = ( float ) y; con.z = ( float ) LWcam.zbuff[add2]; con = cam2world( &LWcam, con ); wpt.x = con.x; wpt.y = con.y; wpt.z = con.z; avgz = Distance( wpt, LWcam.wpos ); if( avgz < zbuff[q] ) zbuff[q] = avgz; } } rr = ( int ) ( ( float ) rr / ( float ) Gmotion_samp ); gg = ( int ) ( ( float ) gg / ( float ) Gmotion_samp ); bb = ( int ) ( ( float ) bb / ( float ) Gmotion_samp ); aa = ( int ) ( ( float ) aa / ( float ) Gmotion_samp ); add = q * 4; acimage[add] += ( int ) rr; acimage[add + 1] += ( int ) gg; acimage[add + 2] += ( int ) bb; acimage[add + 3] += ( int ) aa; } } if( Glow_mem == 0 ) for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) { int add, add2; float az; int rr = 0, gg = 0, bb = 0, aa = 0; { int rr1, gg1, bb1, aa1; add = x * 4; add2 = x; rr1 = ( int ) ( acimage[add] ); gg1 = ( int ) ( acimage[add + 1] ); bb1 = ( int ) ( acimage[add + 2] ); aa1 = ( int ) ( acimage[add + 3] ); az = zbuff[add2]; rr = rr1; gg = gg1; bb = bb1; aa = aa1; } rr = ( int ) ( ( float ) rr / ( float ) MAXPASSES ); gg = ( int ) ( ( float ) gg / ( float ) MAXPASSES ); bb = ( int ) ( ( float ) bb / ( float ) MAXPASSES ); aa = ( int ) ( ( float ) aa / ( float ) MAXPASSES ); if( rr > 255 ) rr = 255; if( gg > 255 ) gg = 255; if( bb > 255 ) bb = 255; if( aa > 255 ) aa = 255; add = x * 4; acimage2[add] += ( int ) rr; acimage2[add + 1] += ( int ) gg; acimage2[add + 2] += ( int ) bb; acimage2[add + 3] += ( int ) aa; } } // mbsamples if( Glow_mem == 0 ) for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) { int add; int rr = 0, gg = 0, bb = 0, aa = 0; { int rr1, gg1, bb1, aa1; add = x * 4; rr1 = ( int ) ( acimage2[add] ); gg1 = ( int ) ( acimage2[add + 1] ); bb1 = ( int ) ( acimage2[add + 2] ); aa1 = ( int ) ( acimage2[add + 3] ); rr = rr1; gg = gg1; bb = bb1; aa = aa1; } rr = ( int ) ( ( float ) rr / ( float ) 1 ); gg = ( int ) ( ( float ) gg / ( float ) 1 ); bb = ( int ) ( ( float ) bb / ( float ) 1 ); aa = ( int ) ( ( float ) aa / ( float ) 1 ); if( rr > 255 ) rr = 255; if( gg > 255 ) gg = 255; if( bb > 255 ) bb = 255; if( aa > 255 ) aa = 255; add = x * 4; image[add] = ( unsigned char ) rr; image[add + 1] = ( unsigned char ) gg; image[add + 2] = ( unsigned char ) bb; image[add + 3] = ( unsigned char ) aa; } } Nfree( acimage ); Nfree( acimage2 ); free_geomWF( &geom ); return ( Glow_mem ); } static void mkDEPTHbuffers( LIGHTINFO * cam ) { int x; int es; es = Gmotion_samp; cam->zbuff = NULL; if( Glow_mem == 0 ) if( ( cam->xres > 0 ) && ( cam->yres > 0 ) ) cam->zbuff = ( float * ) malloc( sizeof( float ) * ( cam->xres ) * ( cam->yres + 6 ) * es ); cam->ibound = 0; if( cam->zbuff ) cam->zbound = ( ( cam->xres ) * ( cam->yres - 1 ) * es ); if( cam->zbuff == NULL ) { Glow_mem = 1; if( GLOBAL_VERBOSE ) printf( "*** ERROR *** Out of memory (allocating depth buffer\n" ); free( cam->zbuff ); cam->zbuff = NULL; cam->xres = 0; cam->yres = 0; cam->ibound = 0; cam->gbound = 0; cam->zbound = 0; } // cam->geombuff=(float *) malloc (sizeof(float)*(cam->xres+1)*(cam->yres+2)*es); // for (x=0;x< cam->xres*cam->yres*oversamp*es; x++) cam->zbuff[x]=100000000000.0f; if( Glow_mem == 0 ) for( x = 0; x < ( int ) cam->zbound; x++ ) cam->zbuff[x] = 1000000.0f; // for (x=0;x< cam->xres*cam->yres*es; x++) cam->geombuff[x]=1000000.0f; #ifndef RENDERLW // cam->Gzbuff=(float *) malloc (sizeof(float)*(cam->xres+1)*(cam->yres+2)*oversamp*es); // for (x=0;x< cam->xres*cam->yres*oversamp*es; x++) cam->Gzbuff[x]=100000000000.0f; #endif } static void mkDEPTHbuffer( LIGHTINFO * cam ) { int x; int sx, sy; // binary cast shadows for now // cam->zbuff = NULL; // cam->geombuff = NULL; if (cam->zbuff) free(cam->zbuff); if (cam->geombuff) free(cam->geombuff); // printinf the vars .. cam->ibound = 0; cam->gbound = 0; cam->zbound = 0; if( GLOBAL_VERBOSE ) printf( "allocating lights\n MAXPASSES = %d Gmotion_samp = %d xres %d yres %d \n", MAXPASSES, GextrasampLIGHT, cam->xres, cam->yres ); if( cam->xres > 0 ) if( Glow_mem == 0 ) { if( cam->xres > 0 ) cam->zbuff = ( float * ) malloc( sizeof( float ) * ( cam->xres ) * ( cam->yres + 6 ) * ( GextrasampLIGHT ) * ( MAXPASSES ) ); cam->ibound = 0; cam->zbound = ( cam->xres ) * ( cam->yres ) * GextrasampLIGHT * ( MAXPASSES ); if( cam->xres > 0 ) if( cam->zbuff == NULL ) Glow_mem = 1; } if( cam->xres > 0 ) if( cam->xres + cam->yres > 0 ) if( Glow_mem == 0 ) { cam->geombuff = ( float * ) malloc( sizeof( float ) * ( cam->xres ) * ( cam->yres + 6 ) * ( GextrasampLIGHT ) ); cam->gbound = ( ( cam->xres ) * ( cam->yres ) * ( GextrasampLIGHT ) ); if( cam->geombuff == NULL ) Glow_mem = 1; } if( cam->xres + cam->yres > 0 ) if( ( cam->geombuff == NULL ) || ( Glow_mem == 1 ) ) { Glow_mem = 1; if( GLOBAL_VERBOSE ) printf( "**** ERROR **** out of memory (allocating camera depth buffers)\n" ); Nfree( cam->zbuff ); Nfree( cam->geombuff ); cam->xres = 0; cam->yres = 0; cam->ibound = 0; cam->gbound = 0; cam->zbound = 0; } if( cam->xres > 0 ) if( Glow_mem == 0 ) { for( x = 0; x < ( int ) cam->gbound; x++ ) cam->geombuff[x] = ( float ) 10000000.0f; for( x = 0; x < ( int ) cam->zbound; x++ ) cam->zbuff[x] = ( float ) 10000000.0f; #ifndef RENDERLW // cam->Gzbuff=(float *) malloc (sizeof(float)*(cam->xres+1)*(cam->yres+2)); // for (x=0;x< cam->xres*cam->yres; x++) cam->Gzbuff[x]=(float)10000000.0f; #endif } } static void init_buffers( void ) { int n; //printf ("initializing buffers\n"); //fflush(stdout); for( n = 0; n < 255; n++ ) { LWlight[n].ibuff = NULL; LWlight[n].zbuff = NULL; LWlight[n].geombuff = NULL; } LWcam.zbuff = NULL; LWcam.ibuff = NULL; LWcam.geombuff = NULL; } static void destroy_buffers( void ) { int n; //printf ("destroying buffers\n"); //fflush(stdout); free_maps( ); for( n = 0; n < 255; n++ ) { // if( LWlight[n].zbuff != NULL ) // if (LWlight[n].xres>0) { if( LWlight[n].zbuff != NULL ) free( LWlight[n].zbuff ); if( LWlight[n].geombuff != NULL ) free( LWlight[n].geombuff ); if( LWlight[n].Gzbuff != NULL ) free( LWlight[n].Gzbuff ); // Nfree(LWlight[n].lumbuff); // Nfree(LWlight[n].ibuff); #ifndef RENDERLW // Nfree(LWlight[n].Gzbuff); // Nfree(LWlight[n].ibuff); // Nfree(LWlight[n].lumbuff); #endif } LWlight[n].zbuff = NULL; LWlight[n].Gzbuff = NULL; LWlight[n].geombuff = NULL; } // if (LWcam.xres>0); { if( LWcam.zbuff != NULL ); free( LWcam.zbuff ); LWcam.zbuff = NULL; if( LWcam.geombuff != NULL ); free( LWcam.geombuff ); LWcam.geombuff = NULL; if( LWcam.ibuff != NULL ); free( LWcam.ibuff ); LWcam.ibuff = NULL; if( LWcam.lumbuff != NULL ); free( LWcam.lumbuff ); LWcam.lumbuff = NULL; } LWcam.xres = 0; free_tiles(); } #ifdef RENDERLW static void mkcamray( int x, int y, LWDVector * pos, LWDVector * n ) { LWDVector rt, up, fd, p; float pixelAspect, zoom, s, d; float xx, yy; LWItemID camera; int i; xx = ( ( float ) x + ( -LWcam.sx ) ) + 2.0f; //+.5; yy = ( ( float ) y + ( -LWcam.sy ) ) + 1.0f; //xx=(float)x; //yy=(float)y; camera = LWcam.id; /* convert from pixel to camera coordinates */ //add=(int)x+((int)y)*LWcam.xres; zoom = lc->zoomFactor( LWcam.id, gt ); iid->param( camera, LWIP_W_POSITION, gt, *pos ); iid->param( camera, LWIP_RIGHT, gt, rt ); iid->param( camera, LWIP_UP, gt, up ); iid->param( camera, LWIP_FORWARD, gt, fd ); s = LWcam.yres * 0.5; p[0] = LWcam.aspect * ( xx - LWcam.xres * 0.5f ) / s; p[1] = 1.0 - yy / s; p[2] = zoom; /* convert to world direction vector */ for( i = 0; i < 3; i++ ) *n[i] = ( p[0] * rt[i] + p[1] * up[i] + p[2] * fd[i] ); /* normalize */ d = ( float ) fsqrt( *n[0] * *n[0] + *n[1] * *n[1] + *n[2] * *n[2] ); if( d != 0.0f ) { *n[0] /= d; *n[1] /= d; *n[2] /= d; } /* cast the ray */ // d = (float)Gsa->rayCast( pos, n ); } #endif static void calcZbuffer( LIGHTINFO * cam ) { #ifdef RENDERLW float xx, yy; int add; // LWItemInfo *iteminfo; // LWSceneInfo *sceneinfo; // LWCameraInfo *caminfo; LWItemID camera; LWDVector pos, rt, up, fd, p, n; float pixelAspect, zoom, s, d; int width, height, i; int x, y; /* initialize in newTime() */ if( GLOBAL_VERBOSE ) printf( "\nmatching LW buffer .. " ); // iteminfo = dat->global( LWITEMINFO_GLOBAL, GFUSE_TRANSIENT ); // sceneinfo = dat->global( LWSCENEINFO_GLOBAL, GFUSE_TRANSIENT ); // caminfo = gf( "LW Cameral Info", GFUSE_TRANSIENT ); camera = LWcam.id; // camera = sceneinfo->renderCamera( t ); // width = sceneinfo->frameWidth; // height = sceneinfo->frameHeight; // pixelAspect = sceneinfo->pixelAspect; zoom = lc->zoomFactor( LWcam.id, gt ); iid->param( camera, LWIP_W_POSITION, gt, pos ); iid->param( camera, LWIP_RIGHT, gt, rt ); iid->param( camera, LWIP_UP, gt, up ); iid->param( camera, LWIP_FORWARD, gt, fd ); /* in evaluate() */ for( y = 1; y < LWcam.yres; y++ ) { for( x = 0; x < LWcam.xres; x++ ) { //xx=(float)x+.25f;//+(LWcam.sx); //yy=(float)(y)+1.0f;//+(LWcam.sy+1.0f); xx = ( float ) x; yy = ( float ) y; /* convert from pixel to camera coordinates */ add = ( int ) ( ( float ) x ) + ( ( int ) ( ( float ) ( y ) ) ) * LWcam.xres; s = LWcam.yres * 0.5; p[0] = LWcam.aspect * ( xx - LWcam.xres * 0.5f ) / s; p[1] = 1.0 - yy / s; p[2] = zoom; /* convert to world direction vector */ for( i = 0; i < 3; i++ ) n[i] = -( p[0] * rt[i] + p[1] * up[i] + p[2] * fd[i] ); /* normalize */ d = ( float ) -fsqrt( n[0] * n[0] + n[1] * n[1] + n[2] * n[2] ); if( d != 0.0f ) { n[0] /= d; n[1] /= d; n[2] /= d; } /* cast the ray */ d = ( float ) Gsa->rayCast( pos, n ); if( ( add >= 0 ) && ( add < LWcam.xres * ( LWcam.yres - 1 ) ) ) { if( d < 0 ) LWcam.geombuff[add] = 1000000.0f; else { float pd; float dd; float cz; pd = ( float ) fsqrt( p[0] * p[0] + p[1] * p[1] + p[2] * p[2] ); if( pd != 0.0f ) dd = ( float ) ( d * zoom / pd ); else dd = 1000000.0f; if( dd != 1000000.0f ) { // this is normally the transformation I put the LWDEPTH through // to get cam depth which will match the cam matricies I construct cz = ( float ) dd - zoom; cz = cz / ( 1.0 + cz / zoom ); } else cz = -dd; LWcam.geombuff[add] = cz; } } } } //printf ("done\n"); #endif } static void mkIMAGEbuffer( LIGHTINFO * cam ) { int x; int es; //getMAXPASSES(); //oversamp=MAXPASSES; es = Gmotion_samp; cam->ibuff = NULL; cam->lumbuff = NULL; cam->geombuff = NULL; if( cam->xres > 0 ) if( Glow_mem == 0 ) { cam->ibuff = ( unsigned char * ) malloc( 4 * es * sizeof( unsigned char ) * cam->xres * ( cam->yres + 2 ) ); if( cam->ibuff == NULL ) Glow_mem = 1; if( Glow_mem == 0 ) cam->geombuff = ( float * ) malloc( es * sizeof( float ) * cam->xres * ( cam->yres + 2 ) ); if( cam->geombuff == NULL ) Glow_mem = 1; if( Glow_mem == 0 ) { cam->ibound = 4 * es * cam->xres * ( cam->yres ); cam->zbound = es * cam->xres * ( cam->yres ); cam->gbound = es * cam->xres * ( cam->yres ); } } if( Glow_mem == 1 ) if( cam->xres > 0 ) // if( cam->geombuff == NULL ) { Glow_mem = 1; if( GLOBAL_VERBOSE ) printf( "*** ERROR *** out of memory (allocating image buffers)\n" ); cam->xres = 0; cam->yres = 0; free( cam->ibuff ); free( cam->geombuff ); cam->ibuff = NULL; cam->lumbuff = NULL; cam->geombuff = NULL; } if( cam->xres > 0 ) if( Glow_mem == 0 ) { for( x = 0; x < ( int ) cam->gbound; x++ ) cam->geombuff[x] = -1000000.0f; for( x = 0; x < ( int ) cam->ibound; x++ ) cam->ibuff[x] = 0; } } // softimage stuff // return is 1 if there is a guide on this vert; int SOFTfetch_guide( int vertnoo, SOFTGUIDE * guide ) { int ret = -1; // if (vertno>=Dtotalverts) ret= 0; if( vertnoo < 0 ) ret = -1; if( total_splines ) if( vertnoo >= total_splines ) ret = -1; if( total_splines == 0 ) if( vertnoo >= totalguides ) ret = -1; if( total_splines ) if( vertnoo >= 0 ) if( vertnoo < total_splines ) { int x; int vertno; { vertno = vertnoo; guide->splitgroup = Shair[vertno].splitgroup; guide->merge = Shair[vertno].splitmerge; guide->hidden = Shair[vertno].hide; for( x = 0; x < 15; x++ ) { // guide->guide[x]=hair[Dlink[vertno]].hv[x]; // guide->select[x]=hair[Dlink[vertno]].select[x]; guide->select[x] = ( int ) Shair[vertno].select[x]; if( Shair[vertno].pfID[x] >= 0 ) guide->lock[x] = 1; else guide->lock[x] = 0; // guide->lock[x] = Shair[vertno].pfID[x]; //guide->lock[x]=1; // else guide->lock[x]=0; guide->zerosize = 0; // if( Shair[vertno].restlength > 0 ) { guide->guide[x] = Shair[vertno].hv[x]; guide->guide[x].z *= -1.0f; // flip guide->velocity[x] = Shair[vertno].velocity[x]; guide->velocity[x].z *= -1.0f; guide->weight[x] = Shair[vertno].w[x]; } // else if( Shair[vertno].restlength < 0.0001f ) { guide->guide[x] = Shair[vertno].hv[0]; guide->velocity[x] = Shair[vertno].velocity[0]; guide->weight[x] = 0.0f; guide->zerosize = 1; } } guide->norm = Shair[vertno].norm; guide->norm.z *= -1.0f; guide->vid = vertno; ret = 1; // if (guide->zerosize==1) ret= -1; } } if( total_splines == 0 ) if( vertnoo >= 0 ) if( vertnoo < totalguides ) // if (Dtag[vertno]) // if (hair[Dlink[vertno]].restlength>0) { int x; int vertno; if( vertnoo < Dtotalverts ) { vertno = guide2vert[vertnoo]; guide->hidden = hair[vertno].hide; guide->splitgroup = hair[vertno].splitgroup; guide->merge = hair[vertno].splitmerge; for( x = 0; x < 15; x++ ) { // guide->guide[x]=hair[Dlink[vertno]].hv[x]; // guide->select[x]=hair[Dlink[vertno]].select[x]; guide->select[x] = ( int ) hair[vertno].select[x]; // guide->lock[x] = hair[vertno].pfID[x]; if( hair[vertno].pfID[x] >= 0 ) guide->lock[x] = 1; else guide->lock[x] = 0; //guide->lock[x]=1; // else guide->lock[x]=0; guide->zerosize = 0; // if( hair[vertno].restlength > 0 ) { guide->weight[x] = hair[vertno].w[x]; guide->guide[x] = hair[vertno].hv[x]; guide->guide[x].z *= -1.0f; // flip guide->velocity[x] = hair[vertno].velocity[x]; guide->velocity[x].z *= -1.0f; } if( hair[vertno].restlength < 0.0001f ) // else { guide->guide[x] = hair[vertno].hv[0]; guide->velocity[x] = hair[vertno].velocity[0]; guide->zerosize = 1; guide->guide[x].z *= -1.0f; // flip guide->velocity[x] = hair[vertno].velocity[x]; guide->velocity[x].z *= -1.0f; } } guide->norm = vn[vertno]; guide->norm.z *= -1.0f; guide->vid = vlink[vertno]; ret = 1; // if (guide->zerosize==1) ret= -1; } } return ( ret ); } int SOFTfetch_guideNOISESPACE( int vertnoo, SOFTGUIDE * guide ) { int ret = -1; // if (vertno>=Dtotalverts) ret= -1; if( vertnoo < 0 ) ret = -1; if( total_splines == 0 ) if( vertnoo > totalguides - 1 ) ret = -1; if( total_splines > 0 ) if( vertnoo > total_splines - 1 ) ret = -1; if( total_splines == 0 ) if( vertnoo >= 0 ) if( vertnoo < totalguides ) // if (Dtag[vertno]) // if (hair[Dlink[vertno]].restlength>0) { int x; int vertno; if( vertnoo < Dtotalverts ) { vertno = guide2vert[vertnoo]; guide->splitgroup = hair[vertno].splitgroup; guide->merge = hair[vertno].splitmerge; for( x = 0; x < 15; x++ ) { // guide->guide[x]=hair[Dlink[vertno]].hv[x]; // guide->select[x]=hair[Dlink[vertno]].select[x]; guide->select[x] = ( int ) hair[vertno].select[x]; if( hair[vertno].pfID[x] >= 0 ) guide->lock[x] = 1; else guide->lock[x] = 0; //guide->lock[x]=1; // else guide->lock[x]=0; guide->zerosize = 0; // if( hair[vertno].restlength > 0 ) { guide->guide[x] = hair[vertno].noisev[x]; guide->guide[x].z *= -1.0f; guide->velocity[x] = hair[vertno].velocity[x]; guide->velocity[x].z *= -1.0f; } if( hair[vertno].restlength < 0.0001f ) { guide->guide[x] = hair[vertno].noisev[0]; guide->guide[x].z *= -1.0f; guide->velocity[x] = hair[vertno].velocity[0]; guide->velocity[x].z *= -1.0f; guide->zerosize = 1; } } guide->norm = vn[vertno]; guide->norm.z *= -1.0f; guide->vid = vlink[vertno]; ret = 1; } } if( total_splines > 0 ) if( vertnoo >= 0 ) if( vertnoo < total_splines ) { int x; int vertno; { vertno = vertnoo; guide->splitgroup = Shair[vertno].splitgroup; guide->merge = Shair[vertno].splitmerge; guide->hidden = Shair[vertno].hide; for( x = 0; x < 15; x++ ) { // guide->guide[x]=hair[Dlink[vertno]].hv[x]; // guide->select[x]=hair[Dlink[vertno]].select[x]; guide->select[x] = ( int ) Shair[vertno].select[x]; if( Shair[vertno].pfID[x] >= 0 ) guide->lock[x] = 1; else guide->lock[x] = 0; //guide->lock[x]=1; // else guide->lock[x]=0; guide->zerosize = 0; if( Shair[vertno].restlength > 0 ) { guide->guide[x] = Shair[vertno].noisev[x]; guide->guide[x].z *= -1.0f; guide->velocity[x] = Shair[vertno].velocity[x]; guide->velocity[x].z *= -1.0f; } else { guide->guide[x] = Shair[vertno].noisev[0]; guide->guide[x].z *= -1.0f; guide->velocity[x] = Shair[vertno].velocity[0]; guide->velocity[x].z *= -1.0f; guide->zerosize = 1; } } guide->norm = Shair[vertno].norm; guide->norm.z *= -1.0f; guide->vid = vertno; ret = 1; } } return ( ret ); } FILE *dppg = NULL; //#ifdef EXTERNAL_COLLISION void SOFTput_guide( int vertnoo, SOFTGUIDE * guide ) // this function will force an eval as well // to re-validate lengths. { int x, y; int vertno; float w = 0; float sl = 0; selmode = VERTS; // if (vertno= 0 ) // if (Dtag[vertno]) { int x; vertno = guide2vert[vertnoo]; for( x = 0; x < 15; x++ ) w += hair[vertno].w[x]; for( x = 0; x < 15; x++ ) sl += hair[vertno].select[x]; hair[vertno].hide = guide->hidden; for( x = 0; x < 15; x++ ) { // hair[Dlink[vertno]].hv[x]=guide->guide[x]; // hair[Dlink[vertno]].select[x]=guide->select[x]; // resthair[Dlink[vertno]].hv[x]=guide->guide[x]; // resthair[Dlink[vertno]].select[x]=guide->select[x]; // hair[vertno].noisev[x]=resthair[vertno].noisev[x]; guide->guide[x].z *= -1.0f; if( x > 0 ) if( hair[vertno].pfID[x] == -1 ) hair[vertno].hv[x] = guide->guide[x]; hair[vertno].select[x] = guide->select[x]; if( x > 0 ) if( hair[vertno].pfID[x] == -1 ) hair[vertno].resthv[x] = guide->guide[x]; hair[vertno].w[x] = guide->weight[x]; // resthair[vertno].select[x]=guide->select[x]; } hair[vertno].select[0] = guide->select[0]; //resthair[vertno].select[0]=guide->select[0]; // checkwmaps(); // recalc_hair(Dlink[vertno]); // recalc_hair(vertno); // hair[vertno].select[0]=1; // resthair[vertno].select[0]=1; Gcollision_hit = 0; if( ( sl > 0 ) ) recalc_hair( vertno ); // hey halfy, this is where we recalculate the hair if there's a collision // recalc_hair( vertno ); // gottabe // if (Gcollision_hit) // { // Gcollision_hit=0; // recalc_hair( vertno ); // gottabe // } // if (Gcollision_hit) // { // Gcollision_hit=0; // recalc_hair( vertno ); // gottabe // } Gcollision_hit = 0; // // recalc_hair(vertno); for( x = 0; x < 15; x++ ) hair[vertno].resthv[x] = hair[vertno].hv[x]; } if( total_splines != 0 ) if( vertnoo < total_splines ) if( vertnoo >= 0 ) // if (Dtag[vertno]) { int x; vertno = vertnoo; // vertno = guide2vert[vertnoo]; Shair[vertno].hide = guide->hidden; //printf ("vn %d vno %d ",vertnoo,vertno); for( x = 0; x < 15; x++ ) { // if( Shair[vertno].pfID[x] == -1 ) { // hair[Dlink[vertno]].hv[x]=guide->guide[x]; // hair[Dlink[vertno]].select[x]=guide->select[x]; // resthair[Dlink[vertno]].hv[x]=guide->guide[x]; // resthair[Dlink[vertno]].select[x]=guide->select[x]; // hair[vertno].noisev[x]=resthair[vertno].noisev[x]; guide->lock[x] = 0; guide->guide[x].z *= -1.0f; if( x > 0 ) { Shair[vertno].hv[x] = guide->guide[x]; Shair[vertno].resthv[x] = guide->guide[x]; } Shair[vertno].select[x] = guide->select[x]; Shair[vertno].w[x] = guide->weight[x]; Sresthair[vertno].w[x] = guide->weight[x]; //printf (" %f\n",Shair[vertno].w[x]);fflush(stdout); // resthair[vertno].select[x]=guide->select[x]; } } Shair[vertno].select[0] = guide->select[0]; //resthair[vertno].select[0]=guide->select[0]; // checkwmaps(); // recalc_hair(Dlink[vertno]); // recalc_hair(vertno); // hair[vertno].select[0]=1; // resthair[vertno].select[0]=1; Gcollision_hit = 0; Srecalc_hair( vertno ); // hey halfy, this is where we recalculate the hair if there's a collision // recalc_hair( vertno ); // gottabe // if (Gcollision_hit) // { // Gcollision_hit=0; // recalc_hair( vertno ); // gottabe // } // if (Gcollision_hit) // { // Gcollision_hit=0; // recalc_hair( vertno ); // gottabe // } Gcollision_hit = 0; // // recalc_hair(vertno); for( x = 0; x < 15; x++ ) { Sresthair[vertno].hv[x] = Shair[vertno].hv[x]; } } //for (x=0;x 0 ) if( hair[vertno].hide == 1 ) for( y = 0; y < 15; y++ ) { hair[vertno].select[y] = 0; } //for (x=0;x 0 ) if( Shair[vertnoo].hide == 1 ) for( y = 0; y < 15; y++ ) { Shair[vertnoo].select[y] = 0; } } //#ifdef EXTERNAL_COLLISION void SOFTput_guideNOCALC( int vertnoo, SOFTGUIDE * guide ) // this function NOT will force an eval { int x, y; int vertno; selmode = VERTS; // if (vertno= 0 ) // if (Dtag[vertno]) { int x; vertno = guide2vert[vertnoo]; hair[vertno].hide = guide->hidden; for( x = 0; x < 15; x++ ) // if( hair[vertno].pfID[x] == -1 ) { // hair[Dlink[vertno]].hv[x]=guide->guide[x]; // hair[Dlink[vertno]].select[x]=guide->select[x]; // resthair[Dlink[vertno]].hv[x]=guide->guide[x]; // resthair[Dlink[vertno]].select[x]=guide->select[x]; // hair[vertno].noisev[x]=hair[vertno].noisev[x]; if( x > 0 ) if( hair[vertno].pfID[x] == -1 ) { hair[vertno].hv[x] = guide->guide[x]; hair[vertno].hv[x].z *= -1.0f; } hair[vertno].select[x] = guide->select[x]; if( x > 0 ) if( hair[vertno].pfID[x] == -1 ) { hair[vertno].resthv[x] = guide->guide[x]; hair[vertno].resthv[x].z *= -1.0f; } hair[vertno].w[x] = guide->weight[x]; // resthair[vertno].select[x]=guide->select[x]; } hair[vertno].select[0] = guide->select[0]; //resthair[vertno].select[0]=guide->select[0]; // checkwmaps(); // recalc_hair(Dlink[vertno]); // recalc_hair(vertno); // recalc_hair(vertno); // recalc_hair(vertno); for( x = 0; x < 15; x++ ) hair[vertno].resthv[x] = hair[vertno].hv[x]; } if( total_splines != 0 ) if( vertnoo < total_splines ) if( vertnoo >= 0 ) // if (Dtag[vertno]) { int x; vertno = vertnoo; // vertno = guide2vert[vertnoo]; //printf ("NOCALC vn %d vno %d \n",vertnoo,vertno); Shair[vertno].hide = guide->hidden; for( x = 1; x < 15; x++ ) { // if( Shair[vertno].pfID[x] == -1 ) { // hair[Dlink[vertno]].hv[x]=guide->guide[x]; // hair[Dlink[vertno]].select[x]=guide->select[x]; // resthair[Dlink[vertno]].hv[x]=guide->guide[x]; // resthair[Dlink[vertno]].select[x]=guide->select[x]; // hair[vertno].noisev[x]=hair[vertno].noisev[x]; Shair[vertno].hv[x] = guide->guide[x]; Shair[vertno].hv[x].z *= -1.0f; Shair[vertno].select[x] = guide->select[x]; Sresthair[vertno].select[x] = guide->select[x]; Shair[vertno].resthv[x] = guide->guide[x]; Shair[vertno].resthv[x].z *= -1.0f; Shair[vertno].w[x] = guide->weight[x]; Sresthair[vertno].w[x] = guide->weight[x]; Sthishair[vertno].w[x] = guide->weight[x]; //printf ("NOCALC %f\n",Shair[vertno].w[x]);fflush(stdout); // resthair[vertno].select[x]=guide->select[x]; } // else { printf ("NOCALC pfID!= -1 !! %d %d %d\n",Shair[vertno].pfID[x],vertno,x);} } Shair[vertno].select[0] = guide->select[0]; //resthair[vertno].select[0]=guide->select[0]; // checkwmaps(); // recalc_hair(Dlink[vertno]); // recalc_hair(vertno); // recalc_hair(vertno); // recalc_hair(vertno); for( x = 0; x < 15; x++ ) Sresthair[vertno].hv[x] = Shair[vertno].hv[x]; } //for (x=0;x 0 ) if( hair[vertno].hide == 1 ) for( y = 0; y < 15; y++ ) { hair[vertno].select[y] = 0; } if( total_splines > 0 ) if( Shair[vertno].hide == 1 ) for( y = 0; y < 15; y++ ) { Shair[vertno].select[y] = 0; } } // obsolete use the NORECALC version void SOFTput_guideSELECTONLY( int vertnoo, SOFTGUIDE * guide ) // this function will force an eval as well // to re-validate lengths. { int x, y; int vertno; if( vertnoo < totalguides ) if( vertnoo >= 0 ) vertno = guide2vert[vertnoo]; if( total_splines > 0 ) if( vertnoo < total_splines ) if( vertnoo >= 0 ) vertno = guide2vert[vertnoo]; if( vertnoo < totalguides ) if( vertnoo >= 0 ) // if (vertnohidden; for( x = 0; x < 15; x++ ) { // hair[Dlink[vertno]].hv[x]=guide->guide[x]; // hair[Dlink[vertno]].select[x]=guide->select[x]; // resthair[Dlink[vertno]].hv[x]=guide->guide[x]; // resthair[Dlink[vertno]].select[x]=guide->select[x]; // hair[vertno].hv[x]=guide->guide[x]; hair[vertno].select[x] = guide->select[x]; // resthair[vertno].hv[x]=guide->guide[x]; // resthair[vertno].select[x]=guide->select[x]; } // for (x=0;x<30;x++) // { // hair[Dlink[vertno]].slider[x]=guide->parms[x]; // hair[vertno].slider[x]=guide->parms[x]; // } // checkwmaps(); // recalc_hair(Dlink[vertno]); // recalc_hair(vertno); //for (x=0;x<15;x++) //resthair[vertno].hv[x]=hair[vertno].hv[x]; } //for (x=0;x 0 ) if( hair[vertno].hide == 1 ) for( y = 0; y < 15; y++ ) { hair[vertno].select[y] = 0; } //for (x=0;x 0 ) if( Shair[vertno].hide == 1 ) for( y = 0; y < 15; y++ ) { Shair[vertno].select[y] = 0; } if( vertnoo < total_splines ) if( vertnoo >= 0 ) if( total_splines > 0 ) for( x = 0; x < 15; x++ ) Shair[vertno].select[x] = guide->select[x]; } void SOFTcomb_select( VERT direction ) { direction.z *= -1; comb_select( direction ); } void SOFTset_vert_parm( int vertno, int chan, float value ) // this function will force an eval as well // to re-validate lengths. { if( total_splines == 0 ) if( vertno < Dtotalverts ) if( Dtag[vertno] ) { // int x; { hair[Dlink[vertno]].slider[chan] = value; // hair[Dlink[vertno]].slider[chan]=value; //// if (value!=1.0) //// for (t=0;t<6;t++) sliders[t][chan].paint=1; } // checkwmaps(); } } float SOFTget_vert_parm( int vertno, int chan ) // this function will force an eval as well // to re-validate lengths. { float value = -1; if( total_splines == 0 ) if( vertno >= 0 ) if( vertno < Dtotalverts ) if( Dtag[vertno] ) { // int x; { value = hair[Dlink[vertno]].slider[chan]; } // checkwmaps(); } return ( value ); } void SOFTscale_select( float factor ) { int x, y; reset_rest( ); if( total_splines == 0 ) for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] == 1 ) { // if (hair[x].restlength!=0) { for( y = 1; y < 15; y++ ) if( hair[x].pfID[y] == -1 ) { VERT tp; tp.x = hair[x].hv[y].x - hair[x].hv[0].x; tp.y = hair[x].hv[y].y - hair[x].hv[0].y; tp.z = hair[x].hv[y].z - hair[x].hv[0].z; tp.x *= factor; tp.y *= factor; tp.z *= factor; tp.x += hair[x].hv[0].x; tp.y += hair[x].hv[0].y; tp.z += hair[x].hv[0].z; hair[x].hv[y] = tp; hair[x].resthv[y] = tp; } hair[x].restlength *= factor; // resthair[x].restlength*=factor; recalc_hair( x ); } } reset_noisespace( ); collect_guides( ); reset_rest( ); } void SOFTpop_zero( void ) { int x; M_sproing( ); Gbeen_scaled = 1; reset_noisespace( ); reset_rest( ); collect_guides( ); for( x = 0; x < 5; x++ ) if( LOCAL_CNT[x] == 0 ) { LOCAL_PASSES[x] = 1; LOCAL_CNT[x] = 1500; } checkforzero( ); } void SOFTpop_select( float scale ) { MS_sproing( scale ); Gbeen_scaled = 1; reset_noisespace( ); reset_rest( ); collect_guides( ); } void SOFTlock_select( void ) { lock_verts( ); } void SOFTunlock_select( void ) { unlock_verts( ); } void SOFTattenuate_len( void ) { atten_len( ); collect_guides( ); } void SOFTcut_select( void ) { int x; int y; reset_rest( ); if( total_splines == 0 ) for( x = 0; x < totalverts; x++ ) { int smallest = 0; for( y = 15; y > 0; y-- ) { if( hair[x].select[y] == 1 ) smallest = y; } // smallest--; if( ( smallest > 0 ) && ( smallest < 14 ) ) // cut it here { BASEHAIR tp; float uu, tt; tp = hair[x]; for( y = 1; y < 15; y++ ) { VERT v1, v2, v3; float rem; tt = smallest / 15.0f; uu = tt * ( float ) y; v1 = hair[x].hv[( int ) floor( uu )]; v2 = hair[x].hv[( int ) floor( uu + 1 )]; rem = uu - floor( uu ); v3.x = v1.x * ( 1.0f - rem ) + v2.x * rem; v3.y = v1.y * ( 1.0f - rem ) + v2.y * rem; v3.z = v1.z * ( 1.0f - rem ) + v2.z * rem; tp.hv[y] = v3; tp.select[y] = 0; } hair[x] = tp; hair[x].restlength = distance( tp.hv[0], tp.hv[1] ); recalc_hair( x ); } if( ( smallest > 0 ) && ( smallest < 14 ) ) // cut it here hair[x].select[14] = 1; for( y = 0; y < 15; y++ ) hair[x].resthv[y] = hair[x].hv[y]; } reset_rest( ); //for (x=0;x 0 ) { int x; WFTYPE wf; init_geomWF( &wf ); MAYAgetobj( objfilename, &wf ); // get wf set_inst( &wf ); unlink( objfilename ); free_geomWF( &wf ); } // else if( GLOBAL_VERBOSE ) // printf( "no memory for instance\n" ); } } int MAYArender_shadows( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, int deep_shadows ) { int x, y, AA, xx; int pass; int mb; int est = 0; float avgz = 0.0f; int *acimage = NULL; int *acimage2 = NULL; float cx, cy; WFTYPE geom; int mult=0; Gdone = 0; rand48_seed = 0; srand( 0 ); cursamp = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0; calibrateY = 0; Grendermode = 1; for( x = 0; x < totallights; x++ ) if( LWlight[x].trace ) { LWlight[x].xres = 0; LWlight[x].yres = 0; } if( totallights > 0 ) { Gmaps_active = 1; antialiasing = 1; MAXPASSES = 0; if( totalhairfiles != 0 ) { int yy; MAXPASSES = 0; for( xx = 0; xx < totalhairfiles; xx++ ) { fetch_hair( xx, 0.0 ); if( ( freeze.totalverts == 0 ) || ( stack_is_from_archive == 0 ) ) for( yy = 0; yy < 5; yy++ ) { if( total_slgfaces[yy] > 0 ) if( LOCAL_PASSES[yy] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[yy]; } } init_noise( ); init_geomWF( &geom ); Gdeep_shadows = deep_shadows; Glow_mem = 0; global_progress = 0; reset_faces( ); Gclipx0 = 0; Gclipx1 = 80000; Gclipy0 = 0; Gclipy1 = 80000; current_cam = &LWlight[0]; est=0; for( xx = 0; xx < totalhairfiles; xx++ ) //if (stopit!=1) { int qq; fetch_hair( xx, 0 ); if (LOCAL_CNT[0]) { int mult; mult=(int)sliders[25][0].value; if (mult<1) mult=1; est+=LOCAL_CNT[0]*mult*LOCAL_PASSES[0]; } if (LOCAL_CNT[4]) { int mult; mult=(int)sliders[25][4].value; if (mult<1) mult=1; est+=LOCAL_CNT[4]*mult*LOCAL_PASSES[4]; } } for (x=0;xtotalverts; geom.totalfaces = geom_open->totalfaces; geom.totalfverts = geom_open->totalfverts; ambient[0] = 0; ambient[1] = 0; ambient[2] = 0; alloc_geomWF( &geom ); rand48_seed = 0; for( x = 0; x < geom_open->totalfaces; x++ ) { geom.face_start[x] = geom_open->face_start[x]; geom.face_end[x] = geom_open->face_end[x]; } for( x = 0; x < geom_open->totalfverts; x++ ) geom.facelist[x] = geom_open->facelist[x]; for( x = 0; x < geom_open->totalverts; x++ ) { geom.v[x] = geom_open->v[x]; geom.velocity[x].x = ( geom_close->v[x].x - geom_open->v[x].x ); geom.velocity[x].y = ( geom_close->v[x].y - geom_open->v[x].y ); geom.velocity[x].z = ( geom_close->v[x].z - geom_open->v[x].z ); } // if (GLOBAL_VERBOSE) //printf ("motion blur sampling = %d\n",MBsampling); if( GLOBAL_VERBOSE ) printf( "over sampling = %d\n", antialiasing ); oversamp = 1; GextrasampLIGHT = 1; if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "making depth buffers (lights)\n" ); //fflush(stdout); if( Glow_mem == 0 ) for( x = 0; x < totallights; x++ ) if( LWlight[x].xres > 0 ) mkDEPTHbuffer( &LWlight[x] ); //oversamp=antialiasing; if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "estimating passes\n" ); //fflush(stdout); // estimate number of callbacks for progress bar if( Glow_mem == 0 ) for( xx = 0; xx < totalhairfiles; xx++ ) { fetch_hair( xx, 0.0 ); if( ( freeze.totalverts == 0 ) || ( stack_is_from_archive == 0 ) ) { if (mult==0) mult=sliders[25][0].value; if( total_slgfaces[0] ) est += LOCAL_CNT[0]; if (mult==0) mult=sliders[25][1].value; if( total_slgfaces[1] ) est += LOCAL_CNT[1]; if (mult==0) mult=sliders[25][2].value; if( total_slgfaces[2] ) est += LOCAL_CNT[2]; if (mult==0) mult=sliders[25][3].value; if (mult==0) if( total_slgfaces[3] ) est += LOCAL_CNT[3]; if (mult==0) mult=sliders[25][4].value; if( total_splines ) est += LOCAL_CNT[4]; } } //est+=(est*totallights); ///est*=MBsampling; est *= ( MAXPASSES ); if (mult==0) mult=1; avgz = 1000000.0f; //est/=100; estimated_total = est / (2000/mult); global_progress = 0; #ifdef progress_update if( SHAVEprogress( global_progress, estimated_total ) == 0 ) global_progress++; #endif if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "rendering light buffers\n" ); //fflush(stdout); if( Glow_mem == 0 ) for( mb = 0; mb < 1; mb++ ) { int doit = 0; int j; float tt; tt = ( ( float ) mb / ( float ) 1 ); for( j = 0; j < totallights; j++ ) doit += LWlight[j].xres; pass=0; if( doit ) // no deep shads for( pass = 0; pass < MAXPASSES; pass++ ) if( Gdone == 0 ) if( ( Gdeep_shadows == 1 ) || ( ( Gdeep_shadows == 0 ) && ( pass == 0 ) ) ) { int yy; if( GLOBAL_VERBOSE ) printf( "pass %d\n", pass ); if( Gdeep_shadows == 1 ) for( yy = 0; yy < totallights; yy++ ) if( LWlight[yy].xres > 0 ) for( x = 0; x < LWlight[yy].xres * LWlight[yy].yres * GextrasampLIGHT; x++ ) if( x < ( int ) LWlight[yy].zbound ) LWlight[yy].zbuff[x] = 1000000.0f; if( Gdeep_shadows == 0 ) for( yy = 0; yy < totallights; yy++ ) if( LWlight[yy].xres > 0 ) for( x = 0; x < LWlight[yy].xres * LWlight[yy].yres; x++ ) if( x < ( int ) LWlight[yy].zbound ) LWlight[yy].zbuff[x] = 1000000.0f; TILEMODE = 0; itsalight = 2; //printf("drawing geom\n"); //#ifndef MAX3D // we only do native lighting in max for( x = 0; x < totallights; x++ ) if( LWlight[x].xres > 0 ) { int qq; current_cam = &LWlight[x]; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWlight[x].xres - 1; Gclipy1 = LWlight[x].yres - 1; TILEMODE = 0; for( qq = 0; qq < geom.totalverts; qq++ ) // phase shadow occlusions { geom.v[qq].x += geom.velocity[qq].x * 0.5f; geom.v[qq].y += geom.velocity[qq].y * 0.5f; geom.v[qq].z += geom.velocity[qq].z * 0.5f; } draw_geomWF( &geom, 0 ); for( qq = 0; qq < geom.totalverts; qq++ ) { geom.v[qq].x -= geom.velocity[qq].x * 0.5f; geom.v[qq].y -= geom.velocity[qq].y * 0.5f; geom.v[qq].z -= geom.velocity[qq].z * 0.5f; } } //#endif for( xx = 0; xx < totalhairfiles; xx++ ) if( Gdone == 0 ) { itsalight = 1; TILEMODE = 0; fetch_hair( xx, tt ); itsalight = 1; TILEMODE = 0; current_cam = &LWlight[x]; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWlight[x].xres - 1; Gclipy1 = LWlight[x].yres - 1; //qqqinit_clumping(); if (Gdone==0) if( freeze.totalverts == 0 ) draw_lotsHAIRNEW( pass ); else if( stack_is_from_archive == 0 ) if (Gdone==0) { WFdraw_lotsINST( pass ); } } //push_lightbuffs((pass)+MAXPASSES*mb+1); if( pass < MAXPASSES - 1 ) push_lightbuffs( ( pass ) + 1 ); } } } free_geomWF( &geom ); } } rand48_seed = 0; srand( 0 ); init_noise( ); cursamp = 0; calibrateX = cx; calibrateY = cy; Grendermode = 0; { float maxp = 0; MAXPASSES = 0; 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; } { int yy; //#ifdef crap if( Gdeep_shadows == 0 ) for( yy = 0; yy < totallights; yy++ ) { int empty = 1; if( LWlight[yy].zbuff ) if( LWlight[yy].xres > 0 ) for( x = 0; x < LWlight[yy].xres * LWlight[yy].yres * GextrasampLIGHT; x++ ) if( x < ( int ) LWlight[yy].zbound ) { if( LWlight[yy].zbuff[x] != 1000000.0f ) empty = 0; } if( empty == 1 ) { if( LWlight[yy].zbuff ) free( LWlight[yy].zbuff ); LWlight[yy].zbuff = NULL; if( LWlight[yy].geombuff ) free( LWlight[yy].geombuff ); LWlight[yy].geombuff = NULL; } } if( Gdeep_shadows == 1 ) for( yy = 0; yy < totallights; yy++ ) { int empty = 1; if( LWlight[yy].xres > 0 ) if( LWlight[yy].zbuff != NULL ) for( x = 0; x < LWlight[yy].xres * LWlight[yy].yres * GextrasampLIGHT * MAXPASSES; x++ ) if( x < ( int ) LWlight[yy].zbound ) { if( LWlight[yy].zbuff[x] != 1000000.0f ) empty = 0; } if( empty == 1 ) { if( LWlight[yy].zbuff ) free( LWlight[yy].zbuff ); LWlight[yy].zbuff = NULL; if( LWlight[yy].geombuff ) free( LWlight[yy].geombuff ); LWlight[yy].geombuff = NULL; } } //#endif } if( Glow_mem ) { SHAVEclear_stack( ); // SHAVEcleanup( ); } if( Gdone ) { SHAVEclear_stack( ); // SHAVEcleanup( ); Glow_mem = 1; } return ( Glow_mem ); } int MAYArender_cam( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice ) { int x, y, AA, xx; int pass; int mb; int maxp = 1; int est = 0; float avgz = 0.0f; int *acimage = NULL; int *acimage2 = NULL; WFTYPE geom; rand48_seed = 0; srand( 0 ); Grendermode = 1; if( totalhairfiles != 0 ) { int yy; MAXPASSES = 1; global_progress = 0; LWcam.xres = xres; LWcam.yres = yres; LWCamOPEN.xres = xres; LWCamOPEN.yres = yres; LWCamCLOSE.xres = xres; LWCamCLOSE.yres = yres; if( GactivateGI == 0 ) if( totallights == 0 ) // let's add a default light { Matrix vm; VERT wpos; VERT nnn; VERT vv; float fov; wpos.x = -1000.0f; wpos.y = 1000.0f; wpos.z = -1000.0f; fov = 130.0f; nnn = wpos; nnn.x = -nnn.x; // this is the lookat vector nnn.y = -nnn.y; // we're just lookin at 0,0,0 nnn.z = -nnn.z; nnn = Vnorm( nnn ); vv.x = 0.0f; // up vector (for roll) vv.y = 1.0f; vv.z = 0.0f; SHAVEmake_view_matrix( vm, vv, nnn, wpos, fov ); SHAVEadd_light( 1.0, 1.0, 1.0, vm, wpos, 0, 0, 1.0, 130.0, 1.0, 10, 0, 0, 0, 0, .01 /*nearclip */ ); } for( xx = 0; xx < totalhairfiles; xx++ ) { fetch_hair( xx, 0.0 ); if( ( stack_is_from_archive == 0 ) || ( freeze.totalverts == 0 ) ) for( yy = 0; yy < 5; yy++ ) { if( total_slgfaces[yy] > 0 ) if( LOCAL_PASSES[yy] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[yy]; } } estimated_total = dice * dice; if (0==1) { HAIRTYPE ht; // fprintf (stdout,"testing export\n"); // fflush(stdout); //SHAVEinit_hairtype(&ht); //SHAVEexport_hairtype(&ht ); // fprintf (stdout,"faces = %d\n",ht.totalfaces); // fflush(stdout); //SHAVEfree_hairtype(&ht); // fprintf (stdout,"testing export done\n"); // fflush(stdout); } init_noise( ); init_geomWF( &geom ); if( Glow_mem == 0 ) { if( clipx0 < 0 ) clipx0 = 0; if( clipy0 < 0 ) clipy0 = 0; if( clipx1 > LWcam.xres - 1 ) clipx1 = LWcam.xres - 1; if( clipy1 > LWcam.yres - 1 ) clipy1 = LWcam.yres - 1; Gclipx0 = clipx0; Gclipx1 = clipx1; Gclipy0 = clipy0; Gclipy1 = clipy1; reset_faces( ); if( GLOBAL_VERBOSE ) printf( "interp views\n" ); for( x = 0; x < Gmotion_samp; x++ ) { float ee; ee = ( float ) x / ( float ) Gmotion_samp; LWcamtable[x] = interp_view( LWCamOPEN, LWCamCLOSE, ee ); } if( GLOBAL_VERBOSE ) printf( "clearing output buffers\n" ); for( x = 0; x < LWcam.xres * ( LWcam.yres ) * 4; x++ ) image[x] = 0; for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) zbuff[x] = 1000000.0f; if( Glow_mem == 0 ) { if( Gmotion_samp < 1 ) Gmotion_samp = 1; OPENGL_DRAW = 0; { char tmp[255]; sprintf( tmp, "SHAVE CAM (tiles) render version %s (c) 2019 Epic Games, US Patent 6720962\n", version_info ); if( GLOBAL_VERBOSE ) printf( "%s", tmp ); } if( GLOBAL_VERBOSE ) printf( "----------------------------------------------------\n" ); if( GLOBAL_VERBOSE ) printf( "MAXPASSES = %d\n", MAXPASSES ); if( GLOBAL_VERBOSE ) printf( "allocating geometry\n" ); geom.totalverts = geom_open->totalverts; geom.totalfaces = geom_open->totalfaces; geom.totalfverts = geom_open->totalfverts; ambient[0] = 0; ambient[1] = 0; ambient[2] = 0; alloc_geomWF( &geom ); rand48_seed = 0; for( x = 0; x < geom_open->totalfaces; x++ ) { geom.face_start[x] = geom_open->face_start[x]; geom.face_end[x] = geom_open->face_end[x]; } for( x = 0; x < geom_open->totalfverts; x++ ) geom.facelist[x] = geom_open->facelist[x]; for( x = 0; x < geom_open->totalverts; x++ ) { geom.v[x] = geom_open->v[x]; geom.velocity[x].x = ( geom_close->v[x].x - geom_open->v[x].x ); geom.velocity[x].y = ( geom_close->v[x].y - geom_open->v[x].y ); geom.velocity[x].z = ( geom_close->v[x].z - geom_open->v[x].z ); } if( GLOBAL_VERBOSE ) printf( "time samples = %d\n", Gmotion_samp ); oversamp = 1; if( GLOBAL_VERBOSE ) printf( "memflag = %d\n", Glow_mem ); LWcam = LWCamOPEN; // remember to interpolate this stuff //oversamp=antialiasing; if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "estimating passes\n" ); if( Glow_mem == 0 ) for( xx = 0; xx < totalhairfiles; xx++ ) { fetch_hair( xx, 0.0 ); if( ( stack_is_from_archive == 0 ) || ( freeze.totalverts == 0 ) ) { if( total_slgfaces[0] ) est += LOCAL_CNT[0] * LOCAL_PASSES[0]; if( total_slgfaces[1] ) est += LOCAL_CNT[1] * LOCAL_PASSES[1]; if( total_slgfaces[2] ) est += LOCAL_CNT[2] * LOCAL_PASSES[2]; if( total_slgfaces[3] ) est += LOCAL_CNT[3] * LOCAL_PASSES[3]; if( total_splines ) est += LOCAL_CNT[4] * LOCAL_PASSES[4]; } } est = dice * dice; est *= MAXPASSES; #ifdef progress_update SHAVEprogress( 0, est ); #endif avgz = 1000000.0f; estimated_total = est; if( Glow_mem == 0 ) if( Glow_mem == 0 ) if( GLOBAL_VERBOSE ) printf( "rendering tiles\n" ); if( Glow_mem == 0 ) { float tt; mb=0; tt = ( ( float ) mb / ( float ) 1 ); if( GLOBAL_VERBOSE ) printf( "drawing hair\n" );fflush(stdout); if( Glow_mem == 0 ) { // render here ... if( !GLOBALocclude ) tile_render( &geom, image, zbuff, dice ); if( GLOBALocclude ) { if( GLOBALocclude ) if( GLOBALocclude->totalverts == 0 ) tile_render( &geom, image, zbuff, dice ); if( GLOBALocclude ) if( GLOBALocclude->totalverts > 0 ) tile_render( GLOBALocclude, image, zbuff, dice ); } } } // accumulate } } // printf ("a\n");fflush(stdout); if (acimage) free( acimage ); // printf ("b\n");fflush(stdout); if (acimage2) free( acimage2 ); // printf ("c\n");fflush(stdout); free_geomWF( &geom ); } rand48_seed = 0; srand( 0 ); Grendermode = 0; return ( Glow_mem ); } static int inside_clip( POLYDAT * pp, int xl, int yl, int xs, int ys ); static int inside_clip( POLYDAT * pp, int xl, int yl, int xs, int ys ) { int ret = 0; int x; for( x = 0; x < 3; x++ ) { if( pp->p[x].z >= -0.01 ) ret = 1; if( pp->p[x].z < -0.01 ) if( !( ( pp->p[x].x >= xl ) && ( pp->p[x].x < xs ) && ( pp->p[x].y >= yl ) && ( pp->p[x].y < ys ) ) ) ret = 1; } return ( ret ); } static int draw_poly2new( POLYDAT pp, int layer, unsigned char lum ); static int draw_poly2newZ( POLYDAT pp, int layer, unsigned char lum ); static int draw_poly2( POLYDAT pp, int layer, unsigned char lum ) { int x; int success = 0; float y; int a, b; float y1; int same = 0; float tim = 0.0f; pp.p[3] = pp.p[0]; // wrap pp.c[3] = pp.c[0]; // wrap pp.v[3] = pp.v[0]; // wrap pp.alpha[3] = pp.alpha[0]; // wrap pp.wv[3] = pp.wv[0]; // wrap pp.w[3] = pp.w[0]; // wrap 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( itsalight == 2 ) { int csmp; csmp = cursamp; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( itsalight != 1 ) cursamp = layer; tim = ( float ) layer / ( float ) Gmotion_samp; if( itsalight == 1 ) tim = 0.0f; //+++ if( itsalight != 1 ) //+++ if( !( ( itsalight == 2 ) && ( TILEMODE == 0 ) ) ) for( x = 0; x < 4; x++ ) { //if (cursamp>0) if( itsalight != 1 ) { pp.p[x].x += pp.v[x].x * tim; pp.p[x].y += pp.v[x].y * tim; pp.p[x].z += pp.v[x].z * tim; pp.w[x].x += pp.wv[x].x * tim; pp.w[x].y += pp.wv[x].y * tim; pp.w[x].z += pp.wv[x].z * tim; } //if (cursamp==0) // { // pp.p[x].x+=pp.v[x].x*.55f; // pp.p[x].y+=pp.v[x].y*.55f; // pp.p[x].z+=pp.v[x].z*.55f; // pp.w[x].x+=pp.wv[x].x*.55f; // pp.w[x].y+=pp.wv[x].y*.55f; // pp.w[x].z+=pp.wv[x].z*.55f; // } } // Gclipx0=0;Gclipy0=0; // Gclipx1=current_cam->xres;Gclipy1=current_cam->yres; if( itsalight != 1 ) if( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) { Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; } if( itsalight == 1 ) { Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = current_cam->xres; Gclipy1 = current_cam->yres; } { float xl, yl, xs, ys; //if (0==1) { // yl=Gclipy0-1; ys = Gclipy1 + 1; yl = Gclipy0 - 1; // ys=Gclipy1; xl = Gclipx0 - 1; // wasn't like this before xs = Gclipx1 + 1; if( yl < 0 ) yl = 0; if( xl < 0 ) xl = 0; // xl=Gclipx0-1; // wasn't like this before // xs=Gclipx1+1; // yl+=3;xl+=3; // xl=Gclipx0+4; // xs=Gclipx1-4; } { // flicker .. int xx; int clippit = 0; int reject = 0; int cp = 0; VERT pdir; VERT camdir; VERT eye; camdir.x = current_cam->view[0][2]; camdir.y = current_cam->view[1][2]; camdir.z = current_cam->view[2][2]; camdir.z *= -1.0f; eye = current_cam->wpos; eye.z *= -1.0f; #ifdef trivial_reject for( x = 0; x < 3; x++ ) { int cp = 0; if( pp.p[x].x < xl ) cp = 1; if( pp.p[x].y < yl ) cp = 1; if( pp.p[x].x > xs ) cp = 1; if( pp.p[x].y > ys ) cp = 1; if( cp ) triv++; } #endif //if (GLOBAL_CLIPIT==0) for( x = 0; x < 3; x++ ) { pdir = pp.w[x]; pdir.z *= -1.0f; pdir.x = pdir.x - eye.x; pdir.y = pdir.y - eye.y; pdir.z = pdir.z - eye.z; Vnorm( pdir ); if( VDot( pdir, camdir ) > 0.0f ) cp++; } //GLOBAL_CLIPIT=1; //if (0==1) // if (itsalight==0) if( cp > 0 ) // if( GLOBAL_CLIPIT==0 ) { WFTYPE ret; init_geomWF( &ret ); { camspace_clipitDEANE( pp, &ret, xl, yl, xs, ys, current_cam->zoom ); if( ret.totalverts >= 3 ) for( xx = 1; xx < ret.totalverts - 1; xx++ ) { pp.p[0] = ret.v[0]; pp.c[0] = ret.color[0]; pp.alpha[0] = ret.alpha[0]; pp.v[0] = ret.velocity[0]; pp.p[1] = ret.v[xx]; pp.c[1] = ret.color[xx]; pp.alpha[1] = ret.alpha[xx]; pp.v[1] = ret.velocity[xx]; pp.p[2] = ret.v[xx + 1]; pp.c[2] = ret.color[xx + 1]; pp.alpha[2] = ret.alpha[xx + 1]; pp.v[2] = ret.velocity[xx + 1]; pp.p[3] = ret.v[0]; pp.c[3] = ret.color[0]; pp.v[3] = ret.velocity[0]; pp.alpha[3] = ret.alpha[0]; // eliminate a linear poly // if( !( ( pp.v[0].x == pp.v[1].x ) && ( pp.v[1].x == pp.v[2].x ) ) || ( ( pp.v[0].y == pp.v[1].y ) && ( pp.v[1].y == pp.v[2].y ) ) ) { if( itsalight == 3 ) success += draw_poly2newZ( pp, layer, lum ); if( itsalight == 2 ) success += draw_poly2newZ( pp, layer, lum ); if( itsalight == 1 ) success += draw_poly2newZ( pp, layer, lum ); if( itsalight == 0 ) success += draw_poly2new( pp, layer, lum ); } } } free_geomWF( &ret ); } } } return ( success ); } static int draw_poly2newTMP( 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; int pageres; float tim = 0.0f; int offscreen = 0; int equal = 0; // printf ("%f ",pp.v[0].x); pp.p[3] = pp.p[0]; // wrap pp.c[3] = pp.c[0]; // wrap pp.v[3] = pp.v[0]; // wrap // layer+=Gsamp_loop*MAXPASSES; // if (TILEMODE==6) // if (itsalight==2) printf("hmmm\n"); pageres = current_cam->xres * current_cam->yres; if( TILEMODE != 0 ) { pageres = alltiles.sx * alltiles.sy * ( float ) GLOBALSAMP *( float ) GLOBALSAMP; } //if (itsalight!=1) // for (x=0;x<4;x++) // { // pp.p[x].x+=campass[cursamp*4].x; // pp.p[x].y+=campass[cursamp*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( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) //if (TILEMODE!=4) for( x = 0; x < 4; x++ ) { pp.p[x].x /= ( float ) 2.0f; pp.p[x].y /= ( float ) 2.0f; pp.v[x].x /= ( float ) 2.0f; pp.v[x].y /= ( float ) 2.0f; } if( itsalight != 1 ) cursamp = layer; // tim=(float)layer/(float)Gmotion_samp; // if (itsalight==1) tim=0.0f; tim = 0.0f; if( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) 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; same += tag_tile( ( int ) floor( pd.x ), ( int ) floor( pd.y ), Gslg, GhairID, GnodeID,Gcurpass ); } // for (x=0;x<4;x++) // { // pp.p[x].z= -pp.p[x].z; // SHAVEcoord_convertTOSHAVE(&pp.p[x]); // hack me // } ////if (((int)pp.p[0].x==(int)pp.p[1].x==(int)pp.p[2].x)&& ////((int)pp.p[0].y==(int)pp.p[1].y==(int)pp.p[2].y)) equal=1; 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; // pp.p[x].x+=campass[layer].x; // pp.p[x].y+=campass[layer].y; } imaxy = ( int ) ( maxy ); iminy = ( int ) ( miny ); ///if (equal==0) { // if (TILEMODE>2) printf ("I'm here\n"); if( iminy != imaxy ) for( y = ( float ) iminy + 1.0f; y < ( float ) imaxy + 1.0f; y += 1.0 ) // for (y=(float)miny+1.0f;y<(float)maxy+1.0f;y+=1.0) { int yclip = 1; int baseadd; int gbaseadd; if( TILEMODE == 0 ) { baseadd = ( int ) y *current_cam->xres + layer * ( pageres ); gbaseadd = ( int ) y *current_cam->xres + layer * ( pageres ); } if( TILEMODE != 0 ) { // printf ("y=%f Gclipy0=%f\n",(float)y,(float)Gclipy0); baseadd = ( int ) ( y - Gclipy0 * GLOBALSAMP ) * alltiles.sx * GLOBALSAMP + layer * ( pageres ); gbaseadd = ( int ) ( y - Gclipy0 * GLOBALSAMP ) * alltiles.sx * GLOBALSAMP + layer * ( pageres ); } y1 = y; //+campass[cursamp].y; if( ( TILEMODE != 0 ) && ( ( y >= Gclipy0 * GLOBALSAMP ) && ( y <= Gclipy1 * GLOBALSAMP ) ) ) yclip = 0; if( ( TILEMODE == 0 ) && ( ( y >= Gclipy0 ) && ( y <= Gclipy1 ) ) ) yclip = 0; if( yclip == 0 ) { int aa; int done = 0; // find 2 intersections // 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]; 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; 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]; 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; 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]; 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; 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]; 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; b = aa; done = 1; } } { float bas; 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; } 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; } } // 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) { VERT pleft, cleft, pright, cright; float dx, dz; float cdx, cdy, cdz; // first sort left and right if( p1.x < p2.x ) { pleft = p1; pright = p2; cleft = c1; cright = c2; } if( p2.x <= p1.x ) { pleft = p2; pright = p1; cleft = c2; cright = c1; } dx = pright.x - pleft.x; if( dx != 0 ) { dz = ( pright.z - pleft.z ) / dx; cdx = ( cright.x - cleft.x ) / dx; cdy = ( cright.y - cleft.y ) / dx; cdz = ( cright.z - cleft.z ) / dx; } else // if dx==0 { dz = 0; cdx = 0; cdy = 0; cdz = 0; } { 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; if( pleft.x < pright.x ) //if (clipx==0) for( tt = ( float ) pleft.x; tt <= ( float ) ( qq2 ); tt += 1.0 ) { int clipit = 0; if( TILEMODE == 0 ) if( current_cam == &LWcam ) if( !( ( tt >= Gclipx0 ) && ( tt <= Gclipx1 ) ) ) clipit = 1; if( TILEMODE != 0 ) if( !( ( tt >= Gclipx0 * GLOBALSAMP ) && ( tt <= Gclipx1 * GLOBALSAMP ) ) ) 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 < current_cam->xres * GLOBALSAMP ) ) ) clipit = 1; //if (pright.x-pleft.x>0.0f) // for (tt=pleft.x;tt<=pright.x;tt+=1.0) if( clipit == 0 ) { 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 - Gclipx0 * GLOBALSAMP; if( TILEMODE > 0 ) y2 = y2 - Gclipy0 * GLOBALSAMP; 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; // plot it { int pixoff = 0; int ok = 0; int aa4 = 1; float ftt, fy; float geomz = 1000000.0f; if( TILEMODE == 6 ) current_cam = &tilebuff; if( current_cam->geombuff ) if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) 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( 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( ( 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( TILEMODE != 0 ) if( ( current_cam == &LWcam ) && ( ( y < Gclipy0 * GLOBALSAMP ) || ( y >= Gclipy1 * GLOBALSAMP ) ) ) { ok = 0; } if( ( TILEMODE != 0 ) && ( ( y < Gclipy0 * GLOBALSAMP ) || ( y >= Gclipy1 * GLOBALSAMP ) ) ) { ok = 0; } if( ( TILEMODE != 0 ) && ( ( x1 < Gclipx0 * GLOBALSAMP ) || ( x1 >= Gclipx1 * GLOBALSAMP ) ) ) { ok = 0; } // printf ("tilemode=%d\n",TILEMODE); // if (itsalight==2) ok=1; if( ok ) { success += 1; if( ( TILEMODE > 0 ) && ( TILEMODE < 6 ) ) // if (TILEMODE!=4) { // tag_tile((int) floor((float)(pc.x*2.0)/(float)GLOBALSAMP),(int) floor((float)(pc.y*2.0)/(float)GLOBALSAMP), Gslg,GhairID, GnodeID); tag_tile( ( int ) floor( ( float ) ( pc.x * 2.0 ) / ( float ) GLOBALSAMP ), ( int ) floor( ( float ) ( pc.y * 2.0 ) / ( float ) GLOBALSAMP ), Gslg, GhairID, GnodeID ,Gcurpass); } if( ( TILEMODE == 0 ) || ( TILEMODE == 6 ) ) if( itsalight != 3 ) { if( itsalight == 2 ) { current_cam->geombuff[gbaseadd + x2] = pc.z; // if (current_cam== &LWcam) // current_cam->ibuff[aa4]=255; } if( itsalight != 2 ) current_cam->zbuff[baseadd + x2] = pc.z; #ifdef showmetheoccludingsurfaces if( TILEMODE == 6 ) if( itsalight == 2 ) { unsigned char *cppt; // printf ("plot\n"); cc.x = 255; cc.y = 255; cc.z = 255; 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( itsalight == 0 ) { unsigned char *cppt; // printf ("plot\n"); 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 } // plot } // pair interp } // loop } // variable decl } // variable decl } // y>0 ysize; hairstate[index].size = ( long ) Ihairstate->size; hairstate[index].pos = 0; hairstate[index].ID = hairdataREST->ID; // hairstate[index].time = hairdataREST->time; hairfiles[index].pos = 0; hairfiles[index].ID = hairdataREST->ID; // hairfiles[index].time = hairdataREST->time; hairfiles[index].data = ( char * ) malloc( 100 + hairdataREST->size * sizeof( char ) ); for( x = 0; x < hairfiles[index].size; x++ ) hairfiles[index].data[x] = hairdataREST->data[x]; hairstate[index].data = ( char * ) malloc( Ihairstate->size * sizeof( char ) + 100 ); for( x = 0; x < hairstate[index].size; x++ ) hairstate[index].data[x] = Ihairstate->data[x]; RW_CONTEXT = RW_LOCAL; hairdataREST->pos = 0; read_hair( hairdataREST ); hairdataREST->pos = 0; if( 0 == 1 ) if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) { hair[x].lasthv[y] = hair[x].resthv[y]; hair[x].hv[y] = hair[x].resthv[y]; } if( 0 == 1 ) if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) { Slasthair[x].hv[y] = Sresthair[x].hv[y]; Sthishair[x].hv[y] = Sresthair[x].hv[y]; } { // int x,y; Ihairstate->pos = 0; //printf ("reading state info\n"); for( x = 0; x < 5; x++ ) { if( total_slgfaces[x] > 0 ) if( LOCAL_PASSES[x] > MAXPASSES ) MAXPASSES = LOCAL_PASSES[x]; } read_state_machine( Ihairstate ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) hair[x].lasthv[y] = hair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Slasthair[x].hv[y] = Sthishair[x].hv[y]; hairstate[index].pos = 0; write_state_machine( &hairstate[index] ); } //printf("done\n"); RW_CONTEXT = RW_DISK; SHAVEID =(unsigned long) hairfiles[index].ID; ///for (x=0;x<5;x++) //{ //Gshavep[totalhairfiles].haircount[x]=LOCAL_CNT[x]; //Gshavep[totalhairfiles].passes[x]=LOCAL_PASSES[x]; //} } void MAYAadd_hairCLOSE2( MEMFILE * Ohairstate, SHAVEPARMS * shavep, int index ) { int x; global_lastID = -1; hairstate[index].pos = 0; hairfiles[index].pos = 0; memcpy( &Gshavep[index], shavep, sizeof( SHAVEPARMS ) ); RW_CONTEXT = RW_LOCAL; //printf ("reading hair info (for close)\n"); read_hair( &hairfiles[index] ); //xcxcxc SHAVEID = (int )hairfiles[index].ID; SHAVEID = (unsigned long) hairfiles[index].ID; MAYAset_parms( shavep ); //#ifdef diagnose_trouble if ( GLOBAL_VERBOSE) { fprintf(stdout,"ID = %d clumps = %d totalverts = %d add_hair_close\n",(int)SHAVEID,Gclumps,totalverts);fflush(stdout); } { int x, y; BASEHAIR *TMPhair = NULL; BASEHAIR *TMPspline = NULL; //printf ("reading state info (for close)\n"); read_state_machine( &hairstate[index] ); if( totalverts > 0 ) TMPhair = ( BASEHAIR * ) malloc( totalverts * sizeof( BASEHAIR ) ); if( total_splines > 0 ) TMPspline = ( BASEHAIR * ) malloc( total_splines * sizeof( BASEHAIR ) ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) TMPhair[x].hv[y] = hair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) TMPspline[x].hv[y] = Sthishair[x].hv[y]; read_state_machine( Ohairstate ); if( totalverts > 0 ) for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) hair[x].lasthv[y] = TMPhair[x].hv[y]; if( total_splines > 0 ) for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Slasthair[x].hv[y] = TMPspline[x].hv[y]; hairstate[index].pos = 0; write_state_machine( &hairstate[index] ); if( totalverts > 0 ) Nfree( TMPhair ); if( total_splines > 0 ) Nfree( TMPspline ); } RW_CONTEXT = RW_DISK; for( x = 0; x < 5; x++ ) { Gshavep[index].shadowHaircount[x] = LOCAL_SHADCNT[x]; Gshavep[index].haircount[x] = LOCAL_CNT[x]; Gshavep[index].passes[x] = LOCAL_PASSES[x]; Gshavep[index].segs[x] = LOCAL_SEGS[x]; } for( x = 0; x < 60; x++ ) Gshavep[index].uv_link[x] = Guv_link[x]; //totalhairfiles++; } static VERT cast_shadows_lgt_simple( VERT worldPt, int lgt ) { VERT shad; int i, q, mp = 0; float cx, cy; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; float sharp; shad.x = 0; shad.y = 0; shad.z = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; // if (Gtrace == 0) if( LWlight[lgt].blank == 0 ) if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].zbuff ) if( LWlight[lgt].trace == 0 ) { float lx, ly, hx, hy; float maxp = 0; int x, y; float angle; VERT tmpa, tmpb, in; in = worldPt; for( i = 0; i < totalhairfiles; i++ ) { for( q = 0; q < 5; q++ ) if( Gshavep[i].passes[q] > mp ) mp = Gshavep[i].passes[q]; } MAXPASSES = mp; tmpa.x = in.x - LWlight[lgt].wpos.x; tmpa.y = in.y - LWlight[lgt].wpos.y; tmpa.z = in.z - LWlight[lgt].wpos.z; tmpa = Vnorm( tmpa ); tmpb.x = LWlight[lgt].view[0][2]; tmpb.y = LWlight[lgt].view[1][2]; tmpb.z = LWlight[lgt].view[2][2]; tmpb = Vnorm( tmpb ); angle = VDot( tmpa, tmpb ); if( angle > 0.0f ) { if( ( totallights > 0 ) ) // && ( (LWlight[lgt].zbuff != NULL) ) ) { sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if( ( LWlight[lgt].xres != 0 ) ) // if( ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; VERT2 cpt1, cpt2, cpt, pt; float d, dx, dy; pt.x = worldPt.x; pt.y = worldPt.y; pt.z = worldPt.z; cpt = world2cam( &LWCamOPEN, pt ); cpt1 = cpt; cpt2 = cpt; cpt1.x += 1; cpt1.y += 1; cpt1 = cam2world( &LWCamOPEN, cpt1 ); cpt2 = cam2world( &LWCamOPEN, cpt2 ); cpt1 = world2cam( &LWlight[lgt], cpt1 ); cpt2 = world2cam( &LWlight[lgt], cpt2 ); dx = cpt1.x - cpt2.x; dy = cpt1.y - cpt2.y; d = sqrt( dx * dx + dy * dy ); if( sharp < d * .75 ) { sharp = d * .75; m = sharp; } camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt.clip = 0; camPt.clipz = 0; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if( skip > 3 ) skip = 3; skip = 1.0f; numSamples = 0; { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); p = 0; shad.x = 0.0f; if( !camPt.clipz ) { int skip = 0; camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; ly = camPt.y - sharp; hx = camPt.x + sharp; hy = camPt.y + sharp; if( lx < 0 ) skip = 1; if( lx > lxr ) skip = 1; if( ly < 0 ) skip = 1; if( ly > lyr ) skip = 1; if( hx < 0 ) skip = 1; if( hx > lxr ) skip = 1; if( hy < 0 ) skip = 1; if( hy > lyr ) skip = 1; if( lx == hx ) shad.x = 1.0f; if( ly == hy ) shad.x = 1.0f; // if( camPt.clip == 0 ) // flicker if( skip == 0 ) shad.x = illum_box_cursamp( jitt.z, lgt, lx, ly, hx, hy, cursamp ); // cursamp needs to be passed down the chain! // else // shad.x = 1.0f; if( lxr == 0 ) shad.x = 1.0f; if( skip == 1 ) shad.x = 0.0f; } shad.y = shad.x; shad.z = shad.x; } } else { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; } } else // (totallights == 0) || (LWlight[lgt].zbuff == NULL) { // float cone=1.0f; if( LWlight[lgt].xres == 0 ) shad.x = shad.y = shad.z = 1.0; if( LWlight[lgt].xres > 0 ) shad.x = shad.y = shad.z = 0.0; } } else { shad.x = shad.y = shad.z = 0.0f; } } if( LWlight[lgt].blank ) { shad.x = shad.y = shad.z = 0.0f; } if( LWlight[lgt].xres > 0 ) if( LWlight[lgt].trace == 0 ) if( !LWlight[lgt].zbuff ) { shad.x = shad.y = shad.z = 0.0f; } //else // Gtrace != 0 if( LWlight[lgt].trace == 1 ) { VOXSAMP vsamp; VERT rdir; rdir.x = LWlight[lgt].wpos.x - worldPt.x; rdir.y = LWlight[lgt].wpos.y - worldPt.y; rdir.z = LWlight[lgt].wpos.z - worldPt.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, worldPt, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; shad.x = shad.y = shad.z = ( 1.0f - vsamp.opacity ); } calibrateX = cx; calibrateY = cy; return shad; } static VERT cast_shadows_lgt_simpleINST( 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 ) { if( ( totallights > 0 ) && ( LWlight[lgt].zbuff != NULL ) ) { SELF_SHARP = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); //SELF_SHARP=1; if( ( Gclipz == 0 ) && ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; int i, j, q; float m = ( float ) SELF_SHARP; int numSamples; int 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; numSamples = 0; skip = 1.0f; //if (camPt.clip!=1) if( Gclipz == 0 ) for( i = camPt.x - SELF_SHARP; i <= camPt.x + SELF_SHARP; i += skip ) for( j = camPt.y - SELF_SHARP; j <= camPt.y + SELF_SHARP; j += skip ) { float zz2; jitt.x = i; jitt.y = j; /// zz2 = getzGEOMNEW(jitt, lgt,0); for( q = 0; q < MAXPASSES; q++ ) { numSamples++; if( ( jitt.x >= 0 ) && ( jitt.x < LWlight[lgt].xres - 1 ) && ( jitt.y >= 0 ) && ( jitt.y < LWlight[lgt].yres - 1 ) ) { float zz; zz = getzNEW( jitt, lgt, q ); 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 } } else { shad.x = 1.0f; numSamples = 1; } if( numSamples > 0 ) { shad.x /= ( float ) ( numSamples ); shad.y /= ( float ) ( numSamples ); shad.z /= ( float ) ( numSamples ); } } } 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 ) * 0.75f + 0.25f; } calibrateX = cx; calibrateY = cy; return shad; } float SHAVEilluminate_point( VERT in, int lgt ) { float cx, cy; float illum = 0.0f; float i, j, q; float numSamples = 0; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; int sharp; int doneone = 0; if( totalhairfiles > 0 ) { if( Gdone == 0 ) { #ifndef EXTPRIM #ifndef ALTERNATE_DEFS #endif #endif in.z = -in.z; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; //if (Gtrace==0) if( LWlight[lgt].trace == 0 ) if( LWlight[lgt].xres > 0 ) if( lgt < totallights ) { int x, y; float angle; VERT tmpa, tmpb; SHAVEcoord_convertTOSHAVE( &in ); tmpa.x = in.x - LWlight[lgt].wpos.x; tmpa.y = in.y - LWlight[lgt].wpos.y; tmpa.z = in.z - LWlight[lgt].wpos.z; tmpa = Vnorm( tmpa ); tmpb.x = LWlight[lgt].view[0][2]; tmpb.y = LWlight[lgt].view[1][2]; tmpb.z = LWlight[lgt].view[2][2]; tmpb = Vnorm( tmpb ); angle = VDot( tmpa, tmpb ); sharp = LWlight[lgt].fuzz; if( sharp < .6 ) sharp = .6; //if (angle>.25f) illum=1; //else illum=0.0f; illum = 1.0f; if( angle > 0.0f ) { if( ( LWlight[lgt].xres != 0 ) && ( LWlight[lgt].zbuff ) && ( totalhairfiles > 0 ) ) { VERT jitt; float mx = ( float ) SELF_SHARP; float my = ( float ) SELF_SHARP; VERT2 pt; int qq; pt.x = in.x; pt.y = in.y; pt.z = in.z; { int p; VERT2 ptt[4]; float remx, remy; float lum[4]; int clp = 0; VERT2 cpt1, cpt2, cpt; float d, dx, dy; // calculate pixel span and make sure the whole pix is covered by fuzz cpt = world2cam( &LWCamOPEN, pt ); cpt1 = cpt; cpt2 = cpt; cpt1.x += 1; cpt1.y += 1; cpt1 = cam2world( &LWCamOPEN, cpt1 ); cpt2 = cam2world( &LWCamOPEN, cpt2 ); cpt1 = world2cam( &LWlight[lgt], cpt1 ); // clp=0;clp+=cpt1.clip; cpt2 = world2cam( &LWlight[lgt], cpt2 ); // clp+=cpt2.clip; dx = cpt1.x - cpt2.x; dy = cpt1.y - cpt2.y; d = sqrt( dx * dx + dy * dy ); if( sharp < d ) sharp = d; { mx = sharp; my = sharp; } pt = world2cam( &LWlight[lgt], pt ); 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 ); // if (clp<2) for( p = 0; p < 4; p++ ) // we're doing this to antialias for spot coverage. { if( pt.clipz == 0 ) { float lx, ly, hx, hy; int skip = 0; pt = ptt[p]; illum = 0.0f; numSamples = 0; lx = pt.x - sharp; ly = pt.y - sharp; hx = pt.x + sharp; hy = pt.y + sharp; if( lx < 0 ) skip = 1; if( lx > lxr ) skip = 1; if( ly < 0 ) skip = 1; if( ly > lyr ) skip = 1; if( hx < 0 ) skip = 1; if( hx > lxr ) skip = 1; if( hy < 0 ) skip = 1; if( hy > lyr ) skip = 1; illum = 1.0f; if( skip == 0 ) { if( !( ( lx == hx ) && ( ly == hy ) ) ) { doneone = 1; illum = illum_box( jitt.z, lgt, lx, ly, hx, hy ); } else { // not sure why we're doing this - but this is what we do when the fuzz=0 doneone = 1; illum = 1.0f; } } lum[p] = illum; } else lum[p] = 1.0f; } { float xxx, xxx1; xxx = lum[0] * ( 1.0f - remx ) + lum[1] * remx; xxx1 = lum[3] * ( 1.0f - remx ) + lum[2] * remx; illum = xxx * ( 1.0f - remy ) + xxx1 * remy; } // if (clp<2) illum=0.0f; } } // else if( ( LWlight[lgt].xres == 0 ) || ( !LWlight[lgt].zbuff ) && ( totalhairfiles > 0 ) ) illum = 1.0f; if( ( LWlight[lgt].xres != 0 ) && ( LWlight[lgt].zbuff == NULL ) ) { int p; VERT2 pt; float remx, remy; float lum[4]; int clp = 0; int skip = 0; VERT2 cpt1, cpt2, cpt; float d, dx, dy; pt.x = in.x; pt.y = in.y; pt.z = in.z; // calculate pixel span and make sure the whole pix is covered by fuzz pt = world2cam( &LWlight[lgt], pt ); if( pt.x < LWlight[lgt].fuzz ) skip = 1; if( pt.y < LWlight[lgt].fuzz ) skip = 1; if( pt.x + LWlight[lgt].fuzz >= LWlight[lgt].xres ) skip = 1; if( pt.y + LWlight[lgt].fuzz >= LWlight[lgt].yres ) skip = 1; illum = 0.0f; if( skip == 0 ) illum = 1.0f; } } // else // else // SELF_SHARP *= LWlight[lgt].xres / 600.0f; } if( LWlight[lgt].trace == 1 ) { VOXSAMP vsamp; VERT rdir; SHAVEcoord_convertTOSHAVE( &in ); rdir.x = LWlight[lgt].wpos.x - in.x; rdir.y = LWlight[lgt].wpos.y - in.y; rdir.z = LWlight[lgt].wpos.z - in.z; rdir = Vnorm( rdir ); VXtrace( 0.0f, 1000000.0f, in, rdir, ( int ) 0, &vsamp ); if( vsamp.opacity > 1.0f ) vsamp.opacity = 1.0f; illum = ( 1.0f - vsamp.opacity ); } if( ( LWlight[lgt].trace == 1 ) && ( totalhairfiles == 0 ) ) illum = 1.0f; if( GactivateGI == 0 ) if( totallights == 0 ) illum = 1.0f; calibrateX = cx; calibrateY = cy; //illum=1.0f; // illum=drand98(); // illum=0; if( ( LWlight[lgt].xres > 0 ) && ( LWlight[lgt].zbuff == NULL ) ) illum = 1.0f; if( ( LWlight[lgt].xres > 0 ) && ( doneone == 0 ) ) illum = 1.0f; } } else illum = 1.0f; return illum; } float SHAVEilluminate_pointNOGEOM( VERT in, int lgt ) { float cx, cy; float illum = 0.0f; int i, j, q; int lxr = LWlight[lgt].xres; int lyr = LWlight[lgt].yres; in.z = -in.z; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; if( lgt < totallights ) { SHAVEcoord_convertTOSHAVE( &in ); SELF_SHARP = LWlight[lgt].fuzz; if( LWlight[lgt].xres != 0 ) { VERT jitt; float mx = ( float ) SELF_SHARP; float my = ( float ) SELF_SHARP; int skip; // int numSamples = LWlight[lgt].shadsamps * GextrasampLIGHT; int numSamples = 0; VERT2 pt; int qq; // skip=LWlight[lgt].shadsamps; // if (skip>3) skip=3; // skip=4-skip; skip = 1; pt.x = in.x; pt.y = in.y; pt.z = in.z; numSamples = 0; { float lx, ly, hx, hy; pt = world2cam( &LWlight[lgt], pt ); jitt.z = pt.z; lx = pt.x - SELF_SHARP; if( lx < 0 ) lx = 0; if( lx > lxr ) lx = lxr; ly = pt.y - SELF_SHARP; if( ly < 0 ) ly = 0; if( ly > lyr - 1 ) ly = lyr - 1; hx = pt.x + SELF_SHARP; if( hx < 0 ) hx = 0; if( hx > lxr - 1 ) hx = lxr - 1; hy = pt.y + SELF_SHARP; if( hy < 0 ) ly = 0; if( hy > lyr - 1 ) hy = lyr - 1; illum = 0.0f; if( lx == hx ) illum = 0.0f; if( ly == hy ) illum = 0.0f; if( Gclipz == 0 ) illum = illum_box( jitt.z, lgt, lx, ly, hx, hy ); else { illum = 1.0f; numSamples = 1; } } } // else // SELF_SHARP *= LWlight[lgt].xres / 600.0f; } calibrateX = cx; calibrateY = cy; return illum; } static VERT cam2world1( LIGHTINFO * cam, VERT in ) // just like cam2world, but no VERT2 struct { float s, t; VERT out; //if (itsalight!=1) //{ // in.x-=calibrateX; // in.y-=calibrateY; //} s = cam->xres * 0.5f; t = cam->yres * 0.5f; out.x = ( ( in.x - s ) / t ) * cam->aspect; out.y = -( ( in.y / t ) - 1 ); out.z = in.z; out = vxmp( cam->iview, out ); return ( out ); } static VERT2 cam2world( LIGHTINFO * cam, VERT2 in ) { float s; VERT out; VERT2 ott; float t; ott.clip = 0; //if (itsalight!=1) //{ // in.x-=calibrateX; // in.y-=calibrateY; //} s = cam->xres * 0.5f; t = cam->yres * 0.5f; out.x = ( ( in.x - s ) / t ) * cam->aspect; out.y = -( ( in.y / t ) - 1 ); out.z = in.z; ott.x = out.x; ott.y = out.y; ott.z = out.z; ott = vxmp3( cam->iview, out, cam->zoom ); out.x = ott.x; out.y = ott.y; out.z = ott.z; // ott.clip=ott.clip; // ott.clip=0; // out.clip=0; return ( ott ); } //ndif static VERT2 world2cam( LIGHTINFO * cam, VERT2 in ) { float s, t; VERT2 out; VERT vin; vin.x = in.x; vin.y = in.y; vin.z = in.z; out = vxmp3( cam->view, vin, cam->zoom ); s = ( float ) cam->xres / 2.0f; t = ( float ) cam->yres / 2.0f; out.x = ( out.x / cam->aspect ) * t + s; out.y = t - out.y * t; return out; } static VERT world2cam1( LIGHTINFO * cam, VERT in ) { VERT out; out = vxmp( cam->view, in ); //out.clip=0; //if ((out.clip==0)) { float s, t; s = ( float ) cam->xres / 2.0f; t = ( float ) cam->yres / 2.0f; out.x = ( out.x / cam->aspect ) * t + s; out.y = t - out.y * t; // out.x = out.x *cam->aspect * s / 2.0f + s ; // out.x = (out.x * s + s )*cam->aspect; //in.y = t - out.y*t; //in.y/t = 1-out.y; //(in.y/t-1) = -out.y; // out.x = int.x * aspect *t + s // out.x - s = int.x * aspect *t // (out.x - s) = int.x * aspect *t // out.x = (in.x - s)/t/aspect // out.y = t - in.y * t ; // out.y/t = 1 +- in.y; // out.y/t -1 = -in.y; // -in.y/t +1 = out.y; // out.x=(out.x * s /(float) cam->aspect + (float)cam->xres / 2.0f + .5f); // out.y=((float)cam->yres/2.0f - out.y * s +.5f); // if (itsalight!=1) // { //out.x+=calibrateX; //out.y+=calibrateY; // } } return ( out ); } static int draw_line2( POLYDAT pp, int layer, unsigned char lum ) { int x; int success = 0; float y; int a, b; float y1; int same = 0; float tim = 0.0f; if( itsalight != 1 ) for( x = 0; x < 2; x++ ) { { pp.p[x].x += campass[cursamp * 4].x; pp.p[x].y += campass[cursamp * 4].y; } if( itsalight == 2 ) { int csmp; csmp = cursamp; // pp.p[x].x+=campass[csmp*4].x; // dont blur occlusions // pp.p[x].y+=campass[csmp*4].y; } } if( itsalight != 1 ) cursamp = layer; tim = ( float ) layer / ( float ) Gmotion_samp; if( itsalight == 1 ) tim = 0.0f; if( itsalight != 1 ) for( x = 0; x < 2; x++ ) { //if (cursamp>0) if( itsalight != 1 ) { pp.p[x].x += pp.v[x].x * tim; pp.p[x].y += pp.v[x].y * tim; pp.p[x].z += pp.v[x].z * tim; pp.w[x].x += pp.wv[x].x * tim; pp.w[x].y += pp.wv[x].y * tim; pp.w[x].z += pp.wv[x].z * tim; } //if (cursamp==0) // { // pp.p[x].x+=pp.v[x].x*.55f; // pp.p[x].y+=pp.v[x].y*.55f; // pp.p[x].z+=pp.v[x].z*.55f; // pp.w[x].x+=pp.wv[x].x*.55f; // pp.w[x].y+=pp.wv[x].y*.55f; // pp.w[x].z+=pp.wv[x].z*.55f; // } } if( itsalight == 1 ) for( x = 0; x < 2; x++ ) { pp.p[x].x += pp.v[x].x * .5f; pp.p[x].y += pp.v[x].y * .5f; pp.p[x].z += pp.v[x].z * .5f; pp.w[x].x += pp.wv[x].x * .5f; pp.w[x].y += pp.wv[x].y * .5f; pp.w[x].z += pp.wv[x].z * .5f; } { float xl, yl, xs, ys; //if (0==1) { yl = Gclipy0 - 1; ys = Gclipy1 + 1; if( yl < 0 ) yl = 0; xl = Gclipx0 - 1; // wasn't like this before xs = Gclipx1 + 1; // xl=Gclipx0+4; // xs=Gclipx1-4; } { int xx; int clippit = 0; int reject = 0; { // WFTYPE ret; // init_geomWF(&ret); { camspace_clipLine( &pp, xl, yl, xs, ys, current_cam->zoom ); if( !( ( pp.p[0].x == pp.p[1].x ) && ( pp.p[0].y == pp.p[1].y ) ) ) success += draw_line2new( pp, layer, lum ); } // free_geomWF(&ret); } } } return ( success ); } float illum_box( float inz, int lgt, int lx, int ly, int hx, int hy ) { // int lx,ly,hx,hy; int i, j; int add1; int add, add2; float ret = 0.0f; int q; float zz; int r2; float numSamples = 0; int lxr = LWlight[lgt].xres; if( LWlight[lgt].zbuff ) { int xr, yr; q=0; xr = LWlight[lgt].xres - 1; yr = LWlight[lgt].yres - 1; r2 = ( int ) ( LWlight[lgt].xres * LWlight[lgt].yres ); if( lxr > 0 ) // no deep shads for( q = 0; q < MAXPASSES; q++ ) { add2 = r2 * q; for( j = ly; j < hy; j++ ) if( ( j >= 0 ) && ( j < yr ) ) { int jj; jj = j; if( jj < 0 ) jj = 0; if( jj > yr - 1 ) jj = yr - 1; add1 = lxr * jj + add2; for( i = lx; i < hx; i++ ) { int ii; ii = i; if( ii < 0 ) ii = 0; if( ii > xr - 1 ) ii = xr - 1; add = add1 + ii; { numSamples++; { zz = LWlight[lgt].zbuff[add]; // zz = getzNEW(jitt, lgt,q); // used to be (inz<=zz) if( ( inz < zz ) ) //&& (jitt.z < zz2)) { ret += 1.0f; } } } } } } if( numSamples > 0 ) ret /= ( float ) numSamples; else ret = 1.0f; // no samples qualified ! } else ret = 1.0f; return ( ret ); } float illum_box_cursamp( float inz, int lgt, int lx, int ly, int hx, int hy, int pass ) { // int lx,ly,hx,hy; int i, j; int add1; int add, add2; float ret = 0.0f; int q; float zz; int r2; float numSamples = 0; int lxr = LWlight[lgt].xres; if( LWlight[lgt].zbuff ) { int xr, yr; xr = LWlight[lgt].xres - 1; yr = LWlight[lgt].yres - 1; r2 = ( int ) ( LWlight[lgt].xres * LWlight[lgt].yres ); if (lx<0) lx=0; if (hx<0) hx=0; if (ly<0) ly=0; if (hy<0) hy=0; if (lx>xr-1) lx=xr-1; if (hx>xr-1) hx=xr-1; if (ly>yr-1) ly=yr-1; if (hy>yr-1) hy=yr-1; if ((lx!=hx)&&(ly!=hy)) if( lxr > 0 ) // for( q = 0; q < MAXPASSES; q++ ) { float *zleft; float *zb; q = pass; add2 = r2 * q; add1 = lxr * ly + add2+lx; zleft=&LWlight[lgt].zbuff[add1]; for( j = ly; j < hy; j++ ) { int jj; zb= zleft; for( i = lx; i < hx; i++ ) { numSamples++; zz = (*zb);//LWlight[lgt].zbuff[add]; if( ( inz < zz ) ) //&& (jitt.z < zz2)) { ret += 1.0f; } zb++; } zleft+=lxr; } } if( numSamples > 0 ) ret /= ( float ) numSamples; // if( numSamples == 0 ) // ret = 0.0f; } else ret = 0.0f; return ( ret ); } float illum_box_cursampOLD( float inz, int lgt, int lx, int ly, int hx, int hy, int pass ) { // int lx,ly,hx,hy; int i, j; int add1; int add, add2; float ret = 0.0f; int q; float zz; int r2; float numSamples = 0; int lxr = LWlight[lgt].xres; if( LWlight[lgt].zbuff ) { int xr, yr; xr = LWlight[lgt].xres - 1; yr = LWlight[lgt].yres - 1; r2 = ( int ) ( LWlight[lgt].xres * LWlight[lgt].yres ); if( lxr > 0 ) // for( q = 0; q < MAXPASSES; q++ ) { q = pass; add2 = r2 * q; for( j = ly; j < hy; j++ ) if( ( j >= 0 ) && ( j < yr ) ) { int jj; jj = j; // if (jj<1) jj=1; // if (jj>yr-2) jj=yr-2; add1 = lxr * jj + add2; for( i = lx; i < hx; i++ ) if( ( i >= 0 ) && ( i < xr ) ) { int ii; ii = i; // if (ii<0) ii=0; // if (ii>xr-1) ii=xr-1; add = add1 + ii; { numSamples++; { zz = LWlight[lgt].zbuff[add]; if( ( inz < zz ) ) //&& (jitt.z < zz2)) { ret += 1.0f; } } } } } } if( numSamples > 0 ) ret /= ( float ) numSamples; // if( numSamples == 0 ) // ret = 0.0f; } else ret = 0.0f; return ( ret ); } float illum_boxGEOM( float inz, int lgt, int lx, int ly, int hx, int hy) { // int lx,ly,hx,hy; int i, j; int add1; int add;//, add2; float ret = 0.0f; int q; float zz; // int r2; float numSamples = 0; int lxr = LWlight[lgt].xres; if( LWlight[lgt].geombuff ) { int xr, yr; xr = LWlight[lgt].xres - 1; yr = LWlight[lgt].yres - 1; // r2 = ( int ) ( LWlight[lgt].xres * LWlight[lgt].yres ); if (lx<0) lx=0; if (hx<0) hx=0; if (ly<0) ly=0; if (hy<0) hy=0; if (lx>xr-1) lx=xr-1; if (hx>xr-1) hx=xr-1; if (ly>yr-1) ly=yr-1; if (hy>yr-1) hy=yr-1; if ((lx!=hx)&&(ly!=hy)) if( lxr > 0 ) // for( q = 0; q < MAXPASSES; q++ ) { float *zleft; float *zb; // q = pass; // add2 = r2 ; // add2=0; add1 = lxr * ly + lx; zleft=&LWlight[lgt].geombuff[add1]; for( j = ly; j < hy; j++ ) { int jj; zb= zleft; for( i = lx; i < hx; i++ ) { numSamples++; zz = (*zb);//LWlight[lgt].zbuff[add]; if( ( inz < zz ) ) //&& (jitt.z < zz2)) { ret += 1.0f; } zb++; } zleft+=lxr; } } if( numSamples > 0 ) ret /= ( float ) numSamples; // if( numSamples == 0 ) // ret = 0.0f; } else ret = 0.0f; return ( ret ); } float illum_boxGEOMOLD( float inz, int lgt, int lx, int ly, int hx, int hy ) { // int lx,ly,hx,hy; int i, j; int add1; int add, add2; float ret = 0.0f; int q; float zz; float numSamples = 0; int lxr = LWlight[lgt].xres; int r2; r2 = ( int ) ( LWlight[lgt].xres * LWlight[lgt].yres ); // for (q=1;q<=MAXPASSES;q++) q = 0; if( lxr > 0 ) { add2 = ( r2 ) * q; for( j = ly; j < hy; j++ ) { add1 = lxr * j + add2; for( i = lx; i < hx; i++ ) { add = add1 + i; { numSamples++; { zz = LWlight[lgt].geombuff[add]; // zz = getzNEW(jitt, lgt,q); if( ( inz <= zz ) ) //&& (jitt.z < zz2)) { ret += 1.0f; } } } } } } else ret = 1.0f; if( numSamples > 0 ) ret /= ( float ) numSamples; return ( ret ); } static VERT cast_shadows_lgt_simplePOINTLIGHT( VERT worldPt, int lgt ) { VERT shad; int i, q, mp = 0; float cx, cy; int lxr = LWlight[lgt].xres - 1; int lyr = LWlight[lgt].yres - 1; float sharp; int lg2; float maxv = 0.0f; shad.x = 0; shad.y = 0; shad.z = 0; cx = calibrateX; cy = calibrateY; calibrateX = 0.0f; calibrateY = 0.0f; // if (Gtrace == 0) lg2 = lgt; if( LWlight[lgt].trace == 0 ) for( lgt = lg2; lgt < lg2 + 6; lgt++ ) // visit all 6 if( LWlight[lgt].blank == 0 ) { { float lx, ly, hx, hy; float maxp = 0; int x, y; float angle; VERT tmpa, tmpb, in; in = worldPt; for( i = 0; i < totalhairfiles; i++ ) { for( q = 0; q < 5; q++ ) if( Gshavep[i].passes[q] > mp ) mp = Gshavep[i].passes[q]; } MAXPASSES = mp; tmpa.x = in.x - LWlight[lgt].wpos.x; tmpa.y = in.y - LWlight[lgt].wpos.y; tmpa.z = in.z - LWlight[lgt].wpos.z; tmpa = Vnorm( tmpa ); tmpb.x = LWlight[lgt].view[0][2]; tmpb.y = LWlight[lgt].view[1][2]; tmpb.z = LWlight[lgt].view[2][2]; tmpb = Vnorm( tmpb ); angle = VDot( tmpa, tmpb ); if( angle > 0.15f ) { if( ( totallights > 0 ) ) // && ( LWlight[lgt].zbuff != NULL ) ) { sharp = LWlight[lgt].fuzz; // * ((float)LWlight[lgt].xres/600.0f); if( sharp < .6 ) sharp = .6; if( ( LWlight[lgt].xres != 0 ) ) // if( ( LWlight[lgt].xres != 0 ) ) { VERT2 camPt; VERT jitt; float i, j, q; float m = ( float ) sharp; int numSamples; float skip; VERT2 cpt1, cpt2, cpt, pt; float d, dx, dy; pt.x = worldPt.x; pt.y = worldPt.y; pt.z = worldPt.z; cpt = world2cam( &LWCamOPEN, pt ); cpt1 = cpt; cpt2 = cpt; cpt1.x += 1; cpt1.y += 1; cpt1 = cam2world( &LWCamOPEN, cpt1 ); cpt2 = cam2world( &LWCamOPEN, cpt2 ); cpt1 = world2cam( &LWlight[lgt], cpt1 ); cpt2 = world2cam( &LWlight[lgt], cpt2 ); dx = cpt1.x - cpt2.x; dy = cpt1.y - cpt2.y; d = sqrt( dx * dx + dy * dy ); if( sharp < d * .75 ) { sharp = d * .75; m = sharp; } camPt.x = worldPt.x; camPt.y = worldPt.y; camPt.z = worldPt.z; camPt.clip = 0; camPt.clipz = 0; camPt = world2cam( &LWlight[lgt], camPt ); jitt.z = camPt.z; skip = LWlight[lgt].shadsamps; if( skip > 3 ) skip = 3; skip = 1.0f; numSamples = 0; { int p; VERT2 ptt[4], pt; float remx, remy; float lum[4]; pt = camPt; ptt[0] = pt; pt.x += 1.0f; ptt[1] = pt; pt.y += 1.0f; ptt[2] = pt; pt.x -= 1.0f; ptt[3] = pt; pt.y -= 1.0f; jitt.z = pt.z; remx = pt.x - floor( pt.x ); remy = pt.y - floor( pt.y ); p = 0; shad.x = 0.0f; if( !camPt.clipz ) { camPt = ptt[p]; shad.x = 0.0f; numSamples = 0; lx = camPt.x - sharp; if( lx < 0 ) lx = 0; if( lx > lxr ) lx = lxr; ly = camPt.y - sharp; if( ly < 0 ) ly = 0; if( ly > lyr ) ly = lyr; hx = camPt.x + sharp; if( hx < 0 ) hx = 0; if( hx > lxr ) hx = lxr; hy = camPt.y + sharp; if( hy < 0 ) ly = 0; if( hy > lyr ) hy = lyr; if( lx == hx ) shad.x = 1.0f; if( ly == hy ) shad.x = 1.0f; // if( camPt.clip == 0 ) shad.x = illum_box_cursamp( jitt.z, lgt, lx, ly, hx, hy, Gcurpass ); // cursamp needs to be passed down the chain! // else // shad.x = 1.0f; if( lxr == 0 ) shad.x = 1.0f; } shad.y = shad.x; shad.z = shad.x; } } else { shad.x = 1.0f; shad.y = 1.0f; shad.z = 1.0f; } } else // (totallights == 0) || (LWlight[lgt].zbuff == NULL) { // float cone=1.0f; shad.x = shad.y = shad.z = 1.0; } } else { shad.x = shad.y = shad.z = 0.0f; } if( shad.x > maxv ) { maxv = shad.x; } } shad.x = maxv; shad.y = maxv; shad.x = maxv; } lgt = lg2 + 6; //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; }