// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 /* change */ #ifdef MAYA3D #define EDIT_SPLINES #endif void Smake_restlengths( void ) { int x, y; float td = 0; for( x = 0; x < total_splines; x++ ) { for( y = 0; y < 14; y++ ) { td += Distance( Shair[x].noisev[y], Shair[x].noisev[y + 1] ); //== Shair[x].restlength = Distance( Shair[x].hv[1], Shair[x].hv[2] ); //== Sthishair[x] = Shair[x]; //==Slasthair[x] = Shair[x]; //== Sresthair[x] = Shair[x]; } td /= ( float ) y; Shair[x].restlength = td; Sresthair[x].restlength = td; Sresthair[x].sparerestlength = td; Shair[x].sparerestlength = td; } } void spline_chain( int n ) { int x; float u; // int q; int a1, a2, a3, a4; for( x = 14; x > 0; x -= 3 ) { // q=x*3; a1 = x - 3; a2 = x; a3 = x + 3; a4 = x + 6; if( a1 < 2 ) a1 = 2; if( a2 < 2 ) a2 = 2; if( a3 < 2 ) a3 = 2; if( a4 < 2 ) a4 = 2; if( a1 > 14 ) a1 = 14; if( a2 > 14 ) a2 = 14; if( a3 > 14 ) a3 = 14; if( a4 > 14 ) a4 = 14; for( u = 0.0f; u < ( float ) 1.0f; u += ( float ) ( 1.0f / 18.0f ) ) { VERT sp; int uu; sp.x = spline( hair[n].hv[a1].x, hair[n].hv[a2].x, hair[n].hv[a3].x, hair[n].hv[a4].x, u ); sp.y = spline( hair[n].hv[a1].y, hair[n].hv[a2].y, hair[n].hv[a3].y, hair[n].hv[a4].y, u ); sp.z = spline( hair[n].hv[a1].z, hair[n].hv[a2].z, hair[n].hv[a3].z, hair[n].hv[a4].z, u ); uu = ( int ) floor( spline( ( float ) a1, ( float ) a2, ( float ) a3, ( float ) a4, u ) ); if( ( uu != 0 ) && ( uu != 2 ) && ( uu != 5 ) && ( uu != 8 ) && ( uu != 11 ) && ( uu != 14 ) ) hair[n].hv[uu] = sp; } } } void extract_chain( BASEHAIR * h ) { VERT lowpoly[555]; VERT highpoly[544]; int tv = 0; int lastv; int thisv; float td, tdd; int uc; int x; // get the face // if (0==1) if( ( sliders[8][4].value == 1.0 ) || ( Grendermode == 1 ) ) { float tvv; float inc; float q; int qqq = 0; tv = ( Dface_end[h->pid] - Dface_start[h->pid] ); tvv = ( float ) tv; inc = ( tvv ) / 15.0f; qqq = 0; // assume splines are 15 verts .. // for (x=0;x<15;x++) h->hv[x]=Dv[Dfacelist[Dface_start[h->pid]+x]]; // if (0==1) for( q = 0; q < tvv; q += inc ) { int qq; int a, b, c, d; float u; // VERT aa,bb,cc,dd; qq = ( int ) floor( q ); u = q - floor( q ); a = qq - 1; b = qq; c = qq + 1; d = qq + 2; if( a < 0 ) a = 0; if( a > tv - 1 ) a = tv - 1; if( b > tv - 1 ) b = tv - 1; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; a = Dfacelist[a + Dface_start[h->pid]]; b = Dfacelist[b + Dface_start[h->pid]]; c = Dfacelist[c + Dface_start[h->pid]]; d = Dfacelist[d + Dface_start[h->pid]]; // if( qqq < 14 ) why? // if( qqq != 0 ) why? { // printf ("qq = %d a b c d pid %d %d %d %d %d\n",qq,a,b,c,d,h->pid); h->hv[qqq].x = spline( Dv[a].x, Dv[b].x, Dv[c].x, Dv[d].x, u ); h->hv[qqq].y = spline( Dv[a].y, Dv[b].y, Dv[c].y, Dv[d].y, u ); h->hv[qqq].z = spline( Dv[a].z, Dv[b].z, Dv[c].z, Dv[d].z, u ); } qqq++; } h->hv[qqq]=Dv[Dfacelist[Dface_end[h->pid]-1]]; h->hv[0]=Dv[Dfacelist[Dface_start[h->pid]]]; qqq++; // h->restlength = Distance( h->hv[1], h->hv[2] ); // h->vid = find_closest_vert( h->hv[0] ); } if( Grendermode == 0 ) if( sliders[8][4].value < 1.0f ) if( Dtotalverts > 0 ) { tv = 0; // why are these flipped?? // for( x = Dface_end[h->pid] - 1; x >= Dface_start[h->pid]; x-- ) for( x = Dface_start[h->pid]; x < Dface_end[h->pid]; x++ ) { lowpoly[tv] = Dv[Dfacelist[x]]; tv++; } // lowpoly[tv]=v[facelist[face_start[h->pid]]]; // tv++; // add an extra one for good measure uc = 0; for( x = 0; x < tv; x++ ) { int a, b, c, d; float u; // VERT aa,bb,cc,dd; a = x - 1; b = x; c = x + 1; d = x + 2; if( a < 0 ) a = 0; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; for( u = 0; u < 1.0f; u += ( ( float ) tv / 500.0 ) ) { char tmp[255]; highpoly[uc].x = spline( lowpoly[a].x, lowpoly[b].x, lowpoly[c].x, lowpoly[d].x, u ); highpoly[uc].y = spline( lowpoly[a].y, lowpoly[b].y, lowpoly[c].y, lowpoly[d].y, u ); highpoly[uc].z = spline( lowpoly[a].z, lowpoly[b].z, lowpoly[c].z, lowpoly[d].z, u ); // sprintf(tmp,"x = %d uc = %d %f %f %f",x,uc,highpoly[uc].x,highpoly[uc].y,highpoly[uc].z); // DRAW_STATUS(tmp); uc++; } } td = 0; for( x = 0; x < 500 - 1; x++ ) { td += Distance( highpoly[x], highpoly[x + 1] ); } tdd = td; td /= 15.0f; // (was 16) this is the distance increment per seg // h->restlength=td; h->hv[0] = lowpoly[0]; h->hv[14] = lowpoly[tv - 1]; lastv = 0; thisv = 1; for( x = 1; x < 15; x++ ) { if( td > 0.0f ) { while( ( Distance( highpoly[lastv], highpoly[thisv] ) <= td ) && ( thisv < 500 - 2 ) ) { thisv++; } if( thisv > 500 - 1 ) thisv = 500 - 1; h->hv[x] = highpoly[thisv]; } else h->hv[x] = highpoly[0]; lastv = thisv; } // h->hv[0] = lowpoly[0]; // fix the ends // h->hv[14] = lowpoly[tv-1]; // h->mtl=splines; // h->vid=find_closest_vert(h->hv[0]); // h->restlength = tdd/15.0f ; tv = ( Dface_end[h->pid] - Dface_start[h->pid] ); /* is this necessary? */ // h->hv[0] = Dv[Dface_start[h->pid]]; // fix the ends // h->hv[14] = Dv[Dface_end[h->pid]-1]; // */ } // for some reason the maya version is flipped (!!) #if !defined( MAX3D ) && !defined( XSI_SOFT3D_ONLY ) h->hv[14] = Dv[Dface_start[h->pid]]; // fix the ends h->hv[0] = Dv[Dface_end[h->pid] - 1]; #else h->hv[0] = Dv[Dface_start[h->pid]]; // fix the ends h->hv[14] = Dv[Dface_end[h->pid] - 1]; #endif for( x = 0; x < 15; x++ ) // invert the faces lowpoly[14 - x] = h->hv[x]; for( x = 0; x < 15; x++ ) h->hv[x] = lowpoly[x]; h->mtl = splines; if( h->pid >= 0 ) if( h->pid < Dtotalfaces ) h->vid = Dfacelist[Dface_start[h->pid]]; // h->vid = find_closest_vert( h->hv[0] ); // h->vid=Dfacelist[Dface_start[h->pid]]; // h->restlength=td; h->restlength=VdistanceK(h->hv[0],h->hv[1]); } void extract_chainSP( BASEHAIR * h, int base ) { VERT lowpoly[255]; VERT highpoly[520]; int tv = 0; int lastv; int thisv; float td; int uc; int x; // get the face h->pid = h->pid - base; // lowpoly[tv]=v[facelistSP[face_endSP[h->pid]-1]]; // tv++; //printf ("extract_chainSP sliders[8][%d]=%f\n",h->mtl,sliders[8][h->mtl].value); if (0==1) if( sliders[8][4].value == 1.0 ) { float tvv; float inc; float q; tv = face_end[h->pid] - face_start[h->pid]; tvv = ( float ) tv; inc = tvv / 15.0f; for( q = 0; q < tvv; q += inc ) { int qq; int a, b, c, d; float u; // VERT aa,bb,cc,dd; qq = ( int ) floor( q ); u = q - floor( q ); a = qq - 1; b = qq; c = qq + 1; d = qq + 2; if( a < 0 ) a = 0; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; a = facelist[a + face_start[h->pid]]; b = facelist[b + face_start[h->pid]]; c = facelist[c + face_start[h->pid]]; d = facelist[d + face_start[h->pid]]; { h->hv[qq].x = spline( v[a].x, v[b].x, v[c].x, v[d].x, u ); h->hv[qq].y = spline( v[a].y, v[b].y, v[c].y, v[d].y, u ); h->hv[qq].z = spline( v[a].z, v[b].z, v[c].z, v[d].z, u ); } } } //if( sliders[8][4].value != 1.0 ) { for( x = face_endSP[h->pid] - 1; x >= face_startSP[h->pid]; x-- ) { lowpoly[tv] = v[facelistSP[x]]; tv++; } //lowpoly[tv]=v[facelistSP[face_startSP[h->pid]]]; // tv++; // add an extra one for good measure uc = 0; for( x = 0; x < tv; x++ ) { int a, b, c, d; float u; // VERT aa,bb,cc,dd; a = x - 1; b = x; c = x + 1; d = x + 2; if( a < 0 ) a = 0; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; if( b > tv - 1 ) b = tv - 1; if( a > tv - 1 ) a = tv - 1; for( u = 0; u < 1.0f; u += ( ( float ) tv / 500.0 ) ) { // char tmp[255]; highpoly[uc].x = spline( lowpoly[a].x, lowpoly[b].x, lowpoly[c].x, lowpoly[d].x, u ); highpoly[uc].y = spline( lowpoly[a].y, lowpoly[b].y, lowpoly[c].y, lowpoly[d].y, u ); highpoly[uc].z = spline( lowpoly[a].z, lowpoly[b].z, lowpoly[c].z, lowpoly[d].z, u ); // sprintf(tmp,"x = %d uc = %d %f %f %f",x,uc,highpoly[uc].x,highpoly[uc].y,highpoly[uc].z); // DRAW_STATUS(tmp); uc++; } } td = 0; for( x = 0; x < 500 - 1; x++ ) { td += Distance( highpoly[x], highpoly[x + 1] ); } td /= 15.0f; // (was /=14.0) this is the distance increment per seg // h->restlength=td; h->hv[0] = highpoly[0]; lastv = 0; thisv = 1; for( x = 1; x < 15; x++ ) { if( td > 0.0f ) { while( ( Distance( highpoly[lastv], highpoly[thisv] ) < td ) && ( thisv < 600 ) ) { thisv++; } h->hv[x] = highpoly[thisv]; } else h->hv[x] = highpoly[0]; lastv = thisv; } h->mtl = splines; h->hv[0] = v[facelist[face_start[h->pid]]]; for( x = 1; x < 15; x++ ) h->noisev[x] = h->hv[x]; h->vid = find_closest_vert( h->hv[0] ); } //h->restlength=Distance(h->hv[1],h->hv[2]); } void free_splines( void ) { if (total_splines>0) { // if (Shair) free( Shair ); // if (Sresthair) free( Sresthair ); // if (Shairvelocity) free( Shairvelocity ); // if (Sthishair) free( Sthishair ); // if (Slasthair) free( Slasthair ); // if (splinelist) free( splinelist ); } //#ifdef NOLIB //#endif Shair = NULL; Sresthair = NULL; Shairvelocity = NULL; Slasthair = NULL; Sthishair = NULL; splinelist = NULL; total_splines = 0; } void init_splines( void ) { //#ifdef NOLIB //#endif Shair = NULL; Sresthair = NULL; Shairvelocity = NULL; Slasthair = NULL; Sthishair = NULL; splinelist = NULL; total_splines = 0; } void alloc_splines( int n ) { int x, y; if( n > 0 ) { n += 2; // char tmp[255]; splinelist = ( int * ) malloc( n * sizeof( int ) ); //#ifdef NOLIB Shair = ( BASEHAIR * ) malloc( n * sizeof( BASEHAIR ) ); Sresthair = ( BASEHAIR * ) malloc( n * sizeof( BASEHAIR ) ); Sthishair = ( BASEHAIR * ) malloc( n * sizeof( BASEHAIR ) ); Slasthair = ( BASEHAIR * ) malloc( n * sizeof( BASEHAIR ) ); Shairvelocity = ( BASEHAIR * ) malloc( n * sizeof( BASEHAIR ) ); if( Shairvelocity == NULL ) { Glow_mem = 1; n = 0; total_splines = 0; free_splines( ); Dfreeverts( ); freeverts( ); } for( x = 0; x < n; x++ ) for( y = 0; y < 60; y++ ) { Shair[x].slider[y] = 1.0f; Sresthair[x].slider[y] = 1.0f; Sthishair[x].slider[y] = 1.0f; Slasthair[x].slider[y] = 1.0f; } for( x = 0; x < n; x++ ) { Shair[x].hide = 0; Sresthair[x].hide = 0; Sthishair[x].hide = 0; Slasthair[x].hide = 0; Sresthair[x].vid = 0; Sthishair[x].vid = 0; Slasthair[x].vid = 0; Shair[x].vid = 0; Shair[x].pid = 0; Shair[x].splitgroup = 0; Shair[x].splitmerge = 0; Sresthair[x].pid = 0; Sthishair[x].pid = 0; Slasthair[x].pid = 0; Shair[x].slgroup = 0; Sthishair[x].slgroup = 0; Slasthair[x].slgroup = 0; Sresthair[x].slgroup = 0; Shair[x].restlength = 0.0f; Sthishair[x].restlength = 0.0f; Sresthair[x].restlength = 0.0f; Slasthair[x].restlength = 0.0f; Sresthair[x].mtl = 0; Shair[x].mtl = 0; Sresthair[x].mtl = 0; Sthishair[x].mtl = 0; Slasthair[x].mtl = 0; Sresthair[x].norm.x = 0; Sresthair[x].norm.y = 1.0f; Sresthair[x].norm.z = 0; Shair[x].norm.x = 0; Shair[x].norm.y = 1.0f; Shair[x].norm.z = 0; Sthishair[x].norm.x = 0; Sthishair[x].norm.y = 1.0f; Sthishair[x].norm.z = 0; Slasthair[x].norm.x = 0; Slasthair[x].norm.y = 1.0f; Slasthair[x].norm.z = 0; for( y = 0; y < 15; y++ ) { Shair[x].pfID[y] = -1; Shair[x].select[y] = 1; Sresthair[x].pfID[y] = -1; Sresthair[x].select[y] = 1; Sresthair[x].color[y].x = 0.0f; Sresthair[x].color[y].y = 0.0f; Sresthair[x].color[y].z = 0.0f; Sresthair[x].velocity[y].x = 0.0f; Sresthair[x].velocity[y].y = 0.0f; Sresthair[x].velocity[y].z = 0.0f; Sresthair[x].resthv[y].x = 0.0f; Sresthair[x].resthv[y].y = 0.0f; Sresthair[x].resthv[y].z = 0.0f; Sresthair[x].hv[y].x = 0.0f; Sresthair[x].hv[y].y = 0.0f; Sresthair[x].hv[y].z = 0.0f; Sresthair[x].noisev[y].x = 0.0f; Sresthair[x].noisev[y].y = 0.0f; Sresthair[x].noisev[y].z = 0.0f; Shair[x].color[y].x = 0.0f; Shair[x].color[y].y = 0.0f; Shair[x].color[y].z = 0.0f; Shair[x].velocity[y].x = 0.0f; Shair[x].velocity[y].y = 0.0f; Shair[x].velocity[y].z = 0.0f; Shair[x].resthv[y].x = 0.0f; Shair[x].resthv[y].y = 0.0f; Shair[x].resthv[y].z = 0.0f; Shair[x].hv[y].x = 0.0f; Shair[x].hv[y].y = 0.0f; Shair[x].hv[y].z = 0.0f; Shair[x].noisev[y].x = 0.0f; Shair[x].noisev[y].y = 0.0f; Shair[x].noisev[y].z = 0.0f; Sthishair[x].color[y].x = 0.0f; Sthishair[x].color[y].y = 0.0f; Sthishair[x].color[y].z = 0.0f; Sthishair[x].velocity[y].x = 0.0f; Sthishair[x].velocity[y].y = 0.0f; Sthishair[x].velocity[y].z = 0.0f; Sthishair[x].resthv[y].x = 0.0f; Sthishair[x].resthv[y].y = 0.0f; Sthishair[x].resthv[y].z = 0.0f; Sthishair[x].hv[y].x = 0.0f; Sthishair[x].hv[y].y = 0.0f; Sthishair[x].hv[y].z = 0.0f; Slasthair[x].color[y].x = 0.0f; Slasthair[x].color[y].y = 0.0f; Slasthair[x].color[y].z = 0.0f; Slasthair[x].velocity[y].x = 0.0f; Slasthair[x].velocity[y].y = 0.0f; Slasthair[x].velocity[y].z = 0.0f; Slasthair[x].resthv[y].x = 0.0f; Slasthair[x].resthv[y].y = 0.0f; Slasthair[x].resthv[y].z = 0.0f; Slasthair[x].hv[y].x = 0.0f; Slasthair[x].hv[y].y = 0.0f; Slasthair[x].hv[y].z = 0.0f; } for( y = 0; y < 15; y++ ) { Shair[x].pfID[y] = -1; Sresthair[x].pfID[y] = -1; Shair[x].select[y] = 1; Sresthair[x].select[y] = 1; } Shair[x].select[14] = 1; } for( x = 0; x < n; x++ ) Slasthair[x].uu = 0.0f; for( x = 0; x < n; x++ ) Slasthair[x].vv = 0.0f; for( x = 0; x < n; x++ ) Shair[x].uu = 0.0f; for( x = 0; x < n; x++ ) Shair[x].vv = 0.0f; for( x = 0; x < n; x++ ) Sthishair[x].uu = 0.0f; for( x = 0; x < n; x++ ) Sthishair[x].vv = 0.0f; for( x = 0; x < n; x++ ) Sresthair[x].uu = 0.0f; for( x = 0; x < n; x++ ) Sresthair[x].vv = 0.0f; for( x = 0; x < n; x++ ) Sresthair[x].splitgroup = 0; for( x = 0; x < n; x++ ) Shair[x].splitgroup = 0; for( x = 0; x < n; x++ ) Sthishair[x].splitgroup = 0; for( x = 0; x < n; x++ ) Slasthair[x].splitgroup = 0; for( x = 0; x < n; x++ ) Shair[x].splitmerge = 0; for( x = 0; x < n; x++ ) Sresthair[x].splitmerge = 0; for( x = 0; x < n; x++ ) Sthishair[x].splitmerge = 0; for( x = 0; x < n; x++ ) Slasthair[x].splitmerge = 0; for( x = 0; x < n; x++ ) Shair[x].hide = 0; } } void make_splines( void ) { int x; int old_total = 0; free_splines( ); Dregroup( ); DRAW_STATUS( "Making spline faces" ); DRAW_STATUS( "Making splines" ); // make the splinelist for( x = 0; x < Dtotalfaces; x++ ) { if( Dmtlgroup[x] >= 0 ) if( Dmtlgroup[x] == splines ) { total_splines++; } } DRAW_STATUS( "Allocating spline space" ); if( total_splines > 1 ) { alloc_splines( total_splines ); total_splines = 0; // first do the faces DRAW_STATUS( "Extracting spline chains" ); for( x = 0; x < Dtotalfaces; x++ ) { if( splines >= 0 ) if( Dmtlgroup[x] == splines ) { splinelist[total_splines] = x; total_splines++; } } for( x = 0; x < total_splines; x++ ) { Shair[x].pid = splinelist[x]; //if (Grendermode==0) extract_chain( &Shair[x] ); //else // Shair[x].vid=find_closest_vert(Shair[x].hv[0]); Shair[x].slgroup = 4; Shair[x].mtl = splines; //if (Grendermode==0) // Shair[x].restlength=Distance(Shair[x].hv[1],Shair[x].hv[2]); if( RW_CONTEXT != RW_LOCAL ) { Sthishair[x] = Shair[x]; Slasthair[x] = Shair[x]; Sresthair[x] = Shair[x]; } } DRAW_STATUS( "Extracting poly chains" ); DRAW_STATUS( "done with poly chains" ); } //initbounds(); } float smoothstep( float in ) { float ret; ret = 1.0f - ( ( COST[( int ) ( in * 314.15 /*9 */ )] + 1.0 ) / 2.0 ); return ( ret ); } VERT clump; void Stagverts( void ) { int x; int y; int SHIFT = 0; int totalt = 0; int gotone = 0; float lowest_dist = 1000000; int closest_vert = 1; float dx, dy, d, sz; VERT p, s, p1; float WX, WY, asp; // clear selection // scrmask((int)(55.0),(int)(580.0f-1),(int)(45.0),(int)(570.0f-1)); /* find the closest vertex */ WX = work2.x - work1.x; WY = work2.y - work1.y; asp = ( WX / WY ); s.x = sculpt.x - work1.x; s.y = sculpt.y - work1.y; s.x /= ( WX ); s.y /= ( WY ); s.x *= 2.0 * asp; s.y *= 2.0f; s.x -= 1.0 * asp; s.y -= 1.0f; sz = sculpt.z; sz /= ( SXRES ); sz *= 2 * asp; if( paintmode < 0 ) for( x = 0; x < total_splines; x++ ) for( y = 1; y < 15; y++ ) if( Shair[x].hide == 0 ) // if( group_stat[Shair[x].mtl] == 0 ) // if( group_enable[Shair[x].mtl] ) { p1.x = ( Shair[x].hv[y].x + cam_panx ) * cam_scale; p1.y = ( Shair[x].hv[y].y + cam_pany ) * cam_scale; p1.z = ( Shair[x].hv[y].z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); d = sqrt( dx * dx + dy * dy ); if( d < sz ) { gotone = 1; if( selmode == ROOTS ) if( y == 1 ) { int yy; if( ( Gaddsub == 1 ) || ( Gaddsub == 0 ) ) Shair[x].select[0] = 1; if( Gaddsub == 2 ) Shair[x].select[0] = 0; for( yy = 1; yy < 15; yy++ ) Shair[x].select[yy] = Shair[x].select[0]; } if( selmode == STRANDS ) { int yy; if( ( Gaddsub == 1 ) || ( Gaddsub == 0 ) ) Shair[x].select[0] = 1; if( Gaddsub == 2 ) Shair[x].select[0] = 0; for( yy = 1; yy < 15; yy++ ) Shair[x].select[yy] = Shair[x].select[0]; } if( selmode == ENDS ) { int tp; tp = addsub; { int yy; // if( addsub == 0 ) for( yy = 0; yy < 15; yy++ ) Shair[x].select[yy] = 0; if( Gaddsub != 2 ) { Shair[x].select[14] = 1; Shair[x].select[0] = 1; } } } if( selmode == VERTS ) { int tp; tp = ( int ) Shair[x].select[y]; { int qq, tt = 0; if( Gaddsub == 2 ) if( y != 0 ) Shair[x].select[y] = 0; if( Gaddsub != 2 ) if( y != 0 ) Shair[x].select[y] = 1; for( qq = 1; qq < 15; qq++ ) { tt += ( int ) Shair[x].select[qq]; } if( tt > 0 ) Shair[x].select[0] = 1; if( tt == 0 ) Shair[x].select[0] = 0; // hair[x].select[0]=addsub; } } } } for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Sresthair[x].select[y] = Shair[x].select[y]; // G_center_select=closest_vert; } void brushtagverts( void ) { int x; int y; int SHIFT = 0; int totalt = 0; int gotone = 0; float lowest_dist = 1000000; int closest_vert = 1; float dx, dy, d, sz; VERT p, s, p1; float WX, WY, asp; // setmainwin(); // Gget_depth=1; // drawmodel(); // Gget_depth=0; // clear selection // scrmask((int)(55.0),(int)(580.0f-1),(int)(45.0),(int)(570.0f-1)); /* find the closest vertex */ WX = work2.x - work1.x; WY = work2.y - work1.y; asp = ( WX / WY ); s.x = sculpt.x - work1.x; s.y = sculpt.y - work1.y; s.x /= ( WX ); s.y /= ( WY ); s.x *= 2.0 * asp; s.y *= 2.0f; s.x -= 1.0 * asp; s.y -= 1.0f; sz = sculpt.z; sz /= ( SXRES ); sz *= 2 * asp; { for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) hair[x].w[y] = 0.0f; for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Shair[x].w[y] = 0.0f; // addsub=0; // SHIFT= (GetAsyncKeyState(VK_SHIFT)&32768); // if (SHIFT) addsub=1; if( paintmode < 0 ) for( x = 0; x < totalverts; x++ ) { hair[x].w[0] = 0.0f; for( y = 1; y < 15; y++ ) if( hair[x].hide == 0 ) if( group_stat[hair[x].mtl] == 0 ) if( group_enable[hair[x].mtl] ) if( ( hair[x].mtl == head ) || ( hair[x].mtl == eyelash ) || ( hair[x].mtl == eyebrow ) || ( hair[x].mtl == beard ) ) if( hair[x].select[y] ) { /// if (Gcamdirty) { p1.x = ( hair[x].hv[y].x + cam_panx ) * cam_scale; p1.y = ( hair[x].hv[y].y + cam_pany ) * cam_scale; p1.z = ( hair[x].hv[y].z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); hair[x].velocity[y] = p; } // else // p=hair[x].sparevelocity[y]; // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); // d=sqrt(dx*dx+dy*dy); d = dx * dx + dy * dy; if( d < sz * sz ) { float mlt = 1.0f; // if (check_depth(hair[x].hv[y])==0) mlt=0.0f; // d=sqrt(d); hair[x].w[y] = ( 1.0f - ( ( float ) d / ( float ) ( sz * sz ) ) ); if( hair[x].w[0] < hair[x].w[y] ) hair[x].w[0] = hair[x].w[y]; } else { hair[x].w[y] = 0.0f; hair[x].w[0] = 0.0f; } } } // addsub=0; // SHIFT= (GetAsyncKeyState(VK_SHIFT)&32768); // if (SHIFT) addsub=1; if( paintmode < 0 ) for( x = 0; x < total_splines; x++ ) { Shair[x].w[0] = 0.0f; for( y = 1; y < 15; y++ ) if( Shair[x].hide == 0 ) // if( group_enable[Shair[x].mtl] ) if( Shair[x].select[y] ) { /// if (Gcamdirty) { p1.x = ( Shair[x].hv[y].x + cam_panx ) * cam_scale; p1.y = ( Shair[x].hv[y].y + cam_pany ) * cam_scale; p1.z = ( Shair[x].hv[y].z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); Shair[x].velocity[y] = p; } // else // p=Shair[x].sparevelocity[y]; // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); // d=sqrt(dx*dx+dy*dy); d = dx * dx + dy * dy; if( d < sz * sz ) { float mlt = 1.0f; // if (check_depth(Shair[x].hv[y])==0) mlt=0.0f; // d=sqrt(d); Shair[x].w[y] = ( 1.0f - ( ( float ) d / ( float ) ( sz * sz ) ) ); if( Shair[x].w[0] < Shair[x].w[y] ) Shair[x].w[0] = Shair[x].w[y]; } else { Shair[x].w[y] = 0.0f; Shair[x].w[0] = 0.0f; } } } } Gcamdirty = 0; for( x = 0; x < totalverts; x++ ) { int qq; hair[x].w[0] = 0.0f; for( qq = 0; qq < 15; qq++ ) { if( hair[x].w[qq] > hair[x].w[0] ) hair[x].w[0] = hair[x].w[qq]; } } for( x = 0; x < total_splines; x++ ) { int qq; Shair[x].w[0] = 0.0f; for( qq = 0; qq < 15; qq++ ) { if( Shair[x].w[qq] > Shair[x].w[0] ) Shair[x].w[0] = Shair[x].w[qq]; } } for( x = 0; x < totalverts; x++ ) { float sm; sm = 14.0f; if( hair[x].w[0] ) // it's in the brush { float q; for( y = 1; y < 14; y++ ) if( hair[x].w[y] > 0 ) if( y < sm ) sm = y; if( sm < 14 ) for( q = sm - 1; q < sm; q += .02f ) { VERT p2; float ww; ww = q - ( sm - 1 ); p2.x = hair[x].hv[( int ) ( sm - 1 )].x * ( 1.0f - ww ) + hair[x].hv[( int ) sm].x * ( ww ); p2.y = hair[x].hv[( int ) ( sm - 1 )].y * ( 1.0f - ww ) + hair[x].hv[( int ) sm].y * ( ww ); p2.z = hair[x].hv[( int ) ( sm - 1 )].z * ( 1.0f - ww ) + hair[x].hv[( int ) sm].z * ( ww ); p1.x = ( p2.x + cam_panx ) * cam_scale; p1.y = ( p2.y + cam_pany ) * cam_scale; p1.z = ( p2.z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); d = sqrt( dx * dx + dy * dy ); if( d < sz ) if( ( ( sm - 1 ) + ww ) < hair[x].trim ) { hair[x].trim = ( sm - 1 ) + ww; // thishair[x].trim=(sm-1)+ww; // lasthair[x].trim=(sm-1)+ww; // resthair[x].trim=(sm-1)+ww; } } } } // x for( x = 0; x < total_splines; x++ ) { float sm; sm = 14.0f; if( Shair[x].w[0] ) // it's in the brush { float q; for( y = 1; y < 14; y++ ) if( Shair[x].w[y] > 0 ) if( y < sm ) sm = y; if( sm < 14 ) for( q = sm - 1; q < sm; q += .02f ) { VERT p2; float ww; ww = q - ( sm - 1 ); p2.x = Shair[x].hv[( int ) ( sm - 1 )].x * ( 1.0f - ww ) + Shair[x].hv[( int ) sm].x * ( ww ); p2.y = Shair[x].hv[( int ) ( sm - 1 )].y * ( 1.0f - ww ) + Shair[x].hv[( int ) sm].y * ( ww ); p2.z = Shair[x].hv[( int ) ( sm - 1 )].z * ( 1.0f - ww ) + Shair[x].hv[( int ) sm].z * ( ww ); p1.x = ( p2.x + cam_panx ) * cam_scale; p1.y = ( p2.y + cam_pany ) * cam_scale; p1.z = ( p2.z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); d = sqrt( dx * dx + dy * dy ); if( d < sz ) if( ( ( sm - 1 ) + ww ) < Shair[x].trim ) { Shair[x].trim = ( sm - 1 ) + ww; // thishair[x].trim=(sm-1)+ww; // lasthair[x].trim=(sm-1)+ww; // resthair[x].trim=(sm-1)+ww; } } } } // x for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) Sresthair[x].w[y] = Shair[x].w[y]; for( x = 0; x < total_splines; x++ ) Sresthair[x].trim = Shair[x].trim; } void tagverts( void ) { int x; int y; int SHIFT = 0; int totalt = 0; int gotone = 0; float lowest_dist = 1000000; int closest_vert = 1; float dx, dy, d, sz; VERT p, s, p1; float WX, WY, asp; // clear selection // scrmask((int)(55.0),(int)(580.0f-1),(int)(45.0),(int)(570.0f-1)); /* find the closest vertex */ // WX=580-800+SXRES; Gcamdirty = 1; WX = work2.x - work1.x; WY = work2.y - work1.y; asp = ( WX / WY ); s.x = sculpt.x - work1.x; s.y = sculpt.y - work1.y; s.x /= ( WX ); s.y /= ( WY ); s.x *= 2.0 * asp; s.y *= 2.0f; s.x -= 1.0 * asp; s.y -= 1.0f; sz = sculpt.z; sz /= ( SXRES ); sz *= 2 * asp; // addsub=0; add_undo( ); // SHIFT= (GetAsyncKeyState(VK_SHIFT)&32768); // if (SHIFT) addsub=1; if( paintmode < 0 ) for( x = 0; x < totalverts; x++ ) for( y = 1; y < 15; y++ ) if( hair[x].hide == 0 ) if( group_stat[hair[x].mtl] == 0 ) if( group_enable[hair[x].mtl] ) if( ( hair[x].mtl == head ) || ( hair[x].mtl == eyelash ) || ( hair[x].mtl == eyebrow ) || ( hair[x].mtl == beard ) ) { p1.x = ( hair[x].hv[y].x + cam_panx ) * cam_scale; p1.y = ( hair[x].hv[y].y + cam_pany ) * cam_scale; p1.z = ( hair[x].hv[y].z + cam_panz ) * cam_scale; p = vxm( CamMatrix, p1 ); // n=vxm(CamMatrix,vn[x]); dx = ( p.x - s.x ); dy = ( p.y - s.y ); d = sqrt( dx * dx + dy * dy ); if( d < sz ) { gotone = 1; if( selmode == ROOTS ) if( y == 1 ) { int yy; // int tp; if( Gaddsub != 2 ) hair[x].select[0] = 1; else hair[x].select[0] = 0; for( yy = 1; yy < 15; yy++ ) hair[x].select[yy] = hair[x].select[0]; } if( selmode == STRANDS ) { int yy; // int tp; if( Gaddsub != 2 ) hair[x].select[0] = 1; else hair[x].select[0] = 0; for( yy = 1; yy < 15; yy++ ) hair[x].select[yy] = hair[x].select[0]; } if( selmode == ENDS ) { int tp; tp = addsub; { int yy; if( Gaddsub == 2 ) for( yy = 0; yy < 15; yy++ ) hair[x].select[yy] = 0; if( Gaddsub != 2 ) hair[x].select[14] = 1; hair[x].select[0] = hair[x].select[14]; } } if( selmode == VERTS ) { int tp; tp = ( int ) hair[x].select[y]; { int qq, tt = 0; if( Gaddsub != 2 ) if( y != 0 ) hair[x].select[y] = 1; if( Gaddsub == 2 ) if( y != 0 ) hair[x].select[y] = 0; for( qq = 1; qq < 15; qq++ ) { tt += ( int ) hair[x].select[qq]; } if( tt > 0 ) hair[x].select[0] = 1; if( tt == 0 ) hair[x].select[0] = 0; // hair[x].select[0]=addsub; } } } } // G_center_select=closest_vert; Stagverts( ); } #ifndef _WIN32 #define POINT VERT #endif void mk_geom( WFTYPE * h1, WFTYPE * h2, WFTYPE * h3, WFTYPE * h4, WFTYPE * geom, int segs ) { float t1[4], t2[4]; int x, y; segs = h1->totalverts; //WFTYPE hh[3]; //hh[0].totalverts=0; //hh[1].totalverts=0;; //hh[2].totalverts=0; //resize_render_hair(h1,&hh[0],segs); //resize_render_hair(h2,&hh[1],segs); //resize_render_hair(h3,&hh[2],segs); free_geomWF( geom ); geom->totalverts = ( segs + 1 ) * 4 + 4; geom->totalfaces = ( segs + 1 ) * 4 + 4; geom->totalfverts = ( segs + 3 ) * 4 * 5; alloc_geomWF( geom ); geom->totalverts = 0; geom->totalfaces = 0; geom->totalfverts = 0; for( x = 0; x < h1->totalverts; x++ ) { geom->uv[x] = h1->uv[x]; geom->v[x] = h1->v[x]; geom->v[x].z = -geom->v[x].z; geom->color[x] = h1->color[x]; geom->velocity[x] = h1->velocity[x]; geom->velocity[x].z *= -1.0f; geom->uv[x + segs] = h2->uv[x]; geom->v[x + segs] = h2->v[x]; geom->v[x + segs].z = -geom->v[x + segs].z; geom->velocity[x + segs] = h2->velocity[x]; geom->velocity[x + segs].z *= -1.0f; geom->color[x + segs] = h2->color[x]; geom->uv[x + segs + segs] = h3->uv[x]; geom->v[x + segs + segs] = h3->v[x]; geom->v[x + segs + segs].z = -geom->v[x + segs + segs].z; geom->velocity[x + segs + segs] = h3->velocity[x]; geom->velocity[x + segs + segs].z *= -1.0f; geom->color[x + segs + segs] = h3->color[x]; geom->uv[x + segs + segs + segs] = h4->uv[x]; geom->v[x + segs + segs + segs] = h4->v[x]; geom->v[x + segs + segs + segs].z = -geom->v[x + segs + segs + segs].z; geom->velocity[x + segs + segs + segs] = h4->velocity[x]; geom->velocity[x + segs + segs + segs].z *= -1.0f; geom->color[x + segs + segs + segs] = h4->color[x]; geom->totalverts += 4; } for( y = 0; y < segs - 1; y++ ) { t1[0] = y + 0; t1[1] = y + 1 * segs + 0; t1[2] = y + 1 * segs + 1 * segs + 0; t1[3] = y + 1 * segs + 1 * segs + 1 * segs + 0; t2[0] = y + 1 + 0; t2[1] = y + 1 + 1 * segs + 0; t2[2] = y + 1 + 1 * segs + 1 * segs + 0; t2[3] = y + 1 + 1 * segs + 1 * segs + 1 * segs + 0; geom->face_start[geom->totalfaces] = geom->totalfverts; geom->facelist[geom->totalfverts] = ( int ) t1[0]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t1[1]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[1]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[0]; geom->totalfverts++; geom->face_end[geom->totalfaces] = geom->totalfverts; geom->totalfaces++; geom->face_start[geom->totalfaces] = geom->totalfverts; geom->facelist[geom->totalfverts] = ( int ) t1[1]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t1[2]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[2]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[1]; geom->totalfverts++; geom->face_end[geom->totalfaces] = geom->totalfverts; geom->totalfaces++; geom->face_start[geom->totalfaces] = geom->totalfverts; geom->facelist[geom->totalfverts] = ( int ) t1[2]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t1[3]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[3]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[2]; geom->totalfverts++; geom->face_end[geom->totalfaces] = geom->totalfverts; geom->totalfaces++; geom->face_start[geom->totalfaces] = geom->totalfverts; geom->facelist[geom->totalfverts] = ( int ) t1[3]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t1[0]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[0]; geom->totalfverts++; geom->facelist[geom->totalfverts] = ( int ) t2[3]; geom->totalfverts++; geom->face_end[geom->totalfaces] = geom->totalfverts; geom->totalfaces++; } #ifdef DUMPIT for( x = 0; x < geom->totalfaces; x++ ) { printf( "\n" ); for( y = geom->face_start[x]; y < geom->face_end[x]; y++ ) printf( "%d ", geom->facelist[y] ); } #endif // free_geomWF(&hh[0]); // free_geomWF(&hh[1]); // free_geomWF(&hh[2]); } void resize_render_hair( RENDERHAIR * h, WFTYPE * ft, int segs ) { //int y; float u, uu; int add; int a, b, c, d; free_geomWF( ft ); ft->totalverts = segs + 1; ft->totalfaces = 1; ft->totalfverts = segs + 1; alloc_geomWF( ft ); ft->totalverts = 0; //ft->mtlgroup[0]=h->slgroup; for( u = 0.0f; u < 1.0f; u += ( ( float ) 1.0 / ( float ) segs ) ) { add = ( int ) ft->totalverts; a = ( ( int ) floor( u * ( float ) 55.0 ) ) - 1; b = ( ( int ) floor( u * ( float ) 55.0 ) ); c = ( ( int ) floor( u * ( float ) 55.0 ) ) + 1; d = ( ( int ) floor( u * ( float ) 55.0 ) ) + 2; if( a < 0 ) a = 0; if( c > 54 ) c = 54; if( d > 54 ) d = 54; uu = u * ( float ) 54.0f - floor( u * ( float ) 54.0 ); ft->v[add].x = spline( h->hv[a].x, h->hv[b].x, h->hv[c].x, h->hv[d].x, uu ); ft->v[add].y = spline( h->hv[a].y, h->hv[b].y, h->hv[c].y, h->hv[d].y, uu ); ft->v[add].z = spline( h->hv[a].z, h->hv[b].z, h->hv[c].z, h->hv[d].z, uu ); ft->color[add].x = spline( h->color[a].x, h->color[b].x, h->color[c].x, h->color[d].x, uu ); ft->color[add].y = spline( h->color[a].y, h->color[b].y, h->color[c].y, h->color[d].y, uu ); ft->color[add].z = spline( h->color[a].z, h->color[b].z, h->color[c].z, h->color[d].z, uu ); ft->totalverts++; } ft->totalfaces = 1; } void resize_base_hair( BASEHAIR * h, WFTYPE * ft, CURVEINFO * cinfo, int segs ) { //int x,y; float u, uu; int add; int x; int a, b, c, d; float inc; // if( segs < 1 ) // segs = 1; // segs+=1; free_geomWF( ft ); if (segs!=0) { ft->totalverts = segs + 12; ft->totalfaces = 1; ft->totalfverts = segs + 12; alloc_geomWF( ft ); ft->totalverts = 0; ft->totalfverts = 0; ft->index[0]=h->index; //ft->mtlgroup[0]=h->slgroup; if (h->cutlength>1.0f) h->cutlength=1.0f; if (h->cutlength<0.0f) h->cutlength=0.0f; //h->cutlength=1.0f; inc = h->cutlength / ( float ) ( segs ); // // It's possible that h->cutlength is non-zero, but is such a small number // that dividing it by 'segs' is too small to be represented in a float, // resulting in 'inc' being set to zero in the above assignment. // // If that's the case, then we should really treat h->cutlength as if it // was zero. // if( inc <= 0.0f ) h->cutlength = 0.0f; //h->cutlength=1.0f; // if( ( ( segs == 14 ) && ( h->cutlength == 1.0f ) ) ) // for( x = 0; x < 14 + 1; x++ ) // { // ft->v[x] = h->hv[x]; // ft->uv[x].x = h->uu; // ft->uv[x].y = h->vv; // ft->uv[x].z = ( float ) x / 14.0f; // ft->velocity[x] = h->velocity[x]; // ft->color[x] = h->color[x]; // ft->totalverts = 15; // ft->totalfverts = 15; // ft->totalfaces = 1; ////ft->uv[x]= // } // if( !( ( segs == 14 ) && ( h->cutlength == 1.0f ) ) ) // if( h->cutlength > 0 ) // for( u = 0.0f; u < h->cutlength + inc / 4.0f; u += inc ) if (h->cutlength>0.0f) { for( u = 0.0f; u < 1.0f + 1.0f/(float)segs; u += 1.0f/(float)segs ) { VERT *aa, *bb, *cc, *dd, *out; float uu; uu=u; add = ( int ) ft->totalverts; uu=u*h->cutlength; if( uu > 1.0f ) uu = 1.0f; a = ( ( int ) floor( uu * 14.0f ) ) - 1; b = ( ( int ) floor( uu * 14.0f ) ); c = ( ( int ) floor( uu * 14.0f ) ) + 1; d = ( ( int ) floor( uu * 14.0f ) ) + 2; if( a < 0 ) a = 0; if( a > 14 ) a = 14; if( b > 14 ) b = 14; if( c > 14 ) c = 14; if( d > 14 ) d = 14; uu = (uu * 14.0f) - floor( uu * 14.0f ); if( uu > 0.99999f ) uu = 0.99999f; out = &ft->uv[add]; out->x = h->uu; out->y = h->vv; out->z = u; out = &ft->v[add]; aa = &h->hv[a]; bb = &h->hv[b]; cc = &h->hv[c]; dd = &h->hv[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); out = &ft->color[add]; aa = &h->color[a]; bb = &h->color[b]; cc = &h->color[c]; dd = &h->color[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); out = &ft->velocity[add]; aa = &h->velocity[a]; bb = &h->velocity[b]; cc = &h->velocity[c]; dd = &h->velocity[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); // ft->color[add].x=spline(h->color[a].x,h->color[b].x,h->color[c].x,h->color[d].x,uu); // ft->color[add].y=spline(h->color[a].y,h->color[b].y,h->color[c].y,h->color[d].y,uu); // ft->color[add].z=spline(h->color[a].z,h->color[b].z,h->color[c].z,h->color[d].z,uu); // ft->velocity[add].x=spline(h->velocity[a].x,h->velocity[b].x,h->velocity[c].x,h->velocity[d].x,uu); // ft->velocity[add].y=spline(h->velocity[a].y,h->velocity[b].y,h->velocity[c].y,h->velocity[d].y,uu); // ft->velocity[add].z=spline(h->velocity[a].z,h->velocity[b].z,h->velocity[c].z,h->velocity[d].z,uu); ft->totalverts++; ft->totalfverts++; } } else { if (segs!=0) for (x=0;xv[x] = h->hv[0]; ft->uv[x].x = h->uu; ft->uv[x].y = h->vv; ft->uv[x].z = 0; ft->color[x] = h->color[0]; ft->velocity[x] = h->velocity[0]; ft->totalverts++; ft->totalfverts++; cinfo->killme = 1; } } } if (segs==0) { x=0; { ft->v[x] = h->hv[0]; ft->uv[x].x = h->uu; ft->uv[x].y = h->vv; ft->uv[x].z = 0; ft->color[x] = h->color[0]; ft->velocity[x] = h->velocity[0]; ft->totalverts++; ft->totalfverts++; cinfo->killme = 1; } } ft->totalfaces = 1; } void resize_base_hair_to_newguide( BASEHAIR * h, NEWGUIDES * ft, int segs ) { //int x,y; float u, uu; int add; int x; int a, b, c, d; float inc; // if( segs < 1 ) // segs = 1; // segs+=1; if (segs>2) { // if (h->cutlength>0.0f) { int tt=0; // for( u = 0.0f; u < 1.0f + 1.0f/(float)segs; u += 1.0f/(float)segs ) for( u = 0.0f; u < 1.0f ; u += 1.0f/(float)segs ) if (tt 1.0f ) uu = 1.0f; a = ( ( int ) floor( uu * 14.0f ) ) - 1; b = ( ( int ) floor( uu * 14.0f ) ); c = ( ( int ) floor( uu * 14.0f ) ) + 1; d = ( ( int ) floor( uu * 14.0f ) ) + 2; if( a < 0 ) a = 0; if( a > 14 ) a = 14; if( b > 14 ) b = 14; if( c > 14 ) c = 14; if( d > 14 ) d = 14; uu = (uu * 14.0f) - floor( uu * 14.0f ); if( uu > 0.99999f ) uu = 0.99999f; out = &ft->hv[add]; aa = &h->hv[a]; bb = &h->hv[b]; cc = &h->hv[c]; dd = &h->hv[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); out = &ft->velocity[add]; aa = &h->velocity[a]; bb = &h->velocity[b]; cc = &h->velocity[c]; dd = &h->velocity[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); out = &ft->resthv[add]; aa = &h->resthv[a]; bb = &h->resthv[b]; cc = &h->resthv[c]; dd = &h->resthv[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); out = &ft->noisev[add]; aa = &h->noisev[a]; bb = &h->noisev[b]; cc = &h->noisev[c]; dd = &h->noisev[d]; out->x = spline( aa->x, bb->x, cc->x, dd->x, uu ); out->y = spline( aa->y, bb->y, cc->y, dd->y, uu ); out->z = spline( aa->z, bb->z, cc->z, dd->z, uu ); // fprintf (stdout, "%d\n",tt);fflush(stdout); tt++; } if (tt!=segs) { fprintf(stdout,"ERROR - guideseg missmatch %d %d\n",tt,segs);fflush(stdout); } } } } int make_geom_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ) { VERT offs; int index = 0; float rr; // int x; //CURVEINFO cinfo; int clone2 = 0; BASEHAIR lowhair[4]; // RENDERHAIR hh[3]; WFTYPE hh[4]; init_geomWF( &hh[0] ); init_geomWF( &hh[1] ); init_geomWF( &hh[2] ); init_geomWF( &hh[3] ); // void resize_base_hair(BASEHAIR *h,WFTYPE *ft,CURVEINFO *cinfo,int segs) global_segs = 56; // offs.x=0.0f; // offs.y=0.0f; // offs.z=0.0f; offs.x = 1.0f; offs.y = 0.0f; offs.z = 0.0f; // if (clone== -1) // { // offs.x=0.0f; // offs.y=0.0f; // offz.z=0.0f; // } // geom->totalverts=0; ////if (clone==0) { // int yy; //lowhair[0]= draw_lotsWF( slg, hairnum, offs, clone, &lowhair[0], cinfo ); if( ( lowhair[0].restlength > 0 ) && ( cinfo->killme == 0 ) ) clone2 = lowhair[0].dreadcount; } // lowhair[0]=draw_lotsWFNEW(0,0,offs,1,junkh); if( ( lowhair[0].restlength > 0 ) && ( cinfo->killme == 0 ) ) { // resize_base_hair(&lowhair[0],&hh[0],cinfo,LOCAL_SEGS[slg]); resize_base_hair( &lowhair[0], &hh[0], cinfo, segs ); index = 1; for( rr = ( float ) ( 6.283 / 4.0 ); rr < ( float ) 6.282999; rr += ( float ) ( 6.283 / 4.0 ) ) { offs.x = cos( rr ); offs.y = 0.0f; offs.z = sin( rr ); // lowhair[index]=draw_lotsWF(slg,hairnum,offs,0,&lowhair[index]); // draw_lotsWF(slg,hairnum,offs,0,&lowhair[index]); draw_lotsWF( slg, hairnum, offs, clone, &lowhair[index], cinfo ); if( cinfo->killme == 0 ) { // resize_base_hair(&lowhair[index],&hh[index],cinfo,LOCAL_SEGS[slg]); resize_base_hair( &lowhair[index], &hh[index], cinfo, segs ); // resample(lowhair[index],&hh[index]); // hh[index]=cut_single_hair(hh[index]); } index++; } } free_geomWF( geom ); if( ( cinfo->killme == 0 ) && ( lowhair[0].restlength > 0 ) ) { mk_geom( &hh[0], &hh[1], &hh[2], &hh[3], geom, segs ); } free_geomWF( &hh[0] ); free_geomWF( &hh[1] ); free_geomWF( &hh[2] ); free_geomWF( &hh[3] ); return ( ( int ) clone2 ); } static int make_spline_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ) { int ret; GLOBS *glots; //glots= &ggl; glots = >hreads[0]; glots->Gcurpass = Gcurpass; glots->hairnumber = hairnum; glots->passnumber = Gcurpass; glots->cursamp = cursamp; glots->Gslg = slg; glots->GhairID = hairnum; glots->rs.Gflyaway_percent=Gflyaway_percent; ret = MTmake_spline_hair( slg, hairnum, clone, segs, geom, cinfo, glots ); return ( ret ); } int make_spline_hairOLD( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ) { VERT offs; int index = 0; // float rr; // int x; BASEHAIR lowhair; //static BASEHAIR hh[1]; ////WFTYPE tmpwf; global_segs = 56; //// init_geomWF(&tmpwf); ////tmpwf.v=NULL; ////tmpwf.totalverts=segs; // offs.x=0.0f; // offs.y=0.0f; // offs.z=0.0f; offs.x = 0.0f; offs.y = 0.0f; offs.z = 0.0f; // geom->totalverts=0; ////if (clone==0) { // int yy; //lowhair[0]= //#ifndef NOLIB draw_lotsWF( slg, hairnum, offs, clone, &lowhair, cinfo ); //#endif //#ifdef NOLIB // draw_lotsWFFAST(slg,hairnum,offs,clone,&lowhair,cinfo); //#endif } // lowhair[0]=draw_lotsWFNEW(0,0,offs,1,junkh); /// resample(lowhair[0],&hh[0]); // hh[0]=cut_single_hair(hh[0]); // hh[0]=cut_single_base_hair(hh[0]); index = 1; free_geomWF( geom ); // if (lowhair.killme==0) if( cinfo->killme == 0 ) //// if (lowhair.restlength>0) { int xx; //geom will get allocated in here? resize_base_hair( &lowhair, geom, cinfo, segs ); //geom->totalverts=segs; geom->totalfaces = 1; //geom->totalfverts=segs; //alloc_geomWF(geom); for( xx = 0; xx < geom->totalverts; xx++ ) geom->facelist[xx] = xx; geom->face_start[0] = 0; geom->face_end[0] = geom->totalverts; if( lowhair.cutlength == 0 ) cinfo->killme = 1; //mk_spline_geom(&hh[0], geom, segs); } if( cinfo->killme ) { lowhair.dreadcount = 0; geom->totalverts = 0; geom->totalfaces = 0; geom->totalfverts = 0; } return ( ( int ) lowhair.dreadcount ); } void extract_chainWF( BASEHAIR * h, WFTYPE * wf ); void re_param_splines( WFTYPE * wf ) { int x, y; WFTYPE tmp; WFTYPE single; BASEHAIR h; init_geomWF( &single ); init_geomWF( &tmp ); tmp.totalfaces = wf->totalfaces; tmp.totalverts = tmp.totalfaces * 15; tmp.totalfverts = tmp.totalfaces * 15; alloc_geomWF( &tmp ); for( x = 0; x < wf->totalfaces; x++ ) { single.totalverts = wf->face_end[x] - wf->face_start[x]; single.totalfaces = 1; single.totalfverts = single.totalverts; alloc_geomWF( &single ); for( y = 0; y < single.totalverts; y++ ) { single.v[y] = // flip it wf->v[wf->facelist[wf->face_start[x] + y]]; single.v[y].z *= -1; } extract_chainWF( &h, &single ); for( y = 0; y < 15; y++ ) tmp.v[y + x * 15] = h.hv[y]; //h.hv[y]; for( y = 0; y < 15; y++ ) tmp.facelist[y + x * 15] = y + x * 15; tmp.face_start[x] = y + x * 15; tmp.face_end[x] = y + x * 15 + 15; free_geomWF( &single ); } free_geomWF( wf ); init_geomWF( wf ); wf->totalfaces = tmp.totalfaces; wf->totalverts = tmp.totalverts; wf->totalfverts = tmp.totalfverts; alloc_geomWF( wf ); for( x = 0; x < tmp.totalverts; x++ ) wf->v[x] = tmp.v[x]; for( x = 0; x < tmp.totalfverts; x++ ) wf->facelist[x] = tmp.facelist[x]; for( x = 0; x < tmp.totalfaces; x++ ) { wf->face_start[x] = x * 15; wf->face_end[x] = x * 15 + 15; } free_geomWF( &tmp ); } void extract_chainWF( BASEHAIR * h, WFTYPE * wf ) { VERT lowpoly[555]; VERT highpoly[1440]; int tv = 0; int lastv; int thisv; float td; int uc; int x; // get the face { for( x = 0; x < wf->totalverts; x++ ) { lowpoly[tv] = wf->v[x]; tv++; } // lowpoly[tv]=v[facelist[face_start[h->pid]]]; // tv++; // add an extra one for good measure uc = 0; for( x = 0; x < tv; x++ ) { int a, b, c, d; float u; // VERT aa,bb,cc,dd; a = x - 1; b = x; c = x + 1; d = x + 2; if( a < 0 ) a = 0; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; for( u = 0; u < 1.0f; u += ( ( float ) tv / 1300.0 ) ) { char tmp[255]; highpoly[uc].x = spline( lowpoly[a].x, lowpoly[b].x, lowpoly[c].x, lowpoly[d].x, u ); highpoly[uc].y = spline( lowpoly[a].y, lowpoly[b].y, lowpoly[c].y, lowpoly[d].y, u ); highpoly[uc].z = spline( lowpoly[a].z, lowpoly[b].z, lowpoly[c].z, lowpoly[d].z, u ); // sprintf(tmp,"x = %d uc = %d %f %f %f",x,uc,highpoly[uc].x,highpoly[uc].y,highpoly[uc].z); // DRAW_STATUS(tmp); uc++; } } td = 0; for( x = 0; x < 1300 - 1; x++ ) { td += Distance( highpoly[x], highpoly[x + 1] ); } td /= 15; // (was 16) this is the distance increment per seg // h->restlength=td; h->hv[0] = highpoly[0]; lastv = 0; thisv = 1; for( x = 1; x < 15; x++ ) { if( td > 0.0f ) { while( ( Distance( highpoly[lastv], highpoly[thisv] ) <= td ) && ( thisv < 1300 - 2 ) ) { thisv++; } if( thisv > 1300 - 1 ) thisv = 1300 - 1; h->hv[x] = highpoly[thisv]; } else h->hv[x] = highpoly[0]; lastv = thisv; } // h->mtl=splines; // h->vid=find_closest_vert(h->hv[0]); } h->mtl = splines; // h->vid=find_closest_vert(h->hv[0]); h->restlength = Distance( h->hv[1], h->hv[2] ); } void re_param_base( BASEHAIR * h ) { VERT lowpoly[555]; VERT highpoly[1440]; WFTYPE wf; int tv = 0; int lastv; int thisv; float td; int uc; int x; // get the face init_geomWF( &wf ); wf.totalfaces = 1; wf.totalverts = 15; wf.totalfverts = 15; alloc_geomWF( &wf ); for( x = 0; x < 15; x++ ) wf.facelist[x] = x; for( x = 0; x < 15; x++ ) wf.v[x] = h->hv[x]; wf.face_start[0] = 0; wf.face_end[0] = 15; { for( x = wf.totalverts - 1; x >= 0; x-- ) { lowpoly[tv] = wf.v[x]; tv++; } // lowpoly[tv]=v[facelist[face_start[h->pid]]]; // tv++; // add an extra one for good measure uc = 0; for( x = 0; x < tv; x++ ) { int a, b, c, d; float u; // VERT aa,bb,cc,dd; a = x - 1; b = x; c = x + 1; d = x + 2; if( a < 0 ) a = 0; if( c > tv - 1 ) c = tv - 1; if( d > tv - 1 ) d = tv - 1; for( u = 0; u < 1.0f; u += ( ( float ) tv / 1300.0 ) ) { char tmp[255]; highpoly[uc].x = spline( lowpoly[a].x, lowpoly[b].x, lowpoly[c].x, lowpoly[d].x, u ); highpoly[uc].y = spline( lowpoly[a].y, lowpoly[b].y, lowpoly[c].y, lowpoly[d].y, u ); highpoly[uc].z = spline( lowpoly[a].z, lowpoly[b].z, lowpoly[c].z, lowpoly[d].z, u ); // sprintf(tmp,"x = %d uc = %d %f %f %f",x,uc,highpoly[uc].x,highpoly[uc].y,highpoly[uc].z); // DRAW_STATUS(tmp); uc++; } } td = 0; for( x = 0; x < 1300 - 1; x++ ) { td += Distance( highpoly[x], highpoly[x + 1] ); } td /= 15; // (was 16) this is the distance increment per seg // h->restlength=td; h->hv[0] = highpoly[0]; lastv = 0; thisv = 1; for( x = 1; x < 15; x++ ) { if( td > 0.0f ) { while( ( Distance( highpoly[lastv], highpoly[thisv] ) <= td ) && ( thisv < 1300 - 2 ) ) { thisv++; } if( thisv > 1300 - 1 ) thisv = 1300 - 1; h->hv[x] = highpoly[thisv]; } else h->hv[x] = highpoly[0]; lastv = thisv; } // h->mtl=splines; // h->vid=find_closest_vert(h->hv[0]); } // h->mtl=splines; // h->vid=find_closest_vert(h->hv[0]); h->restlength = Distance( h->hv[1], h->hv[2] ); free_geomWF( &wf ); } void make_splines2( void ) { int x; int old_total = 0; free_splines( ); Dregroup2( ); DRAW_STATUS( "Making spline faces" ); DRAW_STATUS( "Making splines" ); // make the splinelist for( x = 0; x < Dtotalfaces; x++ ) { if( Dmtlgroup[x] >= 0 ) if( Dmtlgroup[x] == splines ) { total_splines++; } } DRAW_STATUS( "Allocating spline space" ); if( total_splines > 1 ) { alloc_splines( total_splines ); total_splines = 0; // first do the faces DRAW_STATUS( "Extracting spline chains" ); for( x = 0; x < Dtotalfaces; x++ ) { if( splines >= 0 ) if( Dmtlgroup[x] == splines ) { splinelist[total_splines] = x; total_splines++; } } for( x = 0; x < total_splines; x++ ) { Shair[x].pid = splinelist[x]; //if (Grendermode==0) extract_chain( &Shair[x] ); //else // Shair[x].vid=find_closest_vert(Shair[x].hv[0]); Shair[x].slgroup = 4; Shair[x].mtl = splines; //if (Grendermode==0) // Shair[x].restlength=Distance(Shair[x].hv[1],Shair[x].hv[2]); if( RW_CONTEXT != RW_LOCAL ) { Sthishair[x] = Shair[x]; Slasthair[x] = Shair[x]; Sresthair[x] = Shair[x]; } } DRAW_STATUS( "Extracting poly chains" ); DRAW_STATUS( "done with poly chains" ); } //initbounds(); } void make_splines200( void ) { int x; int old_total = 0; free_splines( ); Dregroup2( ); DRAW_STATUS( "Making spline faces" ); DRAW_STATUS( "Making splines" ); // make the splinelist for( x = 0; x < Dtotalfaces; x++ ) { if( Dmtlgroup[x] >= 0 ) if( Dmtlgroup[x] == splines ) { total_splines++; } } DRAW_STATUS( "Allocating spline space" ); if( total_splines > 1 ) { alloc_splines( total_splines ); total_splines = 0; // first do the faces DRAW_STATUS( "Extracting spline chains" ); for( x = 0; x < Dtotalfaces; x++ ) { if( splines >= 0 ) if( Dmtlgroup[x] == splines ) { splinelist[total_splines] = x; total_splines++; } } for( x = 0; x < total_splines; x++ ) { Shair[x].pid = splinelist[x]; //if (Grendermode==0) extract_chain( &Shair[x] ); //else // Shair[x].vid=find_closest_vert(Shair[x].hv[0]); Shair[x].slgroup = 4; Shair[x].mtl = splines; //if (Grendermode==0) // Shair[x].restlength=Distance(Shair[x].hv[1],Shair[x].hv[2]); if( RW_CONTEXT != RW_LOCAL ) { Sthishair[x] = Shair[x]; Slasthair[x] = Shair[x]; Sresthair[x] = Shair[x]; } } DRAW_STATUS( "Extracting poly chains" ); DRAW_STATUS( "done with poly chains" ); } //initbounds(); }