// Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include static void M_toggle_collision( void ) { int x; int col = 0; int tog = 0; for( x = 0; x < 5; x++ ) if( Gsurface_collide[x] ) col = 1; if( col == 1 ) tog = 0; if( col == 0 ) tog = 1; for( x = 0; x < 5; x++ ) Gsurface_collide[x] = tog; DOCOLLIDE = 0; if( DOCOLLIDE == 0 ) { for( x = 0; x < 5; x++ ) if( Gsurface_collide[x] > 0 ) DOCOLLIDE = 1; if( skull_sphere == -1 ) DOCOLLIDE = 0; } if( skull_sphere == -1 ) DOCOLLIDE = 0; if( DOCOLLIDE == 1 ) if( COLLISION_METHOD == 1 ) { make_normals( ); Dcalc_plane_eq( ); // norm is a unit vector setup_poly_vox( ); resize_poly_vox = 0; } if( DOCOLLIDE ) if( COLLISION_METHOD == 0 ) find_skulls( ); testvar = 0; } static void set_local( void ) { freeze.textoggle = 1; freeze_texl = 1; freeze_texg = 0; } static void set_global( void ) { freeze.textoggle = 1; freeze_texl = 0; freeze_texg = 1; } static void write_inst( CHNG fname[500] ); static void split_select( void ) { // int tmp; int x; int shatter; testvar = 0; totalsplits++; shatter = 0; for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] == 1 ) { hair[x].splitgroup = totalsplits; hair[x].splitmerge = 0; // split it // resthair[x].splitgroup=hair[x].splitgroup; // resthair[x].splitmerge=hair[x].splitmerge; } for( x = 0; x < total_splines; x++ ) if( Shair[x].select[0] == 1 ) { Shair[x].splitgroup = totalsplits; Shair[x].splitmerge = 0; // split it Sresthair[x].splitgroup = Shair[x].splitgroup; Sresthair[x].splitmerge = Shair[x].splitmerge; } DRAW_STATUS( "Split Selection" ); // setmainwin(); // drawmodel(); } static void shatter_select( void ) { // int tmp; int x; int shatter; testvar = 0; totalsplits++; shatter = 1; for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] == 1 ) { if( shatter ) totalsplits++; hair[x].splitgroup = totalsplits; hair[x].splitmerge = 0; // split it // resthair[x].splitgroup=hair[x].splitgroup; // resthair[x].splitmerge=hair[x].splitmerge; } for( x = 0; x < total_splines; x++ ) if( Shair[x].select[0] == 1 ) { if( shatter ) totalsplits++; Shair[x].splitgroup = totalsplits; Shair[x].splitmerge = 0; // split it Sresthair[x].splitgroup = Shair[x].splitgroup; Sresthair[x].splitmerge = Shair[x].splitmerge; } DRAW_STATUS( "Shatter Interp for Selection" ); // setmainwin(); // drawmodel(); } static void merge_select( void ) { testvar = 0; { // int tmp; int x; for( x = 0; x < totalverts; x++ ) { if( hair[x].select[0] == 1 ) { hair[x].splitmerge = 1; // merge it // resthair[x].splitmerge=1; } } for( x = 0; x < total_splines; x++ ) { if( Shair[x].select[0] == 1 ) { Shair[x].splitmerge = 1; // merge it Sresthair[x].splitmerge = 1; } } DRAW_STATUS( "Merge Selection" ); // setmainwin(); // drawmodel(); } } //#include static void comb_xminus( void ) { VERT direction; direction.x = -1; direction.y = 0.0f; direction.z = 0; comb_select( direction ); testvar = 0; } static void comb_cam( void ) { int x; VERT direction; direction.x = CamMatrix[2][0]; direction.y = CamMatrix[2][1]; direction.z = CamMatrix[2][2]; comb_select( direction ); for( x = 0; x < totalverts; x++ ) { memcpy( &hair[x].resthv, &hair[x].hv, sizeof( VERT ) * 15 ); } reset_noisespace( ); testvar = 0; } static void comb_xplus( void ) { VERT direction; direction.x = 1; direction.y = 0.0f; direction.z = 0; comb_select( direction ); testvar = 0; } static void comb_yminus( void ) { VERT direction; direction.x = 0; direction.y = -1.0f; direction.z = 0; comb_select( direction ); testvar = 0; } static void comb_yplus( void ) { VERT direction; direction.x = 0; direction.y = 1.0f; direction.z = 0; comb_select( direction ); testvar = 0; } static void comb_zminus( void ) { VERT direction; direction.x = 0; direction.y = 0.0f; direction.z = -1.0f; comb_select( direction ); testvar = 0; } static void comb_zplus( void ) { VERT direction; direction.x = 0; direction.y = 0.0f; direction.z = 1.0f; comb_select( direction ); testvar = 0; } static float VDot( VERT a, VERT b ); static VERT make_combdir( VERT direction, int pn ) { float sml = -1; //=9999.0f; int x, x1; float y; // VERT ctr; VERT ret; // direction.y=0; // direction=Vnorm(direction); ret = direction; for( x = face_start[pn]; x < face_end[pn]; x++ ) { x1 = x + 1; if( x1 >= face_end[pn] ) x1 = face_start[pn]; for( y = 0; y < 1.0f; y += .1f ) { int g, g1; VERT pp; g = facelist[x]; g1 = facelist[x1]; pp.x = ( v[g1].x - v[g].x ) * y + v[g].x; // get a point along an edge pp.y = ( v[g1].y - v[g].y ) * y + v[g].y; pp.z = ( v[g1].z - v[g].z ) * y + v[g].z; pp.x = pp.x - hair[pn].sparehv[1].x; //subtract from center pp.y = pp.y - hair[pn].sparehv[1].y; pp.z = pp.z - hair[pn].sparehv[1].z; pp = Vnorm( pp ); // got a vector for comparison if( ( VDot( pp, direction ) ) > sml ) { sml = ( VDot( pp, direction ) ); ret = pp; } } // y } // x return ( ret ); } static int check_for_unmarked_faces( void ) { int x; int ret = 0; for( x = 0; x < totalfaces; x++ ) { if( hair[x].pid == 0 ) { return ( 1 ); // it's unmakred } } return ( 0 ); // none marked } static int find_closest_unmarked_poly( VERT wp ) { int x; float sml = 999990; int pid; for( x = 0; x < totalfaces; x++ ) { if( hair[x].pid == 0 ) // it's unmarked { float d; d = Distance( hair[x].sparehv[1], wp ); if( d < sml ) { sml = d; pid = x; } } } return ( pid ); // this poly is closest } static int has_neighbors( int pn ) { int x; int fail = 1; for( x = 0; x < totalverts; x++ ) { hair[x].vid = 0; tagvert[x] = 0; } for( x = face_start[pn]; x < face_end[pn]; x++ ) { int g; g = facelist[x]; hair[g].vid = 1; } for( x = 0; x < totalfaces; x++ ) { int y; int tot; tot = 0; if( x != pn ) for( y = face_start[x]; y < face_end[x]; y++ ) { int g; g = facelist[y]; if( hair[g].vid != 0 ) { tagvert[x] = 1; // use this to tag neighbors fail = 0; } } // y } return ( fail ); } static VERT average_neighbors( int pn ) { VERT ret; int x; ret.x = 0; ret.y = 0; ret.z = 0; for( x = 0; x < totalfaces; x++ ) if( tagvert[x] ) // its a neighbor { ret.x += hair[x].norm.x; ret.y += hair[x].norm.y; ret.z += hair[x].norm.z; } return ( ret ); } static void smooth_combing( void ) { int x; int y; for( x = 0; x < totalverts; x++ ) { hair[x].sparehv[0].x = 0; hair[x].sparehv[0].y = 0; hair[x].sparehv[0].z = 0; } for( x = 0; x < totalfaces; x++ ) for( y = face_start[x]; y < face_end[x]; y++ ) { int g; g = facelist[y]; hair[g].sparehv[0].x += hair[x].norm.x; hair[g].sparehv[0].y += hair[x].norm.y; hair[g].sparehv[0].z += hair[x].norm.z; } for( x = 0; x < totalverts; x++ ) hair[x].sparehv[0] = Vnorm( hair[x].sparehv[0] ); } static void average_directions( void ) { int x; for( x = 0; x < totalfaces; x++ ) { int y; VERT avg; avg.x = 0; avg.y = 0; avg.z = 0; for( y = face_start[x]; y < face_end[x]; y++ ) { int g; g = facelist[y]; avg.x += hair[g].sparehv[0].x; avg.y += hair[g].sparehv[0].y; avg.z += hair[g].sparehv[0].z; } avg.x /= ( float ) ( face_end[x] - face_start[x] ); avg.y /= ( float ) ( face_end[x] - face_start[x] ); avg.z /= ( float ) ( face_end[x] - face_start[x] ); avg = Vnorm( avg ); hair[x].norm = avg; } } static void comb_select( VERT direction ) { VERT *poly_vector, *pvert; int x, y; //VERT tmpd; poly_vector = ( VERT * ) malloc( totalfaces * sizeof( VERT ) ); pvert = ( VERT * ) malloc( totalverts * sizeof( VERT ) ); for( x = 0; x < totalfaces; x++ ) { poly_vector[x].x = 0; poly_vector[x].y = 0; poly_vector[x].z = 0; } for( x = 0; x < totalverts; x++ ) { pvert[x].x = 0; pvert[x].y = 0; pvert[x].z = 0; } for( x = 0; x < totalfaces; x++ ) { float BIG = -1; VERT ctr, tmpd; ctr.x = 0; ctr.y = 0; ctr.z = 0; tmpd.x = 1.0f; tmpd.y = 0.0f; tmpd.z = 0.0f; for( y = face_start[x]; y < face_end[x]; y++ ) { int g; g = facelist[y]; ctr.x += v[g].x; ctr.y += v[g].y; ctr.z += v[g].z; } ctr.x /= face_end[x] - face_start[x]; ctr.y /= face_end[x] - face_start[x]; ctr.z /= face_end[x] - face_start[x]; for( y = face_start[x]; y < face_end[x]; y++ ) { float uu; int g, g1; float dt; VERT pp; g = facelist[y]; if( y < face_end[x] - 1 ) g1 = facelist[y + 1]; if( y == face_end[x] - 1 ) g1 = facelist[face_start[x]]; for( uu = 0.0f; uu < 1.0f; uu = uu + .1 ) { pp.x = v[g].x * uu + v[g1].x * ( 1.0f - uu ); pp.y = v[g].y * uu + v[g1].y * ( 1.0f - uu ); pp.z = v[g].z * uu + v[g1].z * ( 1.0f - uu ); pp.x -= ctr.x; pp.y -= ctr.y; pp.z -= ctr.z; pp = Vnorm( pp ); dt = VDot( pp, direction ); if( dt > BIG ) { tmpd = pp; BIG = dt; } } poly_vector[x].x = tmpd.x; poly_vector[x].y = tmpd.y; poly_vector[x].z = tmpd.z; } // y } // x // smooth direction ? //#ifdef crap for( x = 0; x < totalfaces; x++ ) for( y = face_start[x]; y < face_end[x]; y++ ) { int g; g = facelist[y]; pvert[g].x += poly_vector[x].x; pvert[g].y += poly_vector[x].y; pvert[g].z += poly_vector[x].z; // pvert[g].x=poly_vector[x].x; // pvert[g].y=poly_vector[x].y; // pvert[g].z=poly_vector[x].z; } for( x = 0; x < totalverts; x++ ) pvert[x] = Vnorm( pvert[x] ); //#endif // ok, ve've got directions, now let's make hair for( x = 0; x < totalverts; x++ ) { int slct = 0; // 1st check select for( y = 0; y < 15; y++ ) if( hair[x].select[y] ) slct = 1; // now make a straight one if( ( slct ) && ( hair[x].restlength > 0 ) ) { // if (group_stat[hair[x].mtl]<2) if( group_stat[hair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { hair[x].hv[y].x = hair[x].hv[y - 1].x + hair[x].restlength * pvert[x].x; hair[x].hv[y].y = hair[x].hv[y - 1].y + hair[x].restlength * pvert[x].y; hair[x].hv[y].z = hair[x].hv[y - 1].z + hair[x].restlength * pvert[x].z; } // no let's puff it up a bit // if (group_stat[hair[x].mtl]<2) if( group_stat[hair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { float scalar; scalar = ( 15 - y ) / 15.0f; scalar *= scalar; // scalar=pow(scalar,3.5); hair[x].hv[y].x = scalar * ( v[x].x + vn[x].x * ( float ) y * hair[x].restlength ) + ( 1.0f - scalar ) * hair[x].hv[y].x; hair[x].hv[y].y = scalar * ( v[x].y + vn[x].y * ( float ) y * hair[x].restlength ) + ( 1.0f - scalar ) * hair[x].hv[y].y; hair[x].hv[y].z = scalar * ( v[x].z + vn[x].z * ( float ) y * hair[x].restlength ) + ( 1.0f - scalar ) * hair[x].hv[y].z; hair[x].lasthv[y] = hair[x].hv[y]; } // if (group_stat[hair[x].mtl]<2) // if (group_stat[hair[x].mtl]==0) // recalc_hair(x); } // slct } // x reset_dynamics( ); for( x = 0; x < totalverts; x++ ) { if( group_stat[hair[x].mtl] == 0 ) recalc_hair( x ); } reset_dynamics( ); Nfree( pvert ); Nfree( poly_vector ); reset_rest( ); reset_noisespace( ); } static void lock_select( void ) { lock_verts( ); testvar = 0; } static void unlock_select( void ) { unlock_verts( ); testvar = 0; } extern void MAYAxform( WFTYPE * objfile, MEMFILE * node, MEMFILE * node_state, int run_dyn, char *stat ) { //int hair_verts; int obj_verts = 0; int oo; int fastmode = 0; //char statfile[255]; //FILE *fp; oo = OPENGL_DRAW; OPENGL_DRAW = 0; if( run_dyn == 1 ) Grendermode = 0; else Grendermode = 1; global_lastID = -1; SHAVEID = (unsigned long )node->ID; if( global_lastID != -1 ) if( SHAVEID == ( unsigned long ) global_lastID ) fastmode = 1; if( run_dyn > 0 ) fastmode = 0; if( run_dyn < 0 ) fastmode = 0; fastmode = 0; // jerome ! SHAVEID = (unsigned long )node->ID; // if (node->data==NULL) // printf ("MAYAxform :hey man, this MEMfile is NULL! check the dongle"); if( node->data ) // do we have a hair file? { // at this point we do have a hairfile int x; //printf ("before:\n"); //printf ("Dtotalverts = %d\n",Dtotalverts); //for (x=0;x<5;x++) //printf ("LOCAL_HAIRCOUNT[%d]= %d\n",x,LOCAL_CNT[x]); /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; node->pos = 0; read_hair( node ); node->pos = 0; gt = node_state->time; //for (x=0;xpos = 0; read_state_machine( node_state ); node_state->pos = 0; // gt++; // node_state->time = gt; } RW_CONTEXT = RW_DISK; //printf ("after:\n"); //printf ("Dtotalverts = %d\n",Dtotalverts); //for (x=0;x<5;x++) //printf ("LOCAL_HAIRCOUNT[%d]= %d\n",x,LOCAL_CNT[x]); //optimise init_noise( ); //optimise reset_faces( ); //optimise checkforzero( ); //optimise mkbounds( ); //optimise texture_bounds( ); //optimise weight_polys( ); ///// //printf ("resthair[0].x=%f\n",resthair[0].hv[0].x); if( Dv == NULL ) printf( "hey Dv has been cleared somewhere!" ); for( x = 0; x < Dtotalverts; x++ ) { Dv[x].x = objfile->v[x].x; Dv[x].y = objfile->v[x].y; Dv[x].z = -objfile->v[x].z; //flip // Dv[x].z=objfile->v[x].z; if( Dtag[x] ) { v[Dlink[x]] = Dv[x]; } } xformcontrolhair(); //if (run_dyn==0) reset_dynamics(); if( run_dyn == -1 ) { reset_dynamics( ); // node_state->time = 0; } if( ( run_dyn == 1 ) ) //||(run_dyn == -1)) ////if (stat!=NULL) doframe( ); RW_CONTEXT = RW_DISK; if( stat != NULL ) if( ( run_dyn == 1 ) ) //||(run_dyn== -1)) write_state( stat ); if( stat != NULL ) if( run_dyn == 2 ) read_state( stat ); RW_CONTEXT = RW_LOCAL; if( stat != NULL ) if( run_dyn == 2 ) make_normals(); // dec16 if (run_dyn!=2) // dec16 if (run_dyn!=0) { if( run_dyn < 1 ) { // for (x=0;xpos=0; ///write_hair(node); node->pos = 0; } if( node_state ) if( ( fastmode == 0 ) || ( node_state->data == NULL ) ) { node_state->pos = 0; node_state->size = 0; RW_CONTEXT = RW_RESIZE; write_state_machine( node_state ); if( node_state->data != NULL ) free( node_state->data ); node_state->data = ( char * ) malloc( node_state->size * sizeof( char ) ); } if( node_state ) { RW_CONTEXT = RW_LOCAL; node_state->pos = 0; write_state_machine( node_state ); node_state->pos = 0; } RW_CONTEXT = RW_DISK; // now transform the hair ////maya_load_morf2(objfilename); } //OPENGL_DRAW=1; global_lastID = SHAVEID; //init_clumping(); } extern void MAYAalloc( FREEZETYPE * ret ) { if( freeze.totalverts == 0 ) // instancing is off { ret->totalverts = 56 * 3 * 2; ret->totalfaces = 56 * 3 * 2 * 2; ret->totalfverts = 56 * 3 * 2 * 5; } else { ret->totalverts = freeze.totalverts + 1; ret->totalfverts = freeze.totalfverts + 1; ret->totalfaces = freeze.totalfaces + 1; } ret->v = ( VERT * ) malloc( ret->totalverts * sizeof( VERT ) ); ret->uv = ( VERT * ) malloc( ret->totalverts * sizeof( VERT ) ); ret->vn = ( VERT * ) malloc( ret->totalverts * sizeof( VERT ) ); ret->facelist = ( int * ) malloc( ret->totalfverts * sizeof( int ) ); ret->colorlock = ( int * ) malloc( ret->totalfaces * sizeof( int ) ); ret->face_start = ( int * ) malloc( ret->totalfaces * sizeof( int ) ); ret->face_end = ( int * ) malloc( ret->totalfaces * sizeof( int ) ); ret->mtlgroup = ( int * ) malloc( ret->totalfaces * sizeof( int ) ); ret->envelope = ( ENVELOPETYPE * ) malloc( ret->totalverts * sizeof( ENVELOPETYPE ) ); ret->rvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->gvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->bvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->Rrvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->Rgvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->Rbvcolor = ( float * ) malloc( ret->totalverts * sizeof( float ) ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; } extern void MAYANfree( FREEZETYPE * ret ); extern void MAYANfree( FREEZETYPE * ret ) { // STRANDNfree(ret); Dfreeverts( ); freeverts( ); } static void xforminstMT(WFTYPE *ret,int ind, GLOBS *gs ); extern void MAYAmake_a_hair( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cinfo ) { VERT offs; WFTYPE geom; int th = 0; int x; //float rr; int hc = 0; int hc2 = 0; //char tmp[255]; int tv = 0; GLOBS gs; //int didit; offs.x = 0; offs.y = 0; offs.z = 0; global_segs = 56; //ret->totalverts=0; //ret->totalfaces=0; //ret->totalfverts=0; geom.totalverts = 0; free_geomWF( ret ); // init_geomWF(&geom); cinfo->killme = 1; init_geomWF( &geom ); GhairID = hairnum; Gpass = current_samp; //printf ("freeze totalverts = %d\n",freeze.totalverts); //printf ("total_slgfaces = %d\n",total_slgfaces[slg]); if( freeze.totalverts == 0 ) if( total_slgfaces[slg] > 0 ) if( DEGENERATE_OBJECT == 0 ) if( ( LOCAL_CNT[slg] > 0 ) || ( LOCAL_SHADCNT[slg] > 0 ) ) if( LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; Gcurpass = current_samp; clones = make_geom_hair( slg, hairnum, 0, segs, &geom, cinfo ); // make_spline_hair( slg, hairnum, 0, segs, &geom, cinfo ); //printf ("geomverts ==== %d\n",geom.totalverts); // printf("geom.totalverts=%d\n",geom.totalverts); // printf(" slg->%d\n",slg); // fflush(stderr); if( cinfo->killme == 0 ) { int tv, tfv, tf; ret->totalverts = geom.totalverts * ( clones + 2 ); ret->totalfverts = geom.totalfverts * ( clones + 2 ); ret->totalfaces = geom.totalfaces * ( clones + 2 ); alloc_geomWF( ret ); tv = totalverts; tfv = totalfverts; tf = totalfaces; ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; if( clones == 0 ) clones = 1; for( q = 0; q < clones; q++ ) { int off; int foff; int ffoff; int junk; if( q != 0 ) junk = make_geom_hair( slg, hairnum, q, segs, &geom, cinfo ); // make_spline_hair( slg, hairnum, q, segs, // &geom, cinfo ); off = geom.totalverts * q; if( cinfo->killme == 0 ) if( geom.totalverts > 0 ) { for( x = 0; x < geom.totalverts; x++ ) { ret->v[ret->totalverts] = geom.v[x]; ret->velocity[ret->totalverts] = geom.velocity[x]; ret->uv[ret->totalverts] = geom.uv[x]; ret->color[ret->totalverts] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { foff = geom.totalfverts * q; ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } for( x = 0; x < geom.totalfaces; x++ ) { ffoff = geom.totalfaces * q; ret->face_start[ret->totalfaces] = geom.face_start[x] + foff; ret->face_end[ret->totalfaces] = geom.face_end[x] + foff; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } if( DEGENERATE_OBJECT == 0 ) if( freeze.totalverts != 0 ) { // freeze is on free_geomWF( ret ); gs.Gslg=slg; xforminstMT(ret,hairnum,>hreads[0]); } cinfo->hairID = hairnum; cinfo->nodeID = GnodeID; cinfo->depthpass = current_samp; } extern void MAYAset_state( MEMFILE * node, MEMFILE * state, float uu, CHNG *stat1, CHNG *stat2 ) { //int hair_verts; int obj_verts = 0; int oo; //char statfile[255]; //FILE *fp; BASEHAIR *ghair = NULL; BASEHAIR *Sghair = NULL; oo = OPENGL_DRAW; OPENGL_DRAW = 0; // if (node->data==NULL) // printf ("MAYAset_state :hey man, this MEMfile is NULL! check the dongle"); // if (stat1==NULL) // printf ("MAYAset_state :your first statfile is NULL, wsup?"); // if (stat2==NULL) // printf ("MAYAset_state :your second statfile is NULL, wsup?"); if( ( node->data ) ) // do we have a hair file? { // at this point we do have a hairfile int x; int y; /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; node->pos = 0; read_hair( node ); node->pos = 0; RW_CONTEXT = RW_DISK; reset_faces( ); checkforzero( ); mkbounds( ); texture_bounds( ); weight_polys( ); ///// ghair = ( BASEHAIR * ) malloc( ( totalverts + 1 ) * sizeof( BASEHAIR ) ); Sghair = ( BASEHAIR * ) malloc( ( total_splines + 1 ) * sizeof( BASEHAIR ) ); RW_CONTEXT = RW_DISK; if( stat1 != NULL ) read_state( stat1 ); for( x = 0; x < totalverts; x++ ) memcpy( &ghair[x], &hair[x], sizeof( BASEHAIR ) ); for( x = 0; x < total_splines; x++ ) memcpy( &Sghair[x], &Shair[x], sizeof( BASEHAIR ) ); if( stat2 != NULL ) read_state( stat2 ); for (x=0;xpos = 0; write_state_machine( state ); node->pos = 0; RW_CONTEXT = RW_DISK; } //OPENGL_DRAW=1; } extern void MAYAset_stateMEM( MEMFILE * node, MEMFILE * state, float uu, MEMFILE * stat1, MEMFILE * stat2 ) { //int hair_verts; int obj_verts = 0; int oo; //char statfile[255]; //FILE *fp; BASEHAIR *ghair = NULL; BASEHAIR *Sghair = NULL; oo = OPENGL_DRAW; OPENGL_DRAW = 0; // if (node->data==NULL) // printf ("MAYAset_state :hey man, this MEMfile is NULL! check the dongle"); if( ( node->data ) ) // do we have a hair file? { // at this point we do have a hairfile int x; int y; /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; node->pos = 0; read_hair( node ); node->pos = 0; RW_CONTEXT = RW_DISK; reset_faces( ); checkforzero( ); mkbounds( ); texture_bounds( ); weight_polys( ); ///// ghair = ( BASEHAIR * ) malloc( ( totalverts + 1 ) * sizeof( BASEHAIR ) ); Sghair = ( BASEHAIR * ) malloc( ( total_splines + 1 ) * sizeof( BASEHAIR ) ); RW_CONTEXT = RW_LOCAL; if( stat1->data != NULL ) read_state_machine( stat1 ); for( x = 0; x < totalverts; x++ ) ghair[x] = hair[x]; for( x = 0; x < totalverts; x++ ) Sghair[x] = Shair[x]; if( stat2->data != NULL ) read_state_machine( stat2 ); //for (x=0;xpos = 0; write_state_machine( state ); node->pos = 0; RW_CONTEXT = RW_DISK; } //OPENGL_DRAW=1; } extern void MAYAflush_state( MEMFILE * node, MEMFILE * state ) { // if (node->data==NULL) // printf ("MAYAflush_state :hey man, this MEMfile is NULL! "); // SHAVEclear_stack(); // leaks ? if( state->data ) if( node->data ) // do we have a hair file? { // at this point we do have a hairfile int x; int y; /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; global_lastID = -1; // no fastmode! lsSHAVEID = -2; node->pos = 0; read_hair( node ); node->pos = 0; node->pos = 0; global_lastID = -1; // no fastmode! read_state_machine( state ); node->pos = 0; //for (x=0;xclumps; // fprintf (stdout,"ID = %d clumps = %d mayasetparms1\n",SHAVEID, Gclumps);fflush(stdout); for( x = 0; x < 5; x++ ) { Ganim_dir[x] = shavep->frizz_anim_dir[x]; Gsurface_collide[x] = shavep->collide[x]; GtipFade=shavep->tipfade; if( shavep->collide[x] > 0 ) DOCOLLIDE = 1; if( skull_sphere == -1 ) DOCOLLIDE = 0; if( total_slgfaces[x] > 0 ) { LOCAL_PASSES[x] = shavep->passes[x]; LOCAL_CNT[x] = shavep->haircount[x]; LOCAL_SHADCNT[x] = shavep->shadowHaircount[x]; } else { shavep->passes[x]; // LOCAL_PASSES[x]=0; LOCAL_CNT[x] = 0; LOCAL_SHADCNT[x] = 0; } LOCAL_SEGS[x] = shavep->segs[x]; for( y = 0; y < 60; y++ ) { sliders[y][x].value = shavep->slider_val[y][x]; //sprintf(sliders[y][x].lable,"%s",shavep->slider_lable[y][x]); // sliders[y][x].paint = shavep->painted[y][x]; } } //fprintf (stdout,"set_parms shavep->slider_val[44][0]=%f\n",sliders[44][0].value);fflush(stdout); for( y = 0; y < 60; y++ ) Guv_link[y] = shavep->uv_link[y]; sliders[0][5].value = shavep->slider_val[0][5]; sprintf( shavep->slider_lable[0][5], "gravity" ); shavep->painted[0][5] = 0; gravity = shavep->slider_val[0][5]; //#ifdef crap if( olddc == 0 ) if( DOCOLLIDE ) if( COLLISION_METHOD == 1 ) { make_normals( ); Dcalc_plane_eq( ); // norm is a unit vector setup_poly_vox( ); resize_poly_vox = 0; } if( olddc == 0 ) if( DOCOLLIDE ) if( COLLISION_METHOD == 0 ) find_skulls( ); //#endif COLLISION_METHOD = shavep->collision_method; //Guse_old_splayscale=shavep->use_old_splayscale; // fprintf (stdout,"ID = %d clumps = %d mayasetparms2\n",SHAVEID, Gclumps);fflush(stdout); Gdontinterp = shavep->dontinterpolate; sprintf( Gname, "%s", shavep->name ); Gbacklighting = shavep->geom_shadow; Gspec_tint.x = 1.0f; Gspec_tint.y = 1.0f; Gspec_tint.z = 1.0f; Gsquirrel=shavep->squirrel; Gflyaway_percent=shavep->flyaway_percent; // fprintf(stdout,"squirrel = %d\n",shavep->squirrel);fflush(stdout); //#ifdef MAX3D Gspec_tint = shavep->spec_tint; Gspec_tint2 = shavep->spec_tint2; Gclumps = shavep->clumps; if (LOCAL_CNT[0]>0) Gslg=0; if (LOCAL_CNT[4]>0) Gslg=4; Grandom_seed_offset=shavep->rand_seed_offset; #ifdef diagnose_trouble fprintf (stdout,"slg = %d clumps = %d\n",Gslg,Gclumps);fflush(stdout); #endif init_clumping(); #ifdef MAX3D Gspec_tint.x /= 255.0f; Gspec_tint.y /= 255.0f; Gspec_tint.z /= 255.0f; Gspec_tint2.x /= 255.0f; Gspec_tint2.y /= 255.0f; Gspec_tint2.z /= 255.0f; #endif //shavep->total_guides=totalverts; //if (Gindex) //{ //free(Gindex); //kd_free(Gkd); //} // fprintf (stdout,"ID = %d clumps = %d mayasetparms3\n",SHAVEID, Gclumps);fflush(stdout); } extern void MAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret ) { VERT offs; WFTYPE geom; int th = 0; int x; //float rr; int hc = 0; int hc2 = 0; //char tmp[255]; int tv = 0; //int didit; CURVEINFO cinfo; offs.x = 0; offs.y = 0; offs.z = 0; global_segs = 56; //ret->totalverts=0; //ret->totalfaces=0; //ret->totalfverts=0; free_geomWF( ret ); init_geomWF( &geom ); //geom.totalverts=0; // free_geom(ret); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; //if (freeze.totalverts==0) if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; Gcurpass = current_samp; clones = make_spline_hair( slg, hairnum, 0, segs, &geom, &cinfo ); // printf("geom.totalverts=%d\n",geom.totalverts); // printf(" slg->%d\n",slg); // fflush(stderr); if( cinfo.killme == 0 ) { ret->totalverts = geom.totalverts * ( clones + 1 ); ret->totalfverts = geom.totalfverts * ( clones + 1 ); ret->totalfaces = geom.totalfaces * ( clones + 1 ); alloc_geomWF( ret ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; if( clones == 0 ) clones = 1; for( q = 0; q < clones; q++ ) { int off, foff; int junk; if( q != 0 ) junk = make_spline_hair( slg, hairnum, q, segs, &geom, &cinfo ); if( geom.totalverts > 0 ) { for( x = 0; x < geom.totalverts; x++ ) { off = geom.totalverts * q; ret->v[x + off] = geom.v[x]; ret->uv[x + off] = geom.uv[x]; ret->color[x + off] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { foff = geom.totalfverts * q; ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } for( x = 0; x < geom.totalfaces; x++ ) { // off=geom.totalfaces*q; ret->face_start[ret->totalfaces] = geom.face_start[x] + foff; ret->face_end[ret->totalfaces] = geom.face_end[x] + foff; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } } extern void MTMAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, GLOBS * gs ) { VERT offs; WFTYPE geom; int th = 0; int x; //float rr; int hc = 0; int hc2 = 0; //char tmp[255]; int tv = 0; //int didit; CURVEINFO cinfo; offs.x = 0; offs.y = 0; offs.z = 0; //ret->totalverts=0; //ret->totalfaces=0; //ret->totalfverts=0; free_geomWF( ret ); init_geomWF( &geom ); //geom.totalverts=0; // free_geom(ret); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; //if (freeze.totalverts==0) if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; Gcurpass = current_samp; clones = MTmake_spline_hair( slg, hairnum, 0, segs, &geom, &cinfo, gs ); // printf("geom.totalverts=%d\n",geom.totalverts); // printf(" slg->%d\n",slg); // fflush(stderr); if( cinfo.killme == 0 ) { ret->totalverts = geom.totalverts * ( clones + 1 ); ret->totalfverts = geom.totalfverts * ( clones + 1 ); ret->totalfaces = geom.totalfaces * ( clones + 1 ); alloc_geomWF( ret ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; if( clones == 0 ) clones = 1; for( q = 0; q < clones; q++ ) { int off, foff; int junk; if( q != 0 ) junk = MTmake_spline_hair( slg, hairnum, q, segs, &geom, &cinfo, gs ); if( geom.totalverts > 0 ) { for( x = 0; x < geom.totalverts; x++ ) { off = geom.totalverts * q; ret->v[x + off] = geom.v[x]; ret->uv[x + off] = geom.uv[x]; ret->color[x + off] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { foff = geom.totalfverts * q; ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } for( x = 0; x < geom.totalfaces; x++ ) { // off=geom.totalfaces*q; ret->index[ret->totalfaces] = geom.index[x]; ret->face_start[ret->totalfaces] = geom.face_start[x] + foff; ret->face_end[ret->totalfaces] = geom.face_end[x] + foff; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } } extern void MAYAxformNOSTAT( WFTYPE * objfile, MEMFILE * node, MEMFILE * node_state, int run_dyn ) { //int hair_verts; int obj_verts = 0; int oo; //char statfile[255]; //FILE *fp; oo = OPENGL_DRAW; //OPENGL_DRAW=0; // if (node->data==NULL) // printf ("MAYAxform :hey man, this MEMfile is NULL! check the dongle"); if( run_dyn < 2 ) if( node->data ) // do we have a hair file? { // at this point we do have a hairfile int x; //printf ("before:\n"); //printf ("Dtotalverts = %d\n",Dtotalverts); //for (x=0;x<5;x++) //printf ("LOCAL_HAIRCOUNT[%d]= %d\n",x,LOCAL_CNT[x]); /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; node->pos = 0; read_hair( node ); node->pos = 0; for( x = 0; x < totalverts; x++ ) memcpy( &hair[x].resthv, &hair[x].hv, sizeof( VERT ) * 15 ); node_state->pos = 0; read_state_machine( node_state ); node_state->pos = 0; RW_CONTEXT = RW_DISK; //printf ("after:\n"); //printf ("Dtotalverts = %d\n",Dtotalverts); //for (x=0;x<5;x++) //printf ("LOCAL_HAIRCOUNT[%d]= %d\n",x,LOCAL_CNT[x]); reset_faces( ); checkforzero( ); mkbounds( ); texture_bounds( ); weight_polys( ); ///// //if (Dv==NULL) printf ("hey Dv has been cleared somewhere!"); for( x = 0; x < Dtotalverts; x++ ) { Dv[x].x = objfile->v[x].x; Dv[x].y = objfile->v[x].y; Dv[x].z = objfile->v[x].z; Dv[x].z = -objfile->v[x].z; // flip; if( Dtag[x] ) { v[Dlink[x]] = Dv[x]; } } xformcontrolhair( ); // make this a kernal if( run_dyn == 0 ) reset_dynamics( ); if( run_dyn == -1 ) reset_dynamics( ); if( ( run_dyn == 1 ) || ( run_dyn == -1 ) ) doframe( ); node_state->pos = 0; write_state_machine( node_state ); node_state->pos = 0; //node->pos=0; //write_hair(node); //node->pos=0; RW_CONTEXT = RW_DISK; // now transform the hair ////maya_load_morf2(objfilename); } // if (Gkd) // kd_free(Gkd); // Gkd=NULL; // if (!Gkd) // if (hair) // if (Gclumps>3) // init_clumping(); //OPENGL_DRAW=1; } extern void MAYAfetch_parms( SHAVEPARMS * shavep ) { int x; int y; //printf ("parm[8][4]=%f parm[8][0]=%f\n",sliders[8][4].value,sliders[8][0].value); for( x = 0; x < 5; x++ ) { shavep->dontinterpolate = Gdontinterp; //shavep->use_old_splayscale=Guse_old_splayscale; sprintf( shavep->name, "%s", Gname ); shavep->segs[x] = LOCAL_SEGS[x]; shavep->frizz_anim_dir[x] = Ganim_dir[x]; shavep->collide[x] = Gsurface_collide[x]; shavep->clumps=Gclumps; shavep->flyaway_percent=Gflyaway_percent; shavep->squirrel=Gsquirrel; shavep->spec_tint=Gspec_tint; shavep->tipfade=GtipFade; shavep->spec_tint2= Gspec_tint2 ; shavep->rand_seed_offset=Grandom_seed_offset; #ifdef MAX3D shavep->spec_tint.x*=255.0f; shavep->spec_tint.y*=255.0f; shavep->spec_tint.z*=255.0f; shavep->spec_tint2.x*=255.0f; shavep->spec_tint2.y*=255.0f; shavep->spec_tint2.z*=255.0f; #endif if( total_slgfaces[x] > 0 ) { shavep->passes[x] = LOCAL_PASSES[x]; shavep->haircount[x] = LOCAL_CNT[x]; shavep->shadowHaircount[x] = LOCAL_SHADCNT[x]; } else { // shavep->passes[x]=0; shavep->haircount[x] = 0; // LOCAL_PASSES[x]=0; LOCAL_CNT[x] = 0; LOCAL_SHADCNT[x] = 0; } for( y = 0; y < 60; y++ ) { shavep->slider_val[y][x] = sliders[y][x].value; // if( sliders[y][x].enable == 1 ) // sprintf( shavep->slider_lable[y][x], "%s", sliders[y][x].lable ); // else // sprintf( shavep->slider_lable[y][x], "DISSABLED" ); // shavep->painted[y][x] = sliders[y][x].paint; } } //fprintf (stdout,"fetch_parms shavep->slider_val[44][0]=%f\n",sliders[44][0].value);fflush(stdout); for( y = 0; y < 60; y++ ) shavep->uv_link[y] = Guv_link[y]; shavep->instancing_status = 0; if( freeze.totalverts ) shavep->instancing_status = 1; shavep->slider_val[0][5] = sliders[0][5].value; sprintf( shavep->slider_lable[0][5], "gravity" ); shavep->painted[0][5] = 0; if( total_splines == 0 ) shavep->total_guides = totalverts; else shavep->total_guides = total_splines; shavep->collision_method = COLLISION_METHOD; shavep->geom_shadow = Gbacklighting; shavep->spec_tint = Gspec_tint; shavep->spec_tint2 = Gspec_tint2; shavep->squirrel=Gsquirrel; shavep->flyaway_percent=Gflyaway_percent; shavep->clumps = Gclumps; shavep->rand_seed_offset=Grandom_seed_offset; } extern void check_partial_select( void ) { int x; SOFTGUIDE g; for( x = 0; x < totalverts / 2; x++ ) { g.select[0] = 1; SOFTput_guideSELECTONLY( x, &g ); } for( x = totalverts / 2; x < totalverts; x++ ) { g.select[0] = 0; SOFTput_guideSELECTONLY( x, &g ); } } extern void MAYAfetch_node( MEMFILE * node, MEMFILE * node_state, SHAVEPARMS * shavep ) { int x; int fastmode = 0; //int hair_verts; int obj_verts = 0; //int oo; int read_node = 0, read_state = 0, read_parms = 0; //node->ID=SHAVEID; //this should be correct //SHAVEID=node->ID; if( ( node ) && ( node_state ) ) if( global_lastID > 0 ) if( ( int ) global_lastID == SHAVEID ) fastmode = 1; fastmode = 0; // for jerome ! if( ( node ) && ( node_state ) ) { if( node->data == NULL ) fastmode = 0; if( node_state->data == NULL ) fastmode = 0; } if( Gdynamics_mode != 0 ) fastmode = 0; if( shavep != NULL ) read_parms = 1; if( node != NULL ) read_node = 1; if( node_state != NULL ) read_state = 1; RW_CONTEXT = RW_LOCAL; { if( read_state == 1 ) { if( node_state ) if( ( fastmode == 0 ) || ( node_state->data == NULL ) ) { node_state->pos = 0; node_state->size = 0; RW_CONTEXT = RW_RESIZE; write_state_machine( node_state ); if( node_state->data != NULL ) { free( node_state->data ); node_state->data = NULL; } if( node_state->size > 0 ) node_state->data = ( char * ) malloc( node_state->size * sizeof( char ) ); } RW_CONTEXT = RW_LOCAL; node_state->pos = 0; if( node_state->size > 0 ) write_state_machine( node_state ); } if( read_node == 1 ) { // RW_CONTEXT=RW_LOCAL; // if (node->data!=NULL) // { // node->pos=0; // write_hair(node); // node->pos=0; // } // else if( node ) if( ( fastmode == 0 ) || ( node->data == NULL ) ) { // if (node->data!=NULL) free(node->data); node->pos = 0; node->size = 0; RW_CONTEXT = RW_RESIZE; write_hair( node ); if( node->data != NULL ) { free( node->data ); node->data = NULL; } node->data = ( char * ) malloc( node->size * sizeof( char ) ); RW_CONTEXT = RW_LOCAL; node->pos = 0; node->time = gt; write_hair( node ); } node->pos = 0; if( fastmode == 1 ) // write_hair(node); write_hairFAST( node ); } } RW_CONTEXT = RW_DISK; //fprintf (stdout,"setting sliders[51][0].value=%f\n",sliders[51][0].value);fflush(stdout); if( read_parms == 1 ) { int y; for( x = 0; x < 5; x++ ) { shavep->passes[x] = LOCAL_PASSES[x]; shavep->haircount[x] = LOCAL_CNT[x]; shavep->shadowHaircount[x] = LOCAL_SHADCNT[x]; for( y = 0; y < 60; y++ ) { shavep->slider_val[y][x] = sliders[y][x].value; // sprintf( shavep->slider_lable[y][x], "%s", sliders[y][x].lable ); // shavep->painted[y][x] = sliders[y][x].paint; } shavep->collide[x] = Gsurface_collide[x]; } sprintf( shavep->name, "%s", Gname ); shavep->dontinterpolate = Gdontinterp; // shavep->use_old_splayscale = Guse_old_splayscale; shavep->slider_val[0][5] = sliders[0][5].value; sprintf( shavep->slider_lable[0][5], "gravity" ); shavep->painted[0][5] = 0; if( total_splines == 0 ) shavep->total_guides = totalverts; else shavep->total_guides = total_splines; shavep->collision_method = COLLISION_METHOD; shavep->instancing_status = 0; if( freeze.totalverts > 0 ) shavep->instancing_status = 1; for( y = 0; y < 60; y++ ) shavep->uv_link[y] = Guv_link[y]; shavep->flyaway_percent=Gflyaway_percent; shavep->clumps=Gclumps; } global_lastID = SHAVEID; } extern void MAYAfetch_node_for_game( MEMFILE * node, MEMFILE * node_state, SHAVEPARMS * shavep ) { int x; int fastmode = 0; //int hair_verts; int obj_verts = 0; //int oo; int read_node = 0, read_state = 0, read_parms = 0; node->ID=(int)SHAVEID; //this should be correct //SHAVEID=node->ID; if( ( node ) && ( node_state ) ) if( global_lastID > 0 ) if( ( int ) global_lastID == SHAVEID ) fastmode = 1; fastmode = 0; // for jerome ! if( ( node ) && ( node_state ) ) { if( node->data == NULL ) fastmode = 0; if( node_state->data == NULL ) fastmode = 0; } if( Gdynamics_mode != 0 ) fastmode = 0; if( shavep != NULL ) read_parms = 1; if( node != NULL ) read_node = 1; if( node_state != NULL ) read_state = 1; RW_CONTEXT = RW_LOCAL; { if( read_state == 1 ) { if( node_state ) if( ( fastmode == 0 ) || ( node_state->data == NULL ) ) { node_state->pos = 0; node_state->size = 0; RW_CONTEXT = RW_RESIZE; write_state_machine( node_state ); if( node_state->data != NULL ) { free( node_state->data ); node_state->data = NULL; } if( node_state->size > 0 ) node_state->data = ( char * ) malloc( node_state->size * sizeof( char ) ); } RW_CONTEXT = RW_LOCAL; node_state->pos = 0; if( node_state->size > 0 ) write_state_machine( node_state ); } if( read_node == 1 ) { // RW_CONTEXT=RW_LOCAL; // if (node->data!=NULL) // { // node->pos=0; // write_hair(node); // node->pos=0; // } // else if( node ) if( ( fastmode == 0 ) || ( node->data == NULL ) ) { // if (node->data!=NULL) free(node->data); node->pos = 0; node->size = 0; RW_CONTEXT = RW_RESIZE; write_hair( node ); if( node->data != NULL ) { free( node->data ); node->data = NULL; } node->data = ( char * ) malloc( node->size * sizeof( char ) ); RW_CONTEXT = RW_LOCAL; node->pos = 0; node->time = gt; write_hair( node ); } node->pos = 0; if( fastmode == 1 ) // write_hair(node); write_hairFAST( node ); } } RW_CONTEXT = RW_DISK; //fprintf (stdout,"setting sliders[51][0].value=%f\n",sliders[51][0].value);fflush(stdout); if( read_parms == 1 ) { int y; for( x = 0; x < 5; x++ ) { shavep->passes[x] = LOCAL_PASSES[x]; shavep->haircount[x] = LOCAL_CNT[x]; shavep->shadowHaircount[x] = LOCAL_SHADCNT[x]; for( y = 0; y < 60; y++ ) { shavep->slider_val[y][x] = sliders[y][x].value; // sprintf( shavep->slider_lable[y][x], "%s", sliders[y][x].lable ); // shavep->painted[y][x] = sliders[y][x].paint; } shavep->collide[x] = Gsurface_collide[x]; } sprintf( shavep->name, "%s", Gname ); shavep->dontinterpolate = Gdontinterp; // shavep->use_old_splayscale = Guse_old_splayscale; shavep->slider_val[0][5] = sliders[0][5].value; sprintf( shavep->slider_lable[0][5], "gravity" ); shavep->painted[0][5] = 0; if( total_splines == 0 ) shavep->total_guides = totalverts; else shavep->total_guides = total_splines; shavep->collision_method = COLLISION_METHOD; shavep->instancing_status = 0; if( freeze.totalverts > 0 ) shavep->instancing_status = 1; for( y = 0; y < 60; y++ ) shavep->uv_link[y] = Guv_link[y]; shavep->flyaway_percent=Gflyaway_percent; shavep->clumps=Gclumps; } global_lastID = SHAVEID; } extern void MAYAset_stateglue( WFTYPE * wf, MEMFILE * node, MEMFILE * state, float uu, CHNG *stat1, CHNG *stat2 ) { //int hair_verts; int obj_verts = 0; int oo; //char statfile[255]; //FILE *fp; BASEHAIR *ghair = NULL; BASEHAIR *Sghair = NULL; oo = OPENGL_DRAW; OPENGL_DRAW = 0; // if (node->data==NULL) // printf ("MAYAset_state :hey man, this MEMfile is NULL! check the dongle"); // if (stat1==NULL) // printf ("MAYAset_state :your first statfile is NULL, wsup?"); // if (stat2==NULL) // printf ("MAYAset_state :your second statfile is NULL, wsup?"); if( ( node->data ) ) // do we have a hair file? { // at this point we do have a hairfile int x; int y; /// restore the node to shave memory RW_CONTEXT = RW_LOCAL; node->pos = 0; read_hair( node ); node->pos = 0; RW_CONTEXT = RW_DISK; reset_faces( ); checkforzero( ); mkbounds( ); texture_bounds( ); weight_polys( ); ///// ghair = ( BASEHAIR * ) malloc( ( totalverts + 1 ) * sizeof( BASEHAIR ) ); Sghair = ( BASEHAIR * ) malloc( ( total_splines + 1 ) * sizeof( BASEHAIR ) ); RW_CONTEXT = RW_DISK; if( stat1 != NULL ) read_state( stat1 ); for( x = 0; x < totalverts; x++ ) memcpy( &ghair[x], &hair[x], sizeof( BASEHAIR ) ); for( x = 0; x < total_splines; x++ ) memcpy( &Sghair[x], &Shair[x], sizeof( BASEHAIR ) ); if( stat2 != NULL ) read_state( stat2 ); gt=state->time; for( x = 0; x < totalverts; x++ ) { hair[x].norm.x=ghair[x].norm.x * ( 1.0f - uu ) + hair[x].norm.x * uu; hair[x].norm.y=ghair[x].norm.y * ( 1.0f - uu ) + hair[x].norm.y * uu; hair[x].norm.z=ghair[x].norm.z * ( 1.0f - uu ) + hair[x].norm.z * uu; } for( x = 0; x < total_splines; x++ ) { Sthishair[x].norm.x=Sghair[x].norm.x * ( 1.0f - uu ) + Sthishair[x].norm.x * uu; Sthishair[x].norm.y=Sghair[x].norm.y * ( 1.0f - uu ) + Sthishair[x].norm.y * uu; Sthishair[x].norm.z=Sghair[x].norm.z * ( 1.0f - uu ) + Sthishair[x].norm.z * uu; } for( x = 0; x < totalverts; x++ ) for( y = 0; y < 15; y++ ) { hair[x].hv[y].x = ghair[x].hv[y].x * ( 1.0f - uu ) + hair[x].hv[y].x * uu; hair[x].hv[y].y = ghair[x].hv[y].y * ( 1.0f - uu ) + hair[x].hv[y].y * uu; hair[x].hv[y].z = ghair[x].hv[y].z * ( 1.0f - uu ) + hair[x].hv[y].z * uu; // lasthair[x].hv[y]=ghair[x].hv[y]; // hair[x].hv[y]=thishair[x].hv[y]; } for( x = 0; x < total_splines; x++ ) for( y = 0; y < 15; y++ ) { Sthishair[x].hv[y].x = Sghair[x].hv[y].x * ( 1.0f - uu ) + Sthishair[x].hv[y].x * uu; Sthishair[x].hv[y].y = Sghair[x].hv[y].y * ( 1.0f - uu ) + Sthishair[x].hv[y].y * uu; Sthishair[x].hv[y].z = Sghair[x].hv[y].z * ( 1.0f - uu ) + Sthishair[x].hv[y].z * uu; // hair[x].lasthv[y]=hair[x].hv[y]; Shair[x].hv[y] = Sthishair[x].hv[y]; // Slasthair[x].hv[y]=Shair[x].hv[y]; // hair[x].hv[y]=thishair[x].hv[y]; } if( ghair != NULL ) free( ghair ); if( Sghair != NULL ) free( Sghair ); // this is the glue part if( wf->totalverts == Dtotalverts ) { for( x = 0; x < totalverts; x++ ) //hair[x].select[0]) if( ( hair[x].select[0] ) || ( Gdynamics_mode != 0 ) ) { VERT diff; VERT tmp; diff.x = hair[x].hv[0].x - wf->v[vlink[x]].x; diff.y = hair[x].hv[0].y - wf->v[vlink[x]].y; diff.z = hair[x].hv[0].z - wf->v[vlink[x]].z; for( y = 0; y < 15; y++ ) { hair[x].hv[y].x -= diff.x; hair[x].hv[y].y -= diff.y; hair[x].hv[y].z -= diff.z; // thishair[x].hv[y].x-=diff.x; // thishair[x].hv[y].y-=diff.y; // thishair[x].hv[y].z-=diff.z; // lasthair[x].hv[y].x-=diff.x; // lasthair[x].hv[y].y-=diff.y; // lasthair[x].hv[y].z-=diff.z; } } } xformHandles(); for (x=0;xtotalverts;x++) { wf->v[x].z*= -1.0f; } RW_CONTEXT = RW_LOCAL; node->pos = 0; write_state_machine( state ); node->pos = 0; RW_CONTEXT = RW_DISK; } //OPENGL_DRAW=1; } static void Srecomb_select2( void ) { VERT direction; int x, y; int iterate; VERT a; //VERT tmpd; testvar = 0; mkHandles( ); for( x = 0; x < total_splines; x++ ) if( Shair[x].select[0] ) { int slct = 0; a.x = Shair[x].hv[14].x - Shair[x].hv[0].x; a.y = Shair[x].hv[14].y - Shair[x].hv[0].y; a.z = Shair[x].hv[14].z - Shair[x].hv[0].z; a = Vnorm( a ); a = Vcross( a, Shair[x].norm ); a = Vcross( Shair[x].norm, a ); // a=Vcross(Shair[x].norm,Shair[x].handle); // 1st check select for( y = 0; y < 15; y++ ) if( Shair[x].select[y] ) slct = 1; // now make a straight one if( ( slct ) && ( Shair[x].restlength > 0 ) ) { // if (group_stat[hair[x].mtl]<2) if( group_stat[Shair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { Shair[x].hv[y].x = Shair[x].hv[y - 1].x + Shair[x].restlength * a.x; Shair[x].hv[y].y = Shair[x].hv[y - 1].y + Shair[x].restlength * a.y; Shair[x].hv[y].z = Shair[x].hv[y - 1].z + Shair[x].restlength * a.z; } // no let's puff it up a bit // if (group_stat[hair[x].mtl]<2) if( group_stat[Shair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { float scalar; scalar = ( 15 - y ) / 15.0f; scalar *= scalar; // scalar -= .3; if( scalar < 0 ) scalar = 0; // scalar=pow(scalar,3.5); Shair[x].hv[y].x = scalar * ( Shair[x].hv[0].x + Shair[x].norm.x * ( float ) y * Shair[x].restlength * .5 ) + ( 1.0f - scalar ) * Shair[x].hv[y].x; Shair[x].hv[y].y = scalar * ( Shair[x].hv[0].y + Shair[x].norm.y * ( float ) y * Shair[x].restlength * .5 ) + ( 1.0f - scalar ) * Shair[x].hv[y].y; Shair[x].hv[y].z = scalar * ( Shair[x].hv[0].z + Shair[x].norm.z * ( float ) y * Shair[x].restlength * .5 ) + ( 1.0f - scalar ) * Shair[x].hv[y].z; Shair[x].lasthv[y] = Shair[x].hv[y]; } // if (group_stat[hair[x].mtl]<2) // if (group_stat[hair[x].mtl]==0) // recalc_hair(x); } // slct } // x for( x = 0; x < total_splines; x++ ) if( Shair[x].select[0] ) { if( group_stat[Shair[x].mtl] == 0 ) Srecalc_hair( x ); } // reset_dynamics( ); for( x = 0; x < total_splines; x++ ) { if( Shair[x].select[0] ) memcpy( &Shair[x].resthv, &Shair[x].hv, sizeof( VERT ) * 15 ); } for( x = 0; x < total_splines; x++ ) { if( Shair[x].select[0] ) memcpy( &Shair[x].noisev, &Shair[x].hv, sizeof( VERT ) * 15 ); } reset_noisespace( ); } static void recomb_select2( void ) { VERT direction; int x, y; int iterate; VERT a; //VERT tmpd; testvar = 0; mkHandles( ); for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] ) { int slct = 0; a.x = hair[x].hv[14].x - hair[x].hv[0].x; a.y = hair[x].hv[14].y - hair[x].hv[0].y; a.z = hair[x].hv[14].z - hair[x].hv[0].z; a = Vnorm( a ); if( VDot( a, hair[x].norm ) > .999 ) { a.x += .005; a.y -= .5; a.z -= .005; a = Vnorm( a ); } hair[x].norm = Vnorm( hair[x].norm ); a = Vcross( a, hair[x].norm ); a = Vnorm( a ); a = Vcross( hair[x].norm, a ); a = Vnorm( a ); // 1st check select for( y = 0; y < 15; y++ ) if( hair[x].select[y] ) slct = 1; // now make a straight one if( ( slct ) && ( hair[x].restlength > 0 ) ) { // if (group_stat[hair[x].mtl]<2) if( group_stat[hair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { hair[x].hv[y].x = hair[x].hv[y - 1].x + hair[x].restlength * a.x; hair[x].hv[y].y = hair[x].hv[y - 1].y + hair[x].restlength * a.y; hair[x].hv[y].z = hair[x].hv[y - 1].z + hair[x].restlength * a.z; } // no let's puff it up a bit // if (group_stat[hair[x].mtl]<2) if( group_stat[hair[x].mtl] == 0 ) for( y = 1; y < 15; y++ ) { float scalar; scalar = ( 14 - y ) / 14.0f; scalar *= scalar; // scalar -= .3; if( scalar < 0 ) scalar = 0; // scalar=pow(scalar,3.5); hair[x].hv[y].x = scalar * ( hair[x].hv[0].x + hair[x].norm.x * ( float ) y * hair[x].restlength * .5 ) + ( 1.0f - scalar ) * hair[x].hv[y].x; hair[x].hv[y].y = scalar * ( hair[x].hv[0].y + hair[x].norm.y * ( float ) y * hair[x].restlength * .5 ) + ( 1.0f - scalar ) * hair[x].hv[y].y; hair[x].hv[y].z = scalar * ( hair[x].hv[0].z + hair[x].norm.z * ( float ) y * hair[x].restlength * .5 ) + ( 1.0f - scalar ) * hair[x].hv[y].z; hair[x].lasthv[y] = hair[x].hv[y]; } // if (group_stat[hair[x].mtl]<2) // if (group_stat[hair[x].mtl]==0) // recalc_hair(x); } // slct } // x reset_dynamics( ); for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] ) { if( group_stat[hair[x].mtl] == 0 ) recalc_hair( x ); } reset_dynamics( ); for( x = 0; x < totalverts; x++ ) if( hair[x].select[0] ) { memcpy( &hair[x].resthv, &hair[x].hv, sizeof( VERT ) * 15 ); } reset_noisespace( ); } static void recomb_select( void ) { make_normals( ); make_spline_normals( ); if( splines < 0 ) recomb_select2( ); if( splines >= 0 ) Srecomb_select2( ); //recomb_select2(); } void NEWWFxplant( char file[555] ); extern void NEWxplant( char xfile[555] ) { //SHAVEPARMS sparms; int y; OPENGL_DRAW = 0; global_lastID = -1; if( undo ) free( undo ); undo = NULL; if( Sundo ) free( Sundo ); Sundo = NULL; freevox( ); { // at this point we do have a hairfile int x; //for (x=0;x= 0 ) make_spline_normals( ); for( y = 0; y < 5; y++ ) if( Gsurface_collide[y] == 1 ) DOCOLLIDE = 1; if( skull_sphere == -1 ) DOCOLLIDE = 0; if( DOCOLLIDE ) if( COLLISION_METHOD == 1 ) { make_normals( ); Dcalc_plane_eq( ); // norm is a unit vector setup_poly_vox( ); resize_poly_vox = 0; } if( DOCOLLIDE ) if( COLLISION_METHOD == 0 ) find_skulls( ); //OPENGL_DRAW=1; } extern void MTMAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret, GLOBS * gs ) { VERT offs; WFTYPE geom; int th = 0; int x; //float rr; int hc = 0; int hc2 = 0; //char tmp[255]; int tv = 0; //int didit; offs.x = 0; offs.y = 0; offs.z = 0; cret->killme = 1; if( ret->totalverts > 0 ) free_geomWF( ret ); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; geom.totalverts = 0; init_geomWF( ret ); init_geomWF( &geom ); // free_geom(ret); ret->totalverts = 0; ret->totalfaces = 0; ret->totalfverts = 0; if( LOCAL_PASSES[slg] > 0 ) current_samp = current_samp % LOCAL_PASSES[slg]; gs->GhairID = hairnum; // gs->Gcurpass = current_samp; // gs->cursamp = current_samp; // gs->passnumber = current_samp; cret->depthpass = gs->Gcurpass; cret->hairID = hairnum; gs->Gcurpass=current_samp; GhairID=hairnum; //Gcurpass=gs->cursamp; //current_samp=gs->cursamp; //printf ("slg = %d LOCAL_CNT[slg]=%d\n",slg,LOCAL_CNT[slg]);fflush(stdout); //printf ("MTmaya_make_a_curve\n"); if (freeze.totalverts==0) if( total_slgfaces[slg] > 0 ) if( LOCAL_CNT[slg] > 0 ) if( LOCAL_PASSES[slg] > 0 ) { int clones = 0; int q; Gcurpass = current_samp; //printf ("MTmake_spline_hair ..\n");fflush(stdout); clones = MTmake_spline_hair( slg, hairnum, 0, segs, &geom, cret, gs ); // printf("geom.totalverts=%d\n",geom.totalverts); // printf(" slg->%d\n",slg); // fflush(stderr); if( cret->killme == 0 ) { if( clones == 0 ) clones = 1; ret->totalverts = geom.totalverts * ( clones + 1 ); ret->totalfverts = geom.totalfverts * ( clones + 1 ); ret->totalfaces = geom.totalfaces * ( clones + 1 ); if( ret->totalverts > 0 ) alloc_geomWF( ret ); ret->totalverts = 0; ret->totalfverts = 0; ret->totalfaces = 0; // if (clones>0) for( q = 0; q < clones; q++ ) { int off, foff; int junk; if( q != 0 ) junk = MTmake_spline_hair( slg, hairnum, q, segs, &geom, cret, gs ); if( geom.totalverts > 0 ) { off = geom.totalverts * q; for( x = 0; x < geom.totalverts; x++ ) { ret->v[ret->totalverts] = geom.v[x]; ret->v[ret->totalverts].z *= -1.0f; ret->vn[ret->totalverts]=cret->norm; // ret->uv[ret->totalverts]=geom.uv[x]; ret->uv[ret->totalverts].x = cret->u; ret->uv[ret->totalverts].y = cret->v; ret->uv[ret->totalverts].z = geom.uv[x].z; if (GtipFade) ret->alpha[ret->totalverts] = 1.0-geom.uv[x].z; else ret->alpha[ret->totalverts] =1.0f; if (LOCAL_PASSES[slg]) ret->alpha[ret->totalverts]*=(1.0f/(float)LOCAL_PASSES[slg]); ret->velocity[ret->totalverts] = geom.velocity[x]; ret->velocity[ret->totalverts].z *= -1.0f; ret->color[ret->totalverts] = geom.color[x]; ret->totalverts++; } for( x = 0; x < geom.totalfverts; x++ ) { ret->facelist[ret->totalfverts] = geom.facelist[x] + off; ret->totalfverts++; } foff = geom.totalfverts * q; for( x = 0; x < geom.totalfaces; x++ ) { // off=geom.totalfaces*q; ret->index[ret->totalfaces] = geom.index[x]; ret->r1[ret->totalfaces] = cret->baserad; ret->r2[ret->totalfaces] = cret->tiprad; ret->id[ret->totalfaces]=hairnum; ret->face_start[ret->totalfaces] = geom.face_start[x] + off; ret->face_end[ret->totalfaces] = geom.face_end[x] + off; ret->totalfaces++; } // ret->mtlgroup[0]=geom.mtlgroup[0]; } } } free_geomWF( &geom ); // free_geom(&geom); } // if( 0 == 1 ) if( freeze.totalverts != 0 ) { // freeze is on // make_inst( slg, hairnum ); gs->Gslg=slg; xforminstMT(ret,hairnum,gs); //// if (matrixhair.dreadcount==0) if (0==1) { xforminst( 0 ); ret->totalverts = freeze.totalverts; ret->totalfverts = freeze.totalfverts; ret->totalfaces = freeze.totalfaces; alloc_geomWF( ret ); for( x = 0; x < freeze.totalverts; x++ ) { ret->v[x] = freezetmp.v[x]; ret->v[x].z = -ret->v[x].z; } for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].x = freezetmp.Rrvcolor[x]; for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].y = freezetmp.Rgvcolor[x]; for( x = 0; x < freeze.totalverts; x++ ) ret->color[x].z = freezetmp.Rbvcolor[x]; for( x = 0; x < freeze.totalfverts; x++ ) ret->facelist[x] = freeze.facelist[x]; for( x = 0; x < freeze.totalfaces; x++ ) ret->face_start[x] = freeze.face_start[x]; for( x = 0; x < freeze.totalfaces; x++ ) ret->face_end[x] = freeze.face_end[x]; } // dreadcount==0 } //memcpy(cret,&Gcurv,sizeof(CURVEINFO)); // this shouldn't be necessary .. if (freeze.totalverts==0) for( x = 0; x < ret->totalfaces; x++ ) { float tp; int y; tp = ( float ) ( ret->face_end[x] - ret->face_start[x] ); tp -= 1; if( tp < 1 ) tp = 1; for( y = ret->face_start[x]; y < ret->face_end[x]; y++ ) { ret->uv[ret->facelist[y]].z = ( float ) ( y - ret->face_start[x] ) / tp; } } cret->depthpass = current_samp; cret->hairID = hairnum; }