#ifndef shaveNEWSHAVE_h #define shaveNEWSHAVE_h // Shave and a Haircut // (c) 2019 Epic Games // US Patent 6720962 #include "shaveSDKALTNAMES.h" #ifdef DOUNICODE #include "windows.h" #define CHNG wchar_t #define _T(x) L ##x #endif #ifndef DOUNICODE #define CHNG char #define _T(x) x #endif #define RW_DISK 1 #define RW_LOCAL 2 #define RW_RESIZE 3 static int RW_CONTEXT = 1; void* GthreadGroup; int Gmax_geom_world= 1000000.0f; // occlussion culling for hair int Gmax_geom_screen= 01000000.0f; // occlussion culling for hair #include "version.h" static CHNG *version_info = _T(SHAVE_VERSION SHAVE_RELEASE); float Gvox_mult=1.1f; int Gtile_memory_limit=150; // MB int GtipFade=1; static int totalskulls = 0; void clear_uvsets( void ); void init_uvsets( void ); static int Gtransp_depth=30; static void *Gkd; //void *Gkd_stack[255]; //int *Gindex_stack[255]; static int Gclumps=0; static float Gflyaway_percent=0.0f; /// windows only - leak detection #define _CRTDBG_MAP_ALLOC #include #ifdef _WIN32 #include #endif #include "kdtree.h" #include "kdtree.c" int Gnative_lighting=0; void init_engine(void); float *global_zbuff; unsigned char *global_ibuff; // this is passed in for rendering into. #ifdef _WIN32 #include #endif #ifdef NOLIB #if defined(OSMac_MachO_) #include #else #include #endif #endif static void recomb_select( void ); static void DRAW_STATUS( char name[655] ); int collision_stat[4]; //int Gaccept_poly=0,Greject_poly=0; // int Guse_old_splayscale=0; #ifdef MAX3D #define progress_update 1 #endif int Gcurrent_time = 0; int Guse_restlength = 0; int Gmotion_samp = 1; #define ZTABLESIZE 124500 // it was 500 int junkycounter = 0; int undo_totalverts = -232; int Sundo_totalverts = -232; #include #include #include #include static CHNG Gname[264]; static int last_total_splines = -2; static int last_totalverts = -2; int make_undo = 0; static int GactivateGI = 0; static int Gdone = 0; void SHAVEactivateGI( int g ) { GactivateGI = g; } void *MYfopen( void *indata, CHNG *parms ); //static int cache_tile( int xx, int pass ); static int Gplog = 0; // this variable is the logged in/out // security variable for the prim lib static void read_hair34( void *fname ); static void fish_hair34( void *fp ); static int isnan_float( float x ); int DEGENERATE_OBJECT = 0; static void Jsrand( unsigned long seed ); static double drand98( void ); int stack_is_from_archive = 0; // // pick once. pick plus =1, pick minus =2 // int NOBLUR = 0; void clear_texcache( void ); static void flip_instances( void ); unsigned long rand98_seed = 0; static int Gaddsub = 0; static int Gdoswap = 1; static int GmaxThreads = -1; static void brush_button( void ); #define ZSGN(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0) #define SGN(a) (((a)<0) ? -1 : 1) // NOTE: shaveSDKALTNAMES.h *must* come before the other SDK includes //#include "shaveSDKALTNAMES.h" #include "shaveSDKTYPES.h" #include "shaveSDKFUNCS.h" #include "shaveSDKCALLBACKS.h" #include "mini_kernal_structs.h" #include "serializer.c" #include "kernal_entry.c" static ROOTPT *Gindex; typedef struct { VERT hv[15]; } CLUMPCURVE; //int *Gindex=NULL; extern void SHAVEset_tile_limit(int n,int t) { Gtile_memory_limit=n; if (t<2) t=2; Gtransp_depth=t; } /* Period parameters for rand number generators */ #define N11 334 #define M11 207 #define MATRIX_A 0x9908b0df /* constant vector a */ #define UPPER_MASK 0x80000000 /* most significant w-r bits */ #define LOWER_MASK 0x7fffffff /* least significant r bits */ /* Tempering parameters */ #define TEMPERING_MASK_B 0x9d2c5680 #define TEMPERING_MASK_C 0xefc60000 #define TEMPERING_SHIFT_U(y) (y >> 11) #define TEMPERING_SHIFT_S(y) (y << 7) #define TEMPERING_SHIFT_T(y) (y << 15) #define TEMPERING_SHIFT_L(y) (y >> 18) //static unsigned long mt[N11]; /* the array for the state vector */ //static int mti = N11 + 1; /* mti==N+1 means mt[N] is not initialized */ void SHAVEspline_recombXPLANT( SHAVENODE * sn, WFTYPE * wf ); static HAIRTYPE *outhair; void blit_buttonYELLOW( unsigned char *img, int px, int py, int x0, int y0, int x1, int y1 ); extern void SHAVEimport_archive_voxel_by_node( char *fname, int xxx, int yyy, int zzz, HAIRTYPE * hh, UVSETS * outuv, int isShadow, int node_id ); static void set_inst( WFTYPE * wf ); static void store_inst( WFTYPE * wf ); extern void SHAVEfree_UV( UVSETS * uv ); extern void SHAVEinit_UV( UVSETS * uv ); void reset_noisespace( void ); //static void actual_swapbuffers( void ); int SHAVEfetch_guideNOISE( int vertno, SOFTGUIDE * sg ); // Note: i had to ifdef shaveEngine.h out since it doesn't exist. // // Pierre Baillargeon, Innobec, 13 September 2006 #ifndef XSI_SOFT3D_ONLY #include "shaveEngine.h" #endif #define Nfree( a ) {if (a != NULL) {free( a );a=NULL;}} #define OLDKEY_SUCCESS 1 #define NEWKEY_SUCCESS 2 static float NaN = 0.0f; #ifdef ALTERNATE_DEFS void mi_info( const char *const, ... ); #endif static int isnan_float( float x ) { return ( 0 ); } // // Given the number of elements to be processed, returns the number of // threads to use and, optionally, the number of elements per thread. // static int getThreadSettings( int numElements, int *elementsPerThread ) { int nThreads; int nElemPerThread; // If GmaxThreads is negative that means to use one // thread per processor in the system. if( GmaxThreads < 0 ) nThreads = SHAVEnum_processors( ); else nThreads = GmaxThreads; // // No point in using more threads than we have elements to process. // if( nThreads >= numElements ) { nElemPerThread = 1; nThreads = numElements; } else if( nThreads > 1 ) { nElemPerThread = numElements / nThreads + 1; } else { nElemPerThread = numElements; nThreads = 0; } if( elementsPerThread ) *elementsPerThread = nElemPerThread; return nThreads; } static int Gtex_totalchannels[255][5]; static float *Gtex_cacheinfo[255][5]; static int Gtex_channellink[255][60]; extern void MTbunch_of_hairs(int list_total, int *inlist,int slg,int pass, WFTYPE *outwf,CURVEINFO *ci); extern void MTbunch_of_hairsINST(int list_total, int *inlist,int slg,int pass, WFTYPE *outwf,CURVEINFO *ci); FILE *Global_debug = NULL; static void aDRAW_ALL( void ); void make_spline_normals( void ); //// !!!! //// #include #include #include #include #ifdef DOS #include #endif static int GpickmodeON = 1; static void fish_hair( void *fp ); static int Grendermode = 0; static int Gnodraw = 0; static int Gclipz = 0; static int Gcamdirty = 1; static int NOCIRC = 0; static int Gget_depth = 0; // set this to capture depth during drawmodel static unsigned long global_lastID = -1; static void mkbounds( void ); static void blit( unsigned char *img, int px, int py ); static void blit_button( unsigned char *img, int px, int py, int x0, int y0, int x1, int y1 ); static int pick_toolbars( void ); #define DIAGNOSTIC 0 static void brushtagverts( void ); static void M_selmode_strands( void ); static void SIZE_BRUSH_TOOL_SETUP( void ); static void SIZE_BRUSH( void ); static void scrmask( int l, int r, int b, int t ); static void drawc( int, int, int ); static void reset_faces( void ); static void WFxplantNOMAT( CHNG file[555] ); static void WFxplant( CHNG file[555] ); static void NEWWFxplant( CHNG file[555] ); extern void NEWxplant( CHNG xfile[555] ); static int Gtrace = 0; static int BUISYDRAW = 0; static int Gview_dirty = 1; static int SHADOWS_DONE = 0; static void create_preview( void ); #ifdef _WIN32 unsigned long gethostid( void ); #endif #ifndef C4D #ifndef EXTERNAL_COLLISION #ifdef _WIN32 #ifndef MAX3D #ifndef MAYABETA //#include "hostid.c" #endif #endif //unsigned long gethostid(void); #endif #endif #endif #ifdef MAC //unsigned long gethostid(void); #endif #ifdef EXTERNAL_COLLISION #ifdef _WIN32 unsigned long gethostid( void ) { return ( 0 ); } #endif #endif #ifdef MAYABETA unsigned long gethostid( void ) { return ( 0 ); } #endif #ifndef C4D #ifndef _WIN32 #include #endif #endif #ifdef EXTERNAL_COLLISION VERT SHAVEapply_GI( VERT vv, CURVEINFO * ci ) { VERT t; t.x = 0.0f; t.y = 0.0f; t.z = 0.0f; return ( t ); } #endif #ifdef MAX3D #ifdef _WIN32 unsigned long gethostid( void ) { return ( 0 ); } #endif #endif static int MAYArender_camDUMMY( int antialiasing, int clipx0, int clipy0, int clipx1, int clipy1, int dice ); static int Gfast_eval = 0; static int Gdrag_hair = 0; #ifdef NOLIB static int Gmaps_active = 1; #endif #ifndef EXTERNAL_COLLISION #ifdef LIB static int Gmaps_active = 0; #endif #endif #ifdef EXTERNAL_COLLISION #ifdef LIB static int Gmaps_active = 1; #endif #endif #ifndef _MAC #ifndef ALTERNATE_DEFS int GLOBAL_VERBOSE = 1; #endif #ifdef ALTERNATE_DEFS int GLOBAL_VERBOSE = 0; #endif #endif static int resize_poly_vox = 0; static int Glow_mem = 0; #define NONE 0 #define CREATE_CACHE 1 #define PLAYBACK_CACHE 2 static int cachemode = NONE; static void nullify_maps( void ); /* find minimum of a and b */ #define MIN(a,b) (((a)<(b))?(a):(b)) /* find maximum of a and b */ #define MAX(a,b) (((a)>(b))?(a):(b)) /* swap a and b (see Gem by Wyvill) */ #define SWAP(a,b) { a^=b; b^=a; a^=b; } //#define _WIN32 1 //#define _MAC 1 /// build flags static int kkon = 1; static void init_poly_vox( void ); static void SNfree( void ); static void refresh_lights( void ); static void refresh_files( CHNG *hf, CHNG *sf, int inst ); static void GlutInit2( int xsize, int ysize ); static void freevox( void ); static void initvox( void ); static void freeverts(void); static void initverts(void); static int checkface( int i ); static float GlobalJitter = 0; static void setup_poly_vox( void ); static void collect_guides( void ); static void find_skulls( void ); #ifdef VOLUMETRICLW #include #include #include #include #include #include #include #include #include #include #include #include #include static const LWVolumeAccess *VGsa; #endif //// static void dyn_recalc_hair( int g ); static void recalc_hair( int g ); //double big_ass_table[1000000]; static int first_rand_gen = 1; static int jrandseed = 0; static void init_subdiv( void ); #define MAYAFLAG 1 static void center_selectNOLIB( void ); static void free_subdivs( void ); #ifndef RENDERLW #ifndef VOLUMETRICLW #define LWItemID int static int gt = 0; #endif #endif static void getorigin( int *, int * ); static void swapbuffers( void ); static void Jsrand( unsigned long seed ); static int GlutWin; static void joemain( void ); static void LWdraw_lotsINST( void ); static void getobj( CHNG * ); static void alloc_freeze( void ); static void save_scene( CHNG name[255] ); static int ENABLE_RADIOSITY = 0; #define onethree 1 static void sgenrand( unsigned long seed ); static float fsqrt( float ff ); static float global_shadow_density = 1.0f; static float global_hairshadow_density = 1.0f; static void M_draw_keys( void ) { } static void Srecalc_hair( int g ); #ifdef RENDERLW #ifndef VOLUMETRICLW #include "c:\loadmorf\sdk\include\splug.h" #include "c:\loadmorf\sdk\include\moni.h" #include "c:\loadmorf\sdk\include\lwran.h" //#include "c:\loadmorf\sdk\include\server.h" // //#include "c:\loadmorf\sdk\include\host.h" LWItemID Gcurrent_id; #endif #endif #include static float gascalh, gascalr; static float SELF_SHARP = 4; typedef struct { int seed; int shadow; char *filename; } RM_RENDERARGS; ////int haircount=5000; static int GlobalTime = 999999; #define WHT " \n\t" #define WHT2 " \n\t" static VERT *Gtex_cachedisplace[255][5]; void free_renderstate_stack(void); static float VDot( VERT, VERT ); typedef struct { float x, y, z; int clip; int clipz; } VERT2; static int Ginshad = 0; typedef struct { int xres, yres; Matrix view; Matrix iview; unsigned char *ibuff; unsigned char *lumbuff; float *geombuff; float *zbuff; float *ezbuff; float *Gzbuff; LWItemID id; float lwtime; VERT wpos; float aspect; float zoom; float nearclip; float sx, sy; int wind; VERT color; int xlight; int nospec; int nodiffuse; int radiosity; int caustics; char *name; char *filename; float fuzz; int shadsamps; int xrsq; unsigned int pixoffset; unsigned int ibound; unsigned int gbound; unsigned int zbound; VERT shadowcolor; int trace; int type; // 4.0 - 0=point 1=spot int blank; int isroot; VERT coneillum; float conefalloff; int zPage; int gPage; int timePage; int iPage; int cursamp; float fov; } LIGHTINFO; static LIGHTINFO LWCamOPEN; static LIGHTINFO LWCamCLOSE; static int first_dyn = 1; typedef struct { // char lable[255]; // int x, x1, y, y1; int stat; // int type; float value; float rangelow, rangehigh; // VERT bgcolor; // int paint; // int enable; // (*callback)(); } SLIDER; static void check_wmaps( void ); //typedef float Matrix[4][4]; #ifdef NOLIB static int OPENGL_DRAW = 0; #endif #ifndef NOLIB static int OPENGL_DRAW = 0; #endif //int getESCAPE(void); typedef struct { #ifdef NOLIB GLubyte *image; #endif int x, y; int xs, ys; } FRAMETYPE; typedef struct { #ifdef NOLIB GLfloat *image; #endif int x, y; int xs, ys; } DEPTHTYPE; typedef struct { unsigned char *r, *g, *b, *a; int width, height; unsigned char flags; // axis VERT bound1, bound2; char name[255]; } TGABUFF; static TGABUFF colmap[5]; static TGABUFF lenmap[5]; static TGABUFF densemap[5]; static int loopMODE = 0; #define ROTATE_MODEL 1 #define SIZE_SCULPT 2 #define SCULPTME 3 #define SHUTTLE 4 #define SHUTTLE_FORWARD 5 #define SHUTTLE_REVERSE 6 #define PERFORM 7 #define TEST_PERFORM 8 #define SHIFT_KEYS_BACK 9 #define FRAME_FORWARD 10 #define FRAME_REVERSE 11 #define TOGGLE_SOLID 12 #define REAL_PERFORM 15 #define KILLME3 13 #define KILLME2 12 #define KILLME1 11 #define PLAY_FORWARD 15 #define PLAY_REVERSE 16 #define POP 14 #define TOOLBOX 24 #define DYNAMICS 25 #define ROTATE_DYNAMICS 25 #define PREVIEW 20 #define PREVIEW_FORWARD 21 #define PREVIEW_REVERSE 22 #define FRAME_POS 23 #define SIZE_BRUSH 26 #define PICKED_ONE 27 #define TOOLBAR_DOWN 28 #define PAN_CAMERA 29 #define ZOOM_CAMERA 30 static int SOLID = 2; static int ENABLE = 0; static int GLOBAL_SOLID = 2; static int EXIT = 0; static int refresh_OGL = 0; static Matrix NewCamMatrix; static Matrix NewInvCamMatrix; static Matrix CamMatrix; static Matrix InvCamMatrix; static Matrix LgtMatrix; static Matrix InvLgtMatrix; static VERT vxmp( Matrix m, VERT vv ); #ifdef NOLIB static VERT vxm( Matrix, VERT ); #endif static float COST[800]; static float SINT[800]; #define XMAXSCREEN 1280 #define YMAXSCREEN 1024 #define DT_OFF 0 #define DT_ON 1 #define FLAT 0 #define GOURAUD 1 #define MVIEWING 0 #define LIGHT0 0 #define LIGHT1 1 #define MAT0 2 #define GL_3D_FONT_LIST 1000 #define SML_OFF 0 #define SML_ON 1 #define SML_END_CORRECT 2 #define SML_SMOOTHER 4 #define BF_ZERO 0 #define BF_ONE 1 #define BF_SA 2 #define BF_MSA 3 #define BF_DA 4 #define BF_MDA 5 #define BF_SC 6 #define BF_MSC 7 #define BF_DC 8 #define BF_MDC 9 #define BF_MIN_SA_MDA 10 static int drawall = 0; #define GLC_OLDPOLYGON 0 #define Scoord int #define Coord int #define Colorindex int static char group_name[98][255]; // Circle handler //GLUquadricObj *quadObj; typedef struct { float x1, y1, x2, y2; char lable[255]; int stat; } WIN; static void write_hair( void * ); static void write_hairFAST( MEMFILE * fname ); // from test.c static void mkbounds( void ); static void texture_bounds( void ); static VERT Vnorm( VERT v ); //#include "targaman.inc" #define MAXVERTS 65000 //#include // #include // #include static float drand50( int ); static double drand98( void ); #ifdef _WIN32 #include #endif // #include // #include #include // #include // #include #ifdef _WIN32 #include #endif /* performer stuff */ /* gl_joe stuff */ static int mode = 0; #ifdef TODO static float mat[] = { AMBIENT, .4, .4, .4, DIFFUSE, .9, .9, .9, SPECULAR, .2, .2, .2, SHININESS, 10, LMNULL, }; static float lm[] = { AMBIENT, 1, 1, 1, LOCALVIEWER, 1, TWOSIDE, 0, LMNULL }; static float lt1[] = { LCOLOR, 1.00, 1.0f, 1.0f, POSITION, -50, 60, 12, 0, LMNULL }; static float lt2[] = { LCOLOR, .47, .45, .44, POSITION, 50, -10, 14, 0, LMNULL }; #endif static void Mgetobj( CHNG *name ); /* load neutral model */ #define ENDS 1 #define STRANDS 2 #define VERTS 3 #define ROOTS 4 static void setup_MUSH( void ); // float cache[TOTALFRAMES][9700][3]; // int total_cacheverts=0; // hairstuff typedef struct { int link1, link2; float v; } ENVELOPETYPE; static long fmprstr( char *s ); typedef struct { VERT hv[15]; float select[15]; } SMALLBASEHAIR; typedef struct { int vid; // for basehairs only float uu, vv; VERT hv[15]; VERT lasthv[15]; VERT resthv[15]; VERT sparehv[15]; VERT velocity[15]; VERT noisev[15]; float select[15]; float restlength; float sparerestlength; short hide; int mtl; VERT color[15]; VERT norm; // Matrix //mat, imat; float stiffness; int pid; short slgroup; short killme; int hairnumber; int splitgroup; int splitmerge; float dreadroot, dreadtip, dreadcount, diffuse, spec, kspec, ambient, clumpfreq, kink, kinkfreq; float rootfrizz, tipfrizz; float frizzfreqX, frizzfreqY, frizzfreqZ; float kinkfreqX, kinkfreqY, kinkfreqZ; float randscale; float frizzanim; float animspeed; VERT animdir; int pfID[15]; // poly ID's for surf follow float w[15]; float cutlength; // char freechain; // int next; float slider[60]; float thickness; float thicknesstip; float kinkroot; float varval; float trim; VERT handle, resthandle; int curpass; // this is scratch really // new for 5.0 int Bid1,Bid2,Bid3; // 3 closest spline roots float bw1,bw2,bw3; // barycentric blends int index; // new for 5.5 float multasp; float offset; float aspect; float flyaway; float mess; float clump_strength; float clump_flatness; float clump_color_strength; float clump_rot_strength; float clump_rot_offset; int its_flyaway; float randomize; float clone; float scruffle; int neighbor_guide; }BASEHAIR; static int Gtotal_splinelocks=0; // previous total number of splined that have splinelock on them // we don't need these for rendering at all - only for setup. typedef struct { // new ones for multithreaded state BASEHAIR *hair; BASEHAIR *Shair; BASEHAIR *Shairvelocity; SLIDER sliders[60][6]; // don't free this int LOCAL_CNT[5]; int LOCAL_SHADCNT[5]; int LOCAL_PASSES[5]; int LOCAL_SEGS[5]; VERT *Dv; VERT *Dvn; VERT *v; VERT *vn; int *facelist; int *face_start; int *face_end; int totalfaces; int totalfverts; int totalverts; int *Dfacelist; int *Dface_start; int *Dface_end; int Dtotalfaces; int Dtotalfverts; int Dtotalverts; int *face_link; int *D2UTface_link; int *Dlink; int *slgfaces[5]; int total_slgfaces[5]; // these need to be done int *vlink; WFTYPE Guv_sets[70]; int Guv_link[70]; int Guv_totalsets; int DUTtotalfaces; int total_splines; int Gdontinterp; BASEHAIR *Sresthair; int nodeID; unsigned long SHAVEID; int head; int beard; int eyebrow; int eyelash; int splines; double *poly_weight; float *Dpoly_weight; LIGHTINFO *current_cam; int Gclipx0,Gclipx1; int Gclipy0,Gclipy1; int itsalight; int TILEMODE; float restBOUNDLENGTH; float BOUNDLENGTH; VERT Gspec_tint; VERT Gspec_tint2; float Gbacklighting; float calibrateX, calibrateY; int genON; int DEGENERATE_OBJECT; int Gsquirrel; // kd tree stuff void *Gkd; ROOTPT *Gindex; int random_seed_offset; int Gclumps; VERT Gdisplace; float Gflyaway_percent; WFTYPE freeze; } RENDERSTATE; static void init_renderstate(RENDERSTATE *gl); static void pop_renderstate(RENDERSTATE *rs); static RENDERSTATE *Grender_state; typedef struct { int hairnumber; int passnumber; int cursamp; BASEHAIR MTLOTSWFlastone; // definitely need these BASEHAIR MTLOTSWFlasthrest; BASEHAIR MTLOTSWFlastclump; int MTLOTSWFlastpid; CURVEINFO MTLOTSWFlastcinfo; unsigned long mt[N11]; /* the array for the state vector <- rand number generators */ int mti; // = N + 1; /* mti==N+1 means mt[N] is not initialized <- rand number generators */ int sgenrand_been_seeded; int Gslg; int GhairID; int threadID; VERT MTT2[15]; int segs; #if defined(_WIN32) && (_MSC_VER < 1400) //#ifndef NEWRAND double x[5]; #else unsigned int x[5]; #endif int Gcurpass; RENDERSTATE rs; LIGHTINFO tilebuff; int curtile; CURVEINFO ci; int total_hairs; int tilequeue; unsigned long lastSeed; int density_correct; unsigned long random_seed_offset; } GLOBS; int Grandom_seed_offset=0; static float dither2RS( float in,GLOBS *gs); static void push_renderstate(GLOBS *gs, int push_hair); static void init_clumping(); static void free_clumping(); void init_clumping_stack(); #define SHAVE_MAX_THREADS 512 GLOBS gthreads[SHAVE_MAX_THREADS]; int threads_been_initialized = 0; static ShaveMutex Gtile_render_mutex; typedef signed long int32; //#ifndef OSMac_ #ifndef _UINT32 //vlad|10Jun2010 - MacOSX10.5.sdk defines it typedef unsigned long uint32; #endif double MOdrand( GLOBS * gs ); void MOsrand (uint32 seed, GLOBS * gs); static void init_threads( void ) { int x; //printf ("initializing threads\n");fflush(stdout); if( threads_been_initialized == 0 ) for( x = 0; x < SHAVE_MAX_THREADS; x++ ) { gthreads[x].density_correct=1; gthreads[x].threadID=x; gthreads[x].sgenrand_been_seeded = 0; gthreads[x].random_seed_offset=0; gthreads[x].mti=0; gthreads[x].lastSeed=0; if( threads_been_initialized == 0 ) gthreads[x].mti = N11 + 1; /* mti==N+1 means mt[N] is not initialized <- rand number generators */ // init_engine(); if( threads_been_initialized == 0 ) init_renderstate(>hreads[x].rs); // push_renderstate(>hreads[x].rs); // pop_renderstate(>hreads[x].rs); } SHAVEmutex_create( &Gtile_render_mutex ); threads_been_initialized = 1; //printf ("done threads\n");fflush(stdout); } static void init_thread( GLOBS *gs ) { int x; { gs->density_correct=1; gs->threadID=0; gs->random_seed_offset=0; gs->sgenrand_been_seeded = 0; gs->mti = N11 + 1; /* mti==N+1 means mt[N] is not initialized <- rand number generators */ init_renderstate(&gs->rs); } } void destroy_threads( void ) { SHAVEmutex_destroy( &Gtile_render_mutex ); } void composite_pixel(LIGHTINFO *cam,int add, int addi) { int x; float r=0.0f; float g=0.0f; float b=0.0f; float a=0.0f; float z= 1000000.0f; int tm; int add1; int baseadd,baseadd4; for (tm=0;tmtimePage*tm; baseadd4=baseadd*4; add1=add+baseadd; if (addzPage) if (add>=0) { r=0.0f; g=0.0f; b=0.0f; a=0.0f; for (x=Gtransp_depth-1;x>=0;x--) { float alpha,ia; add1=add+cam->zPage*x+baseadd; addi1=addi+cam->iPage*x+baseadd4; ib= &cam->ibuff[addi1]; if ((*(ib+3))>0) { zb= &cam->zbuff[add1]; alpha=(float)(*(ib+3)); alpha/=255.0; ia=1.0-alpha; r=(float)(*(ib))*alpha+r*ia; g=(float)(*(ib+1))*alpha+g*ia; b=(float)(*(ib+2))*alpha+b*ia; if (r>255.0f) r=255.0f; if (g>255.0f) g=255.0f; if (b>255.0f) b=255.0f; a=(float)(*(ib+3))+a*ia; if (a>255.0f) a=255.0f; if (*zbibuff[addi+baseadd4]; zb= &cam->zbuff[add+baseadd]; (*(ib))=(unsigned char) r; (*(ib+1))=(unsigned char) g; (*(ib+2))=(unsigned char) b; (*(ib+3))=(unsigned char) a; cam->zbuff[add+baseadd]=z; } } r=0;g=0;b=0;a=0;z=1000000.0f; for (x=0;xtimePage; add4=add1*4; r+=cam->ibuff[add4]; g+=cam->ibuff[add4+1]; b+=cam->ibuff[add4+2]; a+=cam->ibuff[add4+3]; if (cam->zbuff[add1]zbuff[add1]; } cam->ibuff[addi]=(unsigned char) (r/(float)Gmotion_samp); cam->ibuff[addi+1]=(unsigned char) (g/(float)Gmotion_samp); cam->ibuff[addi+2]=(unsigned char) (b/(float)Gmotion_samp); cam->ibuff[addi+3]=(unsigned char) (a/(float)Gmotion_samp); cam->zbuff[add]=z; } void SHAVEsustained_spline_recomb( SHAVENODE * sn, WFTYPE * wf ); void SHAVEsplinelock_set( SHAVENODE * sn, WFTYPE * wf ); void SHAVEsplinelock(SHAVENODE *sn,WFTYPE *wf) { if (wf->totalverts>0) { if (Gtotal_splinelocks!=wf->totalverts) SHAVEsplinelock_set(sn,wf); else SHAVEsustained_spline_recomb(sn,wf); } } void push_pixel(LIGHTINFO *cam,int add,int addi, float r, float g, float b, float a, float z,int layer) { int baseadd; int baseadd4; int gbaseadd; int tm; int add1r,add4r; // Gtransp_depth Gmotion_samp // cam->iPage cam->zPage cam->gPage // search for spot where z fits, if it's in the stack push it int add1,gadd1; int x=0; int done=0; if (r<0.0f) r=0.0f; if (r>255.0f) r=255.0f; if (g<0.0f) g=0.0f; if (g>255.0f) g=255.0f; if (b<0.0f) b=0.0f; if (b>255.0f) b=255.0f; if (a<0.0f) a=0.0f; if (a>255.0f) a=255.0f; tm=cam->cursamp; tm=layer; gbaseadd=cam->zPage*tm; baseadd=cam->timePage*tm; baseadd4=baseadd*4; gadd1=add+gbaseadd; while (done==0) { int add4; add1=add+baseadd; add4=addi+baseadd4; add1r=x*cam->zPage+add1; add4r=x*cam->iPage+add4; // printf ("z = %f buff = %f\n",z,cam->zbuff[add1+cam->zPage*x]); fflush(stdout); if ((zzbuff[add1+cam->zPage*x])) // ||(cam->zbuff[add1+cam->zPage*x]==1000000)) if ((zgeombuff[gadd1]))// ||(cam->zbuff[add1+cam->zPage*x]==1000000)) //is this necessary????????? { unsigned char *p1,*p2,*pix1,*pix2; float *zz1,*zz2; int ppq,ppq1; int ppqz,ppqz1; int pp; int ip,zp; unsigned char *ib; //push pp=Gtransp_depth-1; ppq=pp * cam->iPage+add4; ppq1=(pp-1) * cam->iPage+add4; ppqz=pp * cam->zPage+add1; ppqz1=(pp-1) * cam->zPage+add1; ip=cam->iPage; zp=cam->zPage; p1= &cam->ibuff[ppq]; p2= &cam->ibuff[ppq1]; pix1= p1; pix2= p2; zz1= &cam->zbuff[ppqz]; zz2= &cam->zbuff[ppqz1]; if (*(p1+3)>0) // there's alpha, so we're pushing one off the end { // so instead lets comp it float rr,gg,bb,aa; float r1,g1,b1,a1; float ia; rr=(float)(*(p2)); gg=(float)(*(p2+1)); bb=(float)(*(p2+2)); aa=(float)(*(p2+3)); aa/=255.0f; r1=(float)(*(p1)); g1=(float)(*(p1+1)); b1=(float)(*(p1+2)); a1=(float)(*(p1+3)); a1/=255.0f; ia=1.0-aa; rr=rr*aa+r1*ia; gg=gg*aa+g1*ia; bb=bb*aa+b1*ia; aa=255.0*aa+255.0*a1*ia; if (rr>255.0f) rr=255.0f; if (gg>255.0f) gg=255.0f; if (bb>255.0f) bb=255.0f; if (aa>255.0f) aa=255.0f; if (rr<0.0f) rr=0.0f; if (gg<0.0f) gg=0.0f; if (bb<0.0f) bb=0.0f; if (aa<0.0f) aa=0.0f; *(p2)=(unsigned char)rr; *(p2+1)=(unsigned char)gg; *(p2+2)=(unsigned char)bb; *(p2+3)=(unsigned char)aa; } for (pp=Gtransp_depth-1;pp>x;pp--) { pix1= p1; pix2= p2; if (*(pix2+3)>0) { *pix1= *pix2; //r pix1++;pix2++; *pix1= *pix2; //g pix1++;pix2++; *pix1= *pix2; //b pix1++;pix2++; *pix1= *pix2; // a *zz1= *zz2; } p1-=ip; p2-=ip; zz1-=zp; zz2-=zp; // cam->ibuff[ppq] = cam->ibuff[ppq1]; // cam->ibuff[ppq+1] = cam->ibuff[ppq1+1]; // cam->ibuff[ppq+2] = cam->ibuff[ppq1+2]; // cam->ibuff[ppq+3] = cam->ibuff[ppq1+3]; // cam->zbuff[ppqz] = cam->zbuff[ppqz1]; } //if (r>255.0f) r=255.0f; assume it's been clipped //if (g>255.0f) g=255.0f; //if (b>255.0f) b=255.0f; //if (a>255.0f) a=255.0f; //if (r<0.0f) r=0.0f; //if (g<0.0f) g=0.0f; //if (b<0.0f) b=0.0f; //if (a<0.0f) a=0.0f; ib = &cam->ibuff[add4r]; (*(ib))= (unsigned char) (r); (*(ib+1))=(unsigned char) (g); (*(ib+2))=(unsigned char) (b); (*(ib+3))=(unsigned char) (a); cam->zbuff[add1r]=z; done=1; } x++; if (x>Gtransp_depth-1) done=1; } } void push_pixelHRM(LIGHTINFO *cam,int add,int addi, float r, float g, float b, float a, float z,int layer) { int baseadd; int baseadd4; int gbaseadd; int tm; int add1r,add4r; int ir,ig,ib,ia; // Gtransp_depth Gmotion_samp // cam->iPage cam->zPage cam->gPage // search for spot where z fits, if it's in the stack push it int add1,gadd1; int x=0; int done=0; unsigned char *ibb; tm=cam->cursamp; tm=layer; gbaseadd=cam->zPage*tm; baseadd=cam->timePage*tm; baseadd4=baseadd*4; gadd1=add+gbaseadd; while (done==0) { int add4; add1=add+baseadd; add4=addi+baseadd4; add1r=x*cam->zPage+add1; add4r=x*cam->iPage+add4; // printf ("z = %f buff = %f\n",z,cam->zbuff[add1+cam->zPage*x]); fflush(stdout); if ((zzbuff[add1r])) // ||(cam->zbuff[add1+cam->zPage*x]==1000000)) if ((zgeombuff[gadd1])) // ||(cam->zbuff[add1+cam->zPage*x]==1000000)) { unsigned char *p1,*p2,*pix1,*pix2; float *zz1,*zz2; int ppq,ppq1; int ppqz,ppqz1; int pp; int ip,zp; //push pp=Gtransp_depth-1; ppq=pp * cam->iPage+add4; ppq1=(pp-1) * cam->iPage+add4; ppqz=pp * cam->zPage+add1; ppqz1=(pp-1) * cam->zPage+add1; ip=cam->iPage; zp=cam->zPage; p1= &cam->ibuff[ppq]; p2= &cam->ibuff[ppq1]; pix1= p1; pix2= p2; zz1= &cam->zbuff[ppqz]; zz2= &cam->zbuff[ppqz1]; if (*(p1+3)>0) // there's alpha, so we're pushing one off the end { // so instead lets comp it float rq,gq,bq,aq; float r1,g1,b1,a1; float ia; rq=(float)(*(p2)); gq=(float)(*(p2+1)); bq=(float)(*(p2+2)); aq=(float)(*(p2+3)); aq/=255.0f; r1=(float)(*(p1)); g1=(float)(*(p1+1)); b1=(float)(*(p1+2)); a1=(float)(*(p1+3)); a1/=255.0f; ia=1.0-aq; rq=rq*aq+r1*ia; gq=gq*aq+g1*ia; bq=bq*aq+b1*ia; aq=255.0*a+255.0*a1*ia; if (rq>255) rq=255.0; if (gq>255) gq=255.0; if (bq>255) bq=255.0; if (aq>255) aq=255.0; if (rq<0.0f) rq=0.0f; if (gq<0.0f) gq=0.0f; if (bq<0.0f) bq=0.0f; if (aq<0.0f) aq=0.0f; *(p2)=(unsigned char)rq; *(p2+1)=(unsigned char)gq; *(p2+2)=(unsigned char)bq; *(p2+3)=(unsigned char)aq; } for (pp=Gtransp_depth-1;pp>x;pp--) { pix1= p1; pix2= p2; *pix1= *pix2; //r pix1++;pix2++; *pix1= *pix2; //g pix1++;pix2++; *pix1= *pix2; //b pix1++;pix2++; *pix1= *pix2; // a *zz1= *zz2; p1-=ip; p2-=ip; zz1-=zp; zz2-=zp; } if (r>255.0f) r=255.0f; if (g>255.0f) g=255.0f; if (b>255.0f) b=255.0f; if (a>255.0f) a=255.0f; if (r<0.0f) r=0.0f; if (g<0.0f) g=0.0f; if (b<0.0f) b=0.0f; if (a<0.0f) a=0.0f; ibb= &cam->ibuff[add4r]; (*(ibb)) = (unsigned char) (r); (*(ibb+1))=(unsigned char) (g); (*(ibb+2))=(unsigned char) (b); (*(ibb+3))=(unsigned char) (a); cam->zbuff[add1r]=z; done=1; } x++; if (x>Gtransp_depth-1) done=1; } } static unsigned long MTgenrand( GLOBS * gs ); static BASEHAIR MTgen_resthair_ROOT( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); static BASEHAIR MTgen_resthair_ROOTRS( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); double MTdrand98( GLOBS * gs ); static void MTsgenrand( unsigned long seed, GLOBS * gs ); BASEHAIR MTgen_hair( int id, int slg, GLOBS * gs ); BASEHAIR MTgen_resthair( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); BASEHAIR MTgen_hairRS( int id, int slg, GLOBS * gs ); BASEHAIR MTgen_resthairRS( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); double MTdrand98( GLOBS * gs ); static void MTJsrand( unsigned long seed, GLOBS * gs ); static void MTdisplace_randscale( BASEHAIR * h, GLOBS * gs ); static void MTcolor_a_hair( BASEHAIR * h, GLOBS * gs ); static void MTcolor_a_hairSOFT( BASEHAIR * h, GLOBS * gs ); static void MTdraw_lotsWF( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * glots ); static void MTdraw_lotsWF2( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * glots ); static void MTdraw_lotsWFRS( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * glots ); static int MTcheckface( int i, GLOBS * gs ); static void draw_lotsWF2( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo ); static void end_paintmode( void ); static void setup_toolbars( void ); static void M_sproing( void ); typedef struct { int vid; // for basehairs only VERT hv[80]; VERT velocity[80]; float select[80]; float restlength; int hide; int mtl; VERT color[80]; VERT normal[80]; VERT norm; Matrix mat, imat; float stiffness; int pid; int slgroup; int segs; int hairnumber; float dreadroot, dreadtip, dreadcount, diffuse, spec, kspec, ambient, rootfrizz, tipfrizz, clumpfreq, kink, kinkfreq; float cutlength; ENVELOPETYPE envelope; float width[80]; int killme; float thickness; float thicknesstip; float uu, vv; // global u,v } RENDERHAIR; static RENDERHAIR cut_single_hair( RENDERHAIR hh ); static int DEEP = 0; typedef struct { int totalverts; int totalfaces; int totalfverts; VERT *vn; VERT *velocity; ENVELOPETYPE *envelope; int *facelist; int *face_start; int *face_end; int *mtlgroup; float *rvcolor; float *gvcolor; float *bvcolor; float *Rrvcolor; float *Rgvcolor; float *Rbvcolor; VERT *v; VERT *uv; int haircount; RENDERHAIR *h; int *colorlock; int textoggle; } FREEZETYPE; static CURVEINFO *cinfo_cache = NULL; static void metafixchains( void ); static void metaunfixchains( void ); static void regroup( void ); static void Dfreeverts( void ); static void Dinitverts( void ); static void center_select( void ); static void read_hair( void *fname ); static void read_hairFAST( MEMFILE * fname ); static VERT vxm( Matrix, VERT ); static void gethair( char name[500] ); static void reset_faces( void ); static void checkforzero( void ); static void free_freeze( void ); void init_a_hair( BASEHAIR * base ); typedef struct { Matrix zero2world[15]; Matrix world2zero[15]; VERT pos[15]; } BASEMATRIX; typedef struct { Matrix rest2zero[80]; Matrix zero2world[80]; VERT restpos[80]; VERT velocity[80]; VERT worldpos[80]; VERT color[80]; float rad[80]; int mtl; float restlength; float dreadroot, dreadtip, dreadcount, diffuse, spec, kspec, ambient, rootfrizz, tipfrizz, clumpfreq, kink, kinkfreq; float cutlength; int hairnumber; int slg; float spanx; float spanz; float spany; VERT norm; float thickness; float thicknesstip; int pid; int vid; float uu; float vv; int killme; } MATRIXHAIRTYPE; static float Distance( VERT a, VERT b ); static void mk_polymat( Matrix m, int n ); static void mk_polymat2( Matrix m, int n,VERT handle ); typedef struct { VERT p[4], c[4], v[4]; VERT w[4], wv[4]; float rad[4]; float alpha[4]; int clip[4]; } POLYDAT; typedef struct { unsigned char x, y, z; } VC; typedef struct { VERT v[3]; unsigned char alpha[3]; VC c[3]; VERT p[3]; } POLYDATSM; void sm2poly( POLYDATSM * in, POLYDAT * out ); void poly2sm( POLYDAT * in, POLYDATSM * out ) { int x; for( x = 0; x < 3; x++ ) { int q; VERT2 tmp; q = x; if( q == 3 ) q = 0; out->p[q] = in->p[x]; out->v[q] = in->v[x]; out->c[q].x = ( unsigned char ) ( ( float ) in->c[x].x ); out->c[q].y = ( unsigned char ) ( ( float ) in->c[x].y ); out->c[q].z = ( unsigned char ) ( ( float ) in->c[x].z ); out->alpha[q] = ( unsigned char ) ( ( float ) in->alpha[x] ); } } typedef struct { int *plist; int totalp; } OVOX; static int genON = 1; static int draw_poly3d( POLYDAT tri, int cs, unsigned char lum ); static int draw_poly3dRS( POLYDAT tri, int cs, unsigned char lum,GLOBS *gs ); static int draw_poly( POLYDAT tri, int cs, unsigned char lum ); static int draw_polyRS( POLYDAT tri, int cs, unsigned char lum,GLOBS *gs ); static int draw_poly2( POLYDAT, int, unsigned char ); static int draw_poly2RS( POLYDAT, int, unsigned char,GLOBS *gs ); static VERT cam2world1( LIGHTINFO * cam, VERT in ); typedef struct { int Dface; VERT bary; } BARY; typedef struct { BARY *plist; int totalp; } SVMAP; typedef struct { int x1, y1, x2, y2; unsigned int *polyhits; unsigned int *hairhits; unsigned int *passhairhits; unsigned int *slghairhits; unsigned int *nodehairhits; unsigned int nodeids[5255]; // watch out static unsigned int totalnodes; unsigned int totalhits; unsigned int totalpolyhits; unsigned int sizehairhits; unsigned int sizepolyhits; int tag; int active; int triangles; int dirty; int triangle_limit; POLYDATSM *triangle_cache; } TILETYPE; typedef struct { TILETYPE *tile; int totaltiles; int sx, sy; WFTYPE *occlude; int dice; } ALLTILES; //typedef stuct { /* object info */ static RM_RENDERARGS RM_RENDERFLAGS; static int init_login = 1; static int GIThairfile = 0, GITlasthairfile = -1; static int GIThairnumber = 0; static int GITpassnumber = 0; static int TEXCACHEMODE = 0; static float Gtex_info[60]; static int Gbeen_scaled = 0; // used in reset_noisespace static int GLOBALSAMP = 1; static float Gbacklighting = 1.0f; static int noise_been_done = 0; static int Gsquirrel=0; static int sgenrand_been_seeded = 0; static int group_stat[555]; #ifndef RENDERLW static int Gshade_polys = 0; static int Gdraw_to_geom_layer = 1; static int Galpha_object = 1; #endif #ifdef RENDERLW static int Gshade_polys = 1; static int Gdraw_to_geom_layer = 0; static int Galpha_object = 0; #endif #ifdef NOLIB static GLubyte *bgbuffer = NULL; #endif static int Gdynamics_mode = 0; static FRAMETYPE workarea; static DEPTHTYPE workz; static float calibrateX = 0.0f, calibrateY = 0.0f; //int totallines= 0; static char G_model_name[255]; static char G_poses_name[255]; static float BOUNDX; static float BOUNDY; static float BOUNDZ; static float BOUND1X; static float BOUND1Y; static float BOUND1Z; static int BIGDRAW = 1; static int ALWAYS_SOLID = 1; static int M_channel_total_passes = 0; static int valuator[512]; static int add_toolbar( char **lables, int *positions, unsigned char *inimage, unsigned char *inimageROLLOVER, unsigned char *inimageON, int items, int xoff, int yoff, float compress ); static int mainbar = -1; static int mainbar725 = -1; static int mainbar950 = -1; static int mainbarsm = -1; static int mainbartiny = -1; static int Gcurrent_toolbar = -1; static void edit_undo( void ); static BASEHAIR *base_cache = NULL; static int total_base_cache = 0; static int current_cachehair = 0; static int paintmode = -1; static void Dweight_polys( void ); static double *poly_weight = NULL; static float *Dpoly_weight = NULL; static SMALLBASEHAIR *undo = NULL; static SMALLBASEHAIR *Sundo = NULL; static void undo_op( void ); static void clear_undo( void ); //VERT *v=NULL; static VERT *bk = NULL; static int realsamp; static int rot_cursor_stat = 0; static int rot_root_stat = 0; static int trans_stat = 1; static int inflate_stat = 0; static int smooth_stat = 0; static int twist_stat = 0; static int neutral_stat = 0; static int clump_stat = 0; static int scale_stat = 0; static int stand_stat = 0; static int puff_stat = 0; void xformHandles( void ); void mkHandles( void ); //static void ADD_FILLER_TOOL(int n,BUTTON f); static void xformcontrolhair_nodyn( void ); static void xformcontrolhair( void ); //static void ADD_POPUP_TOOL(int n,POPUP_TOOL *pop); static BASEHAIR *hairbuffer = NULL; static BASEHAIR *hair = NULL; //static BASEHAIR *hairvelocity=NULL; //static BASEHAIR *lasthair=NULL; //static BASEHAIR *thishair=NULL; //static BASEHAIR *resthair=NULL; static BASEHAIR *Shair = NULL; static BASEHAIR *Slasthair = NULL; static BASEHAIR *Shairvelocity = NULL; static BASEHAIR *Sresthair = NULL; static BASEHAIR *Sthishair = NULL; static int total_splines = 0; static int *splinelist = NULL; // face refferenced list of splines static void Dregroup( void ); static void Dregroup2( void ); static void Gilluminate_strandINST( WFTYPE * pos, int ll, float hambient ); static float Distance( VERT a, VERT b ); static float distance( VERT a, VERT b ); static void Srepulse_hair( int g ); static void Irelight( void ); static void Srepulse_hair9( int g ); static void Sdodyn3( void ); static int StopTimer( ); static unsigned int StartTimer( void ); static void Stagverts( void ); static void Srestore_locked_hair( int g ); static void Salloc( int divs ); static void Smake_normals( void ); static void Sdyn_recalc_hair( int g ); //static MAKE_POPUP_TOOL (char lable[255],POPUP_TOOL *p); static void MYfread( void *indata, int sz, int rep, void *fpointer ); static void MYreset( MEMFILE * fp ); static void MYfclose( void *indata ); static void MYfwrite( void *indata, int sz, int rep, void *fpointer ); static void Imake_normals( void ); static void LWIrelight( void ); static float Jdither( void ); static float *tagvert = NULL; //static VERT lg, lgworld; static int *vert2guide=NULL; static int *guide2vert=NULL; static VERT *v = NULL; static VERT *vn = NULL; static void IdleFunc( void ); static VERT *vnrest = NULL; static VERT *neutral = NULL; static int *pbtag = NULL; static int *facelist = NULL; static int *face_start = NULL; static int *face_link = NULL; //int *line_start=NULL; //int *line_end=NULL; //int *line_faceref=NULL; static int *face_end = NULL; static int *vertgroup = NULL; static int *mtlgroup = NULL; static float *rvcolor = NULL; static float *gvcolor = NULL; static float *bvcolor = NULL; static int *vlink = NULL; //static float *ucord = NULL; //static float *vcord = NULL; static int *Duvfacelist = NULL; static int *Duvface_start = NULL; static int *Duvface_end = NULL; static int Duvtotalfaces = 0; static int Duvtotalfverts = 0; static int Duvtotalverts=0; static float *Ducord = NULL; static float *Dvcord = NULL; static float *Drvcolor = NULL; static float *Dgvcolor = NULL; static float *Dbvcolor = NULL; static float *RDrvcolor = NULL; static float *RDgvcolor = NULL; static float *RDbvcolor = NULL; static VERT *Dface_norm = NULL; static float *DD = NULL; static MEMFILE *Gmemfile; static WIN PW[95]; static WIN W[55]; static WIN performance_group_buttons[9]; static int dialbutstat[55][2]; static int M_keybutstat[55]; static int subdiv = 0; static float poffx, poffy; static float coffx, coffy; static float loffx, loffy; static int flip_norms = 0; //static float rtable[115124]; static int channel_enable[9]; static int G_current_pass = 1; static int current_performance_group = 0; static float noise[20][20][20]; static VERT campass[1400]; static int first_sculpt = 1; static int newMODE = 0; static char laststat[655]; static int first_redraw = 1; static int refresh_dials = 1; static int G_center_select = -1; static int broke = 0; static int GMetaNurb = 0; static int Gextrasamp = 1; static int GextrasampLIGHT = 1; static int oversamp = 1; static int Gcurpass; static int rand59_seed = 0; static int rand69_seed = 0; static int Gcurrent_poly = 0; static int Glast_poly = 0; static int uvtotalfaces = 0; static int qpassnumber; static int global_lores = 0; static int twister_fire = 0; static int pointdraw = 1; static int dither_seed = 0; static float luminous, diff; static double mirror; static float global_scale = 1.0f; static char shaveversion = 0; static float global_fuzz = 0.0f; static float global_twister_speed; static float restBOUNDLENGTH = 1.0f; static int shademe = 0; static int totalverts = -1; static int totalguides = -1; static int test_stat = 0; static int orbit_stat = 0; static int pan_stat = 0; static int zoom_stat = 0; static int drag_stat = 1; static int style_stat = 0; static int brush_stat = 1; static int SXRES = 1180; static int SYRES = 1024; static int addsub = 0; /* camera info */ static float cam_scale = 1.5f; static float cam_panx = 0.0f; static float cam_pany = 0.0f; static float cam_panz = 0.0f; static float post_panx = 0; static float post_pany = 0; static float cam_rot[3]; static char psvs[255]; static VERT sculpt; static int G_MOUSEX, G_MOUSEY; static int kps; static char kkk[255]; static VERT inverseshad; static VERT oldwork1, oldwork2; static VERT work1, work2; static VERT global_tlit; static VERT2 world2cam( LIGHTINFO * cam, VERT2 in ); static VERT2 cam2world( LIGHTINFO * cam, VERT2 in ); static VERT lightdirection; // global static VERT shave_illuminate( VERT in, int ll, VERT vnn ); SLIDER sliders[60][6]; static int rand48_seed = 0; static VERT Ganim_dir[5]; static int Dtotalfaces = 0; static int Dtotalverts = 0; static int Dtotalfverts = 0; static VERT *Dv = NULL; static VERT *Drv = NULL; static VERT *Dvn = NULL; static int *Dfacelist = NULL; static int *Dface_start = NULL; static int *Dface_end = NULL; static int *Dvertgroup = NULL; static int *Dvertlink = NULL; static int *Dmtlgroup = NULL; static int *Dtag = NULL; static int *Dlink = NULL; static int *Dflink = NULL; static int *D2UTface_link = NULL; static int *DUTmtlgroup = NULL; static int *DUTfacelist = NULL; static int *DUTface_start = NULL; static int *DUTface_end = NULL; static int *DUTofaceID = NULL; static int DUTtotalfaces = 0; static int DUTtotalfverts = 0; static int minsamps, samps, cursamp = 0; static char BKcolor[255]; static int previewimage = 0; static int itsalight = 0; static int beard = -1; static int eyebrow = -1; static int eyelash = -1; static int head = -1; static int splines = -1; static int skull_sphere = -1; static int colorlock = -1; static int totalENABLEDverts = 0; static int totalfverts = 0; static int totalfaces = 0; static int totalgroups = 0; static int current_group; static char group_names[555][255]; static int group_enable[555]; static int selmode = 1; static int totalsplits; static MATRIXHAIRTYPE matrixhair; static SHAVENODE Gswatch; static int DOING_SWATCH = 0; static VERT Gdisplace; static char hairfile[255]; static char statfile[255]; static float BOUNDLENGTH; static FREEZETYPE freeze, freezetmp, freezetmp1, freezetmp2; //} GLOBALS; static char gPATH[512]; static int totallights = 0; static int Gcachehair = 0; static int Gtotal_cachehair = 0; //#ifdef LIB static float lumcol[3]; static int lockfordraw = 0; static float gravity = 1.0f; static FILE *Glog = NULL; static int genlog = 0; static int do_filter = 0; static int Gcurrent_extrasamp = 0; //#endif static int LWLIGHTBUFFERRES = 600; static VERT first_cast, first_self; static int ZORPIXFILTER = 0; static int global_bwshad = 0; static float shdiff, shspec; static int twister = 0; static int unseen = 0; static float shadowbuff; static int shadow_button = 0; static int hair_shadow_button = 1; static void xformcontrolhair( void ); static float blurLen; static float lrastery = 9999999.0f; static int trigy = 0; static VERT lmap, lmm; static VERT LWshad; static int disable_shadows = 0; static VERT lighthit[255]; ///int pregen=0; static int GlobalStep = 1; static int filterON = 0; static float ambient[3]; static double ambi[3]; static VERT cast_shadows( VERT wpt ); //int PASSES = 1 ; static int global_segs = 56; static int accum_counter = 0; static char neg1[255]; static char neg12[255]; static char neg13[255]; static char neg14[255]; static char diskvol[255]; static int gseed = 0; static LIGHTINFO *current_cam; static LIGHTINFO LWcam; //LIGHTINFO accumbuffer; static LIGHTINFO LWlight[555]; static LIGHTINFO LWcamtable[255]; //#ifdef LIB static LIGHTINFO shadowmask; static FILE *diag; static SHAVEPARMS Gshavep[400]; static MEMFILE hairfiles[400]; static MEMFILE hairstate[400]; static int totalhairfiles = 0; static int Gfirstpass = 1; static int testvar = 0; static int Gtotal_guides = 0; static int Gdontinterp = 0; static int Gsurface_collide[6]; static int MAXPASSES = 0; static int LOCAL_PASSES[5]; static int LOCAL_CNT[5]; static int LOCAL_SEGS[5]; static int LOCAL_SHADCNT[5]; static int G_loaded = 0; static int totalfvertsSP = 0; static int totalfacesSP = 0; static int *face_startSP = NULL; static int *face_endSP = NULL; static int *facelistSP = NULL; static int *Dline_start = NULL; static int Dtotallines = 0; static int Graycast = 0; static int nokey = 0; static int *slgfaces[5]; static int total_slgfaces[5]; static int Gdeep_shadows = 1; static int Gclipx0 = 0, Gclipx1 = 8000, Gclipy0 = 0, Gclipy1 = 80000; static int estimated_total = 0; static int global_progress = 0; static WFTYPE Guv; unsigned long SHAVEID = (int )0; static int *Sdominant_faceID = NULL; static int *Smtlgroup = NULL; static float *SUBDrvcolor = NULL; static float *SUBDgvcolor = NULL; static float *SUBDbvcolor = NULL; static float *RSUBDrvcolor = NULL; static float *RSUBDgvcolor = NULL; static float *RSUBDbvcolor = NULL; static VERT *Svn = NULL; static VERT *VS = NULL; //VERT *VSB=NULL; static VERT *SVtmp = NULL; static int Stotalverts = 0; static int Stotalfaces = 0; static int Stotalfverts = 0; static int *Sfacelist = NULL; static int *Sface_start = NULL; static int *Sface_end = NULL; static int *Stag = NULL; static int *Skeepme = NULL; static int *Sedgepairs = NULL; static int Stotaledges = 0; static int *Sedgeflag = NULL; static SVMAP *Svert2DfaceID = NULL; #define OVLIMIT 50 static OVOX OVX[OVLIMIT][OVLIMIT][OVLIMIT]; static int MAXMODE = 0; static int slgID = 0; static int hairID = 0; #ifndef EXTERNAL_COLLISION static int DOCOLLIDE = 0; static int COLLISION_METHOD = 1; #endif #ifdef EXTERNAL_COLLISION static int DOCOLLIDE = 1; static int COLLISION_METHOD = 0; #endif static int Gslg, GhairID, GnodeID, Gpass; static ALLTILES alltiles; static LIGHTINFO tilebuff; static int TILEMODE = 0; static int LASTiy = -1; static int LASTix = -1; static int LASThairID = -1; // ** global static int find_closest_vert( VERT in ); static BASEHAIR DBdraw_lots( int ); static void spline_chain( int n ); static unsigned long genrand( void ); static void srand198( int q ) { gseed = q; } #ifdef MAX3D static float drand198( void ) { float ret = 0.0f; // int iret; ret = ( float ) cos( ( float ) gseed / 28.2f ) / 2.0f + .5f; // ret*=9.0f; //ret=(float)fabs(ret); //gseed++; // ret =(float)( (int)ret % 9); //ret=(float)fabs(ret); //if (ret<0) ret=0; //if (ret>9) ret=9; return ( ret ); } static float drand199( void ) { float ret; ret = ( float ) cos( ( ( float ) gseed / 42.0 ) * 3.14 + ( float ) gseed ) / ( float ) 2.0 + ( float ) .5; // woa possible error ret = ( float ) fabs( ret ); // woa possible errr if( ret < 0 ) ret = 0; if( ret > 9 ) ret = 9; return ( ret ); } #endif #ifndef MAX3D static float drand198( void ) { float ret; ret = ( float ) cos( ( ( float ) gseed / 10.0 ) * 23.14 + ( float ) gseed ) / ( float ) 2.0 + ( float ) .5; // woa possible error ret = ( float ) fabs( ret ); // woa possible errr if( ret < 0 ) ret = 0; if( ret > 9 ) ret = 9; return ( ret ); } static float drand199( void ) { float ret; ret = ( float ) cos( ( ( float ) gseed / 12.0 ) * 3.14 + ( float ) gseed ) / ( float ) 2.0 + ( float ) .5; // woa possible error ret = ( float ) fabs( ret ); // woa possible errr if( ret < 0 ) ret = 0; if( ret > 9 ) ret = 9; return ( ret ); } #endif static int Jexists( void *fname ); //static int BUTTON_CHECK( int a, int b, int a1, int b1 ); static int getCTRL( void ); #ifndef _WIN32 #define LPDWORD int #endif static int slcheck( void ); static void pop_rect( int x0, int y0, int x1, int y1 ); static WFTYPE Guv_sets[70]; // total possible sets = 45 static int Guv_link[70]; static int Guv_totalsets = 0; // related funcs // int SHAVEadd_uvset(WFTYPE *); // void SHAVEclear_uvsets(void); static VERT2 vxmp3( Matrix m, VERT vv, float e ); static void render_lineCP( RENDERHAIR * h, int a, int b, float sz1, float sz2, int cs, int zerovert ); static void draw_a_clumpCP( RENDERHAIR * h, int cs ); static void free_buff( void ); static void apply_shadowsDB( void ); static float smoothstep( float in ); static void backbuffer( void ); static void frontbuffer( void ); static void cmov2i( int x, int y ); static void make_normals( void ); static void Dmake_normals( void ); static void setmainwin( void ); static void drawpreview( void ); static void drawdepth( void ); static void drawmodel( void ); static void map_colors( void ); static void map_colorsprev( void ); static void DISPLAY_GROUPS( void ); static void aDRAW_FRAME_WINDOW( void ); static void DRAW_POPUP_TOOL( int n, int x ); static void aDRAW_POPUP_TOOL( int n, int x ); static void G_getmouse( void ); static void free_toolbars( void ); static void aDRAW_TOOLBOX( int n ); //static void DRAW_ALL( void ); static void Dcalc_plane_eq( void ); // norm is a unit vector static void surface_collide( int hh, float radius ); static void Ssurface_collide( int hh, float radius ); static float VDot( VERT a, VERT b ); typedef struct { char text[255]; int stat; int *setvar; void ( *callback ) ( ); } MENU; typedef struct { int x, y, stat, xs, ys, clickable; char text[255]; int wintool; } BUTTON; typedef struct { int xpos, ypos, stat, xsize, ysize, clickable; char text[255]; MENU menu[20]; int type; int elements; int wintool; int current_pick; } POPUP_TOOL; static int PICK_POPUP_LINE( int xx, int yy, POPUP_TOOL * p ); typedef struct { /* tool for seting positions or rotations or scale */ int xpos, ypos; int xsize, ysize; int stat; BUTTON axis[3]; BUTTON lable; BUTTON select; BUTTON set; } VERTEX_TOOL; typedef struct { /* tool chest you see on either side of screen */ int xpos, ypos; int stat; int xsize, ysize; int total_popup_tools; int total_radio_tools; int total_filler_tools; POPUP_TOOL pop_tool[35]; BUTTON filler[35]; } TOOLCHEST; typedef struct { /* viewer window */ BUTTON buttons[20]; int xsize, ysize; int xpos, ypos; int stat; int ymin, ymax; int xmin, xmax; float orthozoom; float opanx; float opany; int *image; int newframe; Colorindex *scratchimage; int sizeimage; float selectx1, selecty1; float selectx2, selecty2; } WINDOW; static void DRAW_POPUP_MENU( POPUP_TOOL * p ); static void CLOSE_POPUP_MENU( POPUP_TOOL * p ); static void UPDATE_POPUP_MENU( POPUP_TOOL * p ); static void HIGHLIGHT_POPUP_LINE( int x, POPUP_TOOL * p ); static void aDRAW_POPUP_MENU( POPUP_TOOL * p ); static void comb_select( VERT direction ); static void tagverts( void ); static void xform( int mx, int my ); static void make_inst( int slg, int aa ); static void draw_lotsINST( void ); static void saveallINST( char filename[255] ); static void adjoint( Matrix in, Matrix out ); static void weight_polys( void ); static void set_defaults( void ); static void config_toolbox( void ); static void MOVE_SLIDERS( int oldx, int newx ); static void rectf_steel( Scoord ax, Scoord ay, Scoord bx, Scoord by ); static void viewport( int l, int r, int b, int t ); static void reset_rest( void ); static void dodyn( void ); static void recalc_hair2( int g ); static void getframe( void ); static void doframe( void ); static void draw_lotsRENDER( void ); static void draw_lots( void ); static void freeverts( void ); static float drand49( void ); static void draw_geomWF( WFTYPE * geom, int cs ); static void draw_geomWFRS( WFTYPE * geom, int cs,GLOBS *gs ); static int Gcollision_hit = 0; //int draw_geomWF2(WFTYPE *geom, int cs); static void FILL_BUTTON_OUT( VERT a, VERT b ); static void FILL_BUTTON_IN( VERT a, VERT b ); static VERT Gilluminate( VERT pos, int l, float hambient ); static void NEW_MOVE_SLIDERS( int newxx ); static char GLOBAL_HAIR_NAME[255]; static int GLOBAL_QUIT = 0; static void reset_mmode( void ); static void make_splines( void ); static VERT cast_shadows_lgt_simplePLUSGEOM( VERT in, int lgt ); //BASEHAIR displace_randscale(BASEHAIR); static void free_splines( void ); static void init_splines( void ); static void alloc_splines( int ); // shading cache stuff #ifdef __linux__ #define SHAVE_SWAB(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #define SHAVE_SWAB2(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #endif #ifdef _WIN32 #define SHAVE_SWAB(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #define SHAVE_SWAB2(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #endif #ifdef INTEL #define SHAVE_SWAB(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #define SHAVE_SWAB2(val) /**NO BYTE SWAPPING UNDER WINDOWS**/ #endif #ifdef IRIX static void SHAVE_SWAB( void *val ) { char *c; c = ( char * ) ( val ); if( sizeof( val ) == 2 ) { c[0] ^= c[1]; c[1] ^= c[0]; c[0] ^= c[1]; } else if( sizeof( val ) == 4 ) { c[0] ^= c[3]; c[3] ^= c[0]; c[0] ^= c[3]; c[1] ^= c[2]; c[2] ^= c[1]; c[1] ^= c[2]; } } static void SHAVE_SWAB2( void *val ) { char *c; c = ( char * ) ( val ); { c[0] ^= c[1]; c[1] ^= c[0]; c[0] ^= c[1]; } } #endif #ifndef INTEL #ifdef MAC static void SHAVE_SWAB( void *val ) { char *c; c = ( char * ) ( val ); if( sizeof( val ) == 2 ) { c[0] ^= c[1]; c[1] ^= c[0]; c[0] ^= c[1]; } else if( sizeof( val ) == 4 ) { c[0] ^= c[3]; c[3] ^= c[0]; c[0] ^= c[3]; c[1] ^= c[2]; c[2] ^= c[1]; c[1] ^= c[2]; } } static void SHAVE_SWAB2( void *val ) { char *c; c = ( char * ) ( val ); { c[0] ^= c[1]; c[1] ^= c[0]; c[0] ^= c[1]; } } #endif #endif static float calculate_light_cone( VERT in, int lgt, float hamblient, VERT * rawcone ); static void metanurbfix( RENDERHAIR * hh ); static void draw_a_clumpCS( RENDERHAIR * h, int cs ); static void metanurbfixINST( void ); static BASEHAIR gen_resthair_ROOT( int id, int slg, CURVEINFO * cinfo ); static void initbounds( void ); static void MTmix100(GLOBS *gs); static void extract_chain( BASEHAIR * h ); static void getMAXPASSES( void ); static void add_undo( void ); static void Smk_polymat( Matrix m, int n ); static void draw_lotsWF( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo ); static void draw_lotsWFROOTRS( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo ); static void fish_hair( void *fp ); static void fish_hair2( void *fp ); void retag2( void ); unsigned long lsSHAVEID = 99998; //void Dallocvert(int n,int f,int tuv,int tl); static void Dallocvert( void ); static void split_select( void ); static void shatter_select( void ); static void merge_select( void ); static BASEHAIR gen_hair( int id, int slg ); static BASEHAIR gen_hair_ROOT( int id, int slg ); static void reorg( void ); static void reorg2( void ); static void fish_chains( void ); static BASEHAIR gen_resthair( int id, int slg, CURVEINFO * cinfo ); static void scanobj( CHNG *name ); static BASEHAIR gen_resthair_root( int id, int slg, CURVEINFO * cinfo ); static float getzGEOMNEW( VERT gg, int ll, int dd ); static float getzNEW( VERT gg, int ll, int dd ); static float getzGEOM( VERT gg, int ll ); static float getz( VERT gg, int ll ); //BASEHAIR displace_kinky(BASEHAIR h,float ss,float freqq); static float getnoise( float u, float v, float z ); static void Smake_restlengths( void ); static void Dregroup_nosplines( void ); static void mixitup( void ) { //for (pd=0;pd<(int)(30.*drand98());pd++) jfloat=drand98(); //for (pd=0;pd<(int)(27.*cc*drand98());pd++) jfloat=drand98(); } static unsigned long GLseed = 0; static void inverse( Matrix in, Matrix out ); static void MAYAalloc( FREEZETYPE * ret ); static void MAYANfree( FREEZETYPE * ret ); static void resize_render_hair( RENDERHAIR * h, WFTYPE * ft, int segs ); static float spline( float p1, float p2, float p3, float p4, float u ); static int WFdraw_lotsINSTWD( WFTYPE * wf, int cs ); static void init_noise( void ); static void reset_faces( void ); static void read_state_machine( MEMFILE * fp ); static void write_state( CHNG *fname ); static void read_state( CHNG *fname ); static void write_state_machine( MEMFILE * fp ); static void copy_to_rest( void ); static void relight_geom( FREEZETYPE * geom ); static void alloc_geom( FREEZETYPE * geom ); static void free_geom( FREEZETYPE * geom ); static void draw_geom( FREEZETYPE * geom, int cs ); static void LWdraw_geom( int cs ); static void write_inst( CHNG fname[500] ); static void read_inst( CHNG fname[500] ); static void unlock_verts( void ); static void lock_verts( void ); static float getzNEW( VERT gg, int ll, int dd ); static void LORESallocvert( int n, int f, int fl ); static VERT cast_shadows_lgt( VERT in, int lgt ); static VERT cast_shadows_lgt_simple( VERT in, int lgt ); static VERT cast_shadows_lgt_simpleINST( VERT in, int lgt ); //void resize_render_hair(RENDERHAIR *,WFTYPE *,int ); static VERT GilluminateWGEOM( VERT pos, int ll, float hambient ); extern void MAYAgetobj( CHNG *name, WFTYPE * wfdata ); static int check_curve( CURVEINFO * hp, WFTYPE * wf ); static void init_buffers( void ); static VERT cast_shadows( VERT wpt ); static void make_normalsWF( WFTYPE * wf ); static void make_normalsHT( HAIRTYPE * wf, VERT *vvn ); static void clear( void ); static void cleanup3( void ); static void center_all( void ); static void chain_reduce( void ); static void clear_buffers( void ); static void mkDEPTHbuffer( LIGHTINFO * cam ); static double ldot( double a[3], double b[3] ); static void destroy_buffers( void ); static void mkIMAGEbuffer( LIGHTINFO * cam ); static void mkDEPTHbuffers( LIGHTINFO * cam ); static void WFdraw_lotsINST( int cs ); #ifndef _WIN32 #define HWND int #endif static void calcZbuffer( LIGHTINFO * cam ); //#ifndef SOFTIMAGE //int EXTERNAL_COLLISIONS=0; //#endif #ifdef SOFTIMAGE static int EXTERNAL_COLLISIONS = 1; #endif #ifndef SOFTIMAGE static int EXTERNAL_COLLISIONS = 0; #endif static void put_geomWF( WFTYPE * wf, CHNG *fname ); //#include "voxels.h" #ifndef SOFTIMAGE static void MAYAexternal_forces( VERT * lastpos, VERT * vect, int y ) { vect->x += 0; vect->y += 0; vect->z += 0; } static void MAYAcache_forces(int clearCache) {} static void MAYAapply_cached_forces(int guideNum, int vertNum, VERT* vect) {} static void MAYAexternal_collision( SOFTGUIDE * lastpos, SOFTGUIDE * vect, float seglen ) { } #ifndef ALTERNATE_DEFS VERT SHAVEapply_GI( VERT tmp, CURVEINFO * ci ) { VERT t; t.x = 0.0f; t.y = 0.0f; t.z = 0.0f; return ( t ); } #endif static VERT SHAVEapply_atmosphere( VERT wpos, VERT inbound_color ) { // range = 0.0 - 1.0 (shave will clip out of bound returns) // do your tint here based on wpos // ie - make it really bright : // inbound_color.x*=3.0f; // inbound_color.y*=3.0f; // inbound_color.z*=3.0f; //inbound_color.x=255; //inbound_color.y=255; return ( inbound_color ); } static void SHAVEapply_inst_color( WFTYPE * instance_geom, int hairID, int slgID, unsigned long shaveINSTID ) { // empty funciton does nothing, but normally this funciton is called when rendering // so you can apply your own vert colors to instances } #ifndef ALTERNATEDEFS static float SHAVEapply_texture( CURVEINFO * ci, VERT rest_root_worldpos, unsigned long shaveINSTID, int parm, float inbound_value ) { // this function callback gives you the opportunity to apply external texture to any/every // channel in shave // CURVEINFO contains all kinds of basis information // rest_root_worldpos is the world coord for the hair's root in the rest position // shaveINSTID contains the ID you burned the restMEM (at creation) that's // being rendered // parm tells you which channel is being evaluated from SHAVEPARMS // this function is called during rendering // inbound contains the param value as evaluated internally (slider * weight * texture) // do something to inbound value here before it's returned return ( inbound_value ); } #endif static float SHAVEapply_VMAP( long SHAVEINSTID, int VERTID, int chan, float inbound_value ) { // this function callback gives you the opportunity to apply external vertpaint to any/every // channel in shave // normally the inbound_value will be 1.0 (unless you've painted a map inside shave) // the return, should contain a value who's range is (float) 0-1 return ( inbound_value ); } // this needs to be here as well, but you won't be using it // the 'MAYA' in the name is due to back compatibility with a MAYAShave version // this is an illumination callback (see docs) static VERT SHAVEdisplace_root( VERT * root, CURVEINFO * ci, int ID ) { VERT ret; ret.x = 0; ret.y = 0; ret.z = 0; return ( ret ); } float SHAVEapply_falloff( int lightNUM, VERT pos, float cone ) { return ( cone ); } static void mk_geom( WFTYPE * h1, WFTYPE * h2, WFTYPE * h3, WFTYPE * h4, WFTYPE * geom, int segs ); static int make_geom_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); static VERT SHAVEapply_illumination( int LIGHTID, VERT wpos, VERT vector, VERT color ) { // this function is now obsolete!! see SHAVEapply_illuminationWF // ranges are 0.0 - 1.0 (return isn't clipped until after shading) // modify or replace 'color' - it contains light info for current test before // shave shadows are applied return ( color ); } static void SHAVEapply_illuminationWF( int LIGHTID, WFTYPE * samples ) { // ranges are 0.0 - 1.0 (return isn't clipped until after shading) // modify or replace 'samples->color' - it contains light info for current test before // shave shadows are applied // samples->v is the position // samples->totalverts is the total number of points } static int SHAVEprogress( int actual, int estimated_total ) { int killit = 0; return ( killit ); } #endif static POLYDAT tocam( LIGHTINFO * cam, POLYDAT pp ); static int make_geom_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); static void read_targa( char filename[255], TGABUFF * tbuff ); static int make_spline_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); static void reset_dynamics( void ); static void metanurb( int divs ); static VERT fog_point( VERT wpt, VERT clr ); //float tmpface[10]; static void MS_sproing( float scale ); /* * RGB-HSL transforms. * Ken Fishkin, Pixar Inc., January 1989. */ /* * given r,g,b on [0 ... 1], * return (h,s,l) on [0 ... 1] */ static void RGB_to_HSL( float r, float g, float b, float *h, float *s, float *l ) { float vv; float m; float vm; float r2, g2, b2; vv = MAX( r, g ); vv = MAX( vv, b ); m = MIN( r, g ); m = MIN( m, b ); if( ( *l = ( m + vv ) / 2.0f ) <= 0.0f ) return; if( ( *s = vm = vv - m ) > 0.0f ) { *s /= ( *l <= 0.5f ) ? ( vv + m ) : ( 2.0f - vv - m ); } else return; r2 = ( vv - r ) / vm; g2 = ( vv - g ) / vm; b2 = ( vv - b ) / vm; if( r == vv ) *h = ( g == m ? 5.0f + b2 : 1.0f - g2 ); else if( g == vv ) *h = ( b == m ? 1.0f + r2 : 3.0f - b2 ); else *h = ( r == m ? 3.0f + g2 : 5.0f - r2 ); *h /= 6.0f; } static int JexistsNOWAIT( void *fname ); static int getTAB( void ); /* * given h,s,l on [0..1], * return r,g,b on [0..1] */ static void HSL_to_RGB( float h, float sl, float l, float *r, float *g, float *b ) { float vv; vv = ( l <= 0.5f ) ? ( l * ( 1.0f + sl ) ) : ( l + sl - l * sl ); if( vv <= 0.0f ) { *r = *g = *b = 0.0f; } else { float m; float sv; int sextant; float fract, vsf, mid1, mid2; m = l + l - vv; sv = ( vv - m ) / vv; h *= 6.0f; sextant = ( int ) h; fract = h - sextant; vsf = vv * sv * fract; mid1 = m + vsf; mid2 = vv - vsf; switch ( sextant ) { case 0: *r = vv; *g = mid1; *b = m; break; case 1: *r = mid2; *g = vv; *b = m; break; case 2: *r = m; *g = vv; *b = mid1; break; case 3: *r = m; *g = mid2; *b = vv; break; case 4: *r = mid1; *g = m; *b = vv; break; case 5: *r = vv; *g = m; *b = mid2; break; } } } #ifdef RENDERLW static void mkcamray( int x, int y, LWDVector * pos, LWDVector * n ); static const PixelAccess *Gsa = NULL; /* * Saved globals. */ //static static LWItemInfo *iid; static MessageFuncs *mf; static LWItemInfo *iid; //static static LWLightInfo *li; //static static LWBackdropInfo *bdinfo; //static #ifndef VOLUMETRICLW static MessageFuncs *mf; #endif #ifdef VOLUMETRICLW static LWMessageFuncs *mf; #endif //MessageFuncs *mf; // static static LWSceneInfo *ls; // static static LWCameraInfo *lc; // static static LWFogInfo *fog; static LWItemInfo *iid; #endif static void WFIrelight( WFTYPE * wf ); static void VXclear( void ); static void draw_tile( unsigned current_thread, void *qqq); static VERT Vnorm( VERT v ); static float get_shadow_pix( float xx, float yy, float zz ); static void WFdraw_oneINST( int x, int slg, int cs ); static void fetch_hair( int xx, float t ); static int draw_oneHAIR( int slg, int xid, int cs, int curtile ); static int MTdraw_oneHAIR( int slg, int xid, int cs, int curtile, GLOBS * gs ); static void draw_oneINST( int slg, int xxx ); // tile stuff static void freetilebuff( LIGHTINFO * cam ); static void mktilebuff( LIGHTINFO * cam, int xr, int yr ); static int tag_tile( int x, int y, int slg, int hairID, int nodeID , int passID); static int tag_tile_rect( int x1, int y1, int x2, int y2, int slg, int hairID, int nodeID, int triangles,int passID ); static void init_tiles( void ); static void free_tiles( void ); static void tile_render( WFTYPE * occlusion, unsigned char *ibuff, float *zbuff, int dice ); void free_tiles( void ) { int x; for( x = 0; x < alltiles.totaltiles; x++ ) { //if (alltiles.tile[x].totalpolyhits>0) if (alltiles.tile[x].polyhits) free( alltiles.tile[x].polyhits ); alltiles.tile[x].totalpolyhits = 0; // if (alltiles.tile[x].totalhits>0) { if (alltiles.tile[x].passhairhits) free( alltiles.tile[x].passhairhits ); if (alltiles.tile[x].hairhits) free( alltiles.tile[x].hairhits ); if (alltiles.tile[x].slghairhits) free( alltiles.tile[x].slghairhits ); if (alltiles.tile[x].nodehairhits) free( alltiles.tile[x].nodehairhits ); alltiles.tile[x].totalhits = 0; alltiles.tile[x].nodehairhits=NULL; alltiles.tile[x].slghairhits=NULL; alltiles.tile[x].hairhits=NULL; alltiles.tile[x].passhairhits=NULL; alltiles.tile[x].polyhits=NULL; } if( alltiles.tile[x].totalnodes > 0 ) { // static alloc Nfree(alltiles.tile[x].nodeids); alltiles.tile[x].totalnodes = 0; } } if( alltiles.totaltiles > 0 ) { if (alltiles.tile) free( alltiles.tile ); alltiles.tile=NULL; alltiles.totaltiles = 0; } } static void init_tiles( void ) { int xt, yt; int x, y; xt = ( int ) ceil( ( float ) LWcam.xres / ( float ) alltiles.dice ); yt = ( int ) ceil( ( float ) LWcam.yres / ( float ) alltiles.dice ); alltiles.sx = xt; //*(float)GLOBALSAMP; alltiles.sy = yt; //*(float)GLOBALSAMP; alltiles.totaltiles = 0; alltiles.tile = NULL; } POLYDATSM *newpc=NULL; static void alloc_tiles( void ) { int xt, yt; int x, y; xt = ( int ) ceil( ( float ) LWcam.xres / ( float ) alltiles.dice ); yt = ( int ) ceil( ( float ) LWcam.yres / ( float ) alltiles.dice ); alltiles.sx = xt; //*(float)GLOBALSAMP; alltiles.sy = yt; //*(float)GLOBALSAMP; alltiles.totaltiles = ( alltiles.dice + 2 ) * ( alltiles.dice + 2 ); alltiles.tile = ( TILETYPE * ) malloc( alltiles.totaltiles * sizeof( TILETYPE ) ); alltiles.totaltiles = 0; for( x = 0; x < alltiles.dice; x++ ) for( y = 0; y < alltiles.dice; y++ ) { int add; TILETYPE *current_tile; add = x + y * alltiles.dice; current_tile = &alltiles.tile[add]; current_tile->triangles = 0; current_tile->totalhits = 0; current_tile->sizehairhits = 0; current_tile->totalpolyhits = 0; current_tile->sizepolyhits = 0; current_tile->totalnodes = 0; current_tile->hairhits = NULL; current_tile->passhairhits = NULL; current_tile->slghairhits = NULL; current_tile->nodehairhits = NULL; current_tile->polyhits = NULL; current_tile->x1 = x * xt; current_tile->y1 = y * yt; current_tile->x2 = x * xt + xt; current_tile->y2 = y * yt + yt; alltiles.totaltiles++; } } static int tag_tile( int x, int y, int slg, int hairID, int nodeID,int passID ) { int add; int ix, iy; TILETYPE *curtile; int skipit = 0; int same = 0; if( ( alltiles.sx > 0 ) && ( alltiles.sy > 0 ) ) { ix = ( int ) floor( ( float ) x / ( float ) alltiles.sx ); iy = ( int ) floor( ( float ) y / ( float ) alltiles.sy ); if( ( ix == LASTix ) && ( iy == LASTiy ) && ( hairID == LASThairID ) ) skipit = 1; LASTix = ix; LASTiy = iy; LASThairID = hairID; same = skipit; add = ix + iy * alltiles.dice; if( skipit == 0 ) if( ( ix < alltiles.dice ) && ( ix >= 0 ) && ( iy < alltiles.dice ) && ( iy >= 0 ) ) { if( alltiles.totaltiles > add ) { curtile = &alltiles.tile[add]; if( curtile ) { // if (TILEMODE==1) // curtile->totalhits++; if( TILEMODE == 2 ) { // if this hair didn't just hit it, add it to the stack if( curtile->totalnodes < 5255 ) { if( curtile->totalhits > 0 ) { if( curtile->hairhits[curtile->totalhits - 1] != ( unsigned int ) hairID ) { if( curtile->totalhits > curtile->sizehairhits - 3 ) { curtile->sizehairhits += 1400; curtile->passhairhits = ( unsigned int * ) realloc( curtile->passhairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->hairhits = ( unsigned int * ) realloc( curtile->hairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->slghairhits = ( unsigned int * ) realloc( curtile->slghairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->nodehairhits = ( unsigned int * ) realloc( curtile->nodehairhits, curtile->sizehairhits * sizeof( unsigned int ) ); } curtile->slghairhits[curtile->totalhits] = ( unsigned int ) slg; curtile->nodehairhits[curtile->totalhits] = ( unsigned int ) nodeID; curtile->hairhits[curtile->totalhits] = ( unsigned int ) hairID; curtile->passhairhits[curtile->totalhits] = ( unsigned int ) passID; curtile->totalhits++; } } if( curtile->totalhits == 0 ) { { curtile->sizehairhits += 1400; curtile->hairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->passhairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->slghairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->nodehairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); } curtile->slghairhits[curtile->totalhits] = ( unsigned int ) slg; curtile->nodehairhits[curtile->totalhits] = ( unsigned int ) nodeID; curtile->hairhits[curtile->totalhits] = ( unsigned int ) hairID; curtile->passhairhits[curtile->totalhits] = ( unsigned int ) passID; curtile->totalhits++; } // add node hits if( curtile->totalnodes < 5255 ) { if( curtile->totalnodes > 0 ) if( curtile->nodeids[curtile->totalnodes - 1] != ( unsigned int ) nodeID ) { curtile->nodeids[curtile->totalnodes] = ( unsigned int ) nodeID; curtile->totalnodes++; } if( curtile->totalnodes == 0 ) { curtile->nodeids[curtile->totalnodes] = ( unsigned int ) nodeID; curtile->totalnodes++; } } } } if( TILEMODE == 3 ) curtile->totalpolyhits++; if( TILEMODE == 4 ) { // if this hair didn't just hit it, add it to the stack if( curtile->totalpolyhits > 0 ) if( curtile->polyhits[curtile->totalpolyhits - 1] != ( unsigned int ) hairID ) { curtile->polyhits[curtile->totalpolyhits] = hairID; curtile->totalpolyhits++; } // first hit if( curtile->totalpolyhits == 0 ) { curtile->polyhits[curtile->totalpolyhits] = hairID; curtile->totalpolyhits++; } } } } } } return ( same ); } static int tag_tile_rect( int x1, int y1, int x2, int y2, int slg, int hairID, int nodeID, int triangles, int passID ) { int add; int ix, iy; TILETYPE *curtile; int skipit = 0; int same = 0; int ix1, iy1, ix2, iy2; int failtest = 0; // if( x1 == x2 ) // failtest = 1; // if( y1 == y2 ) // failtest = 1; //printf ("tagging %d\n",passID);fflush(stdout); // x1 -= GLOBALSAMP; // y1 -= GLOBALSAMP; // x2 += GLOBALSAMP; // y2 += GLOBALSAMP; // if( ( x1 < 0 ) && ( x2 < 0 ) ) // failtest = 1; // if( ( y1 < 0 ) && ( y2 < 0 ) ) // failtest = 1; if( ( x1 / alltiles.sx > alltiles.dice ) && ( x2 / alltiles.sx > alltiles.dice ) ) failtest = 1; if( ( y1 / alltiles.sy > alltiles.dice ) && ( y2 / alltiles.sy > alltiles.dice ) ) failtest = 1; if( failtest == 0 ) if( ( alltiles.sx > 0 ) && ( alltiles.sy > 0 ) ) { ix1 = ( int ) floor( ( float ) x1 / ( float ) (alltiles.sx) )-2; iy1 = ( int ) floor( ( float ) y1 / ( float ) (alltiles.sy) )-2; ix2 = ( int ) ceil( ( float ) x2 / ( float ) (alltiles.sx) ); iy2 = ( int ) ceil( ( float ) y2 / ( float ) (alltiles.sy) ); // if( NOBLUR == 1 ) // { // ix2 = ( int ) floor( ( float ) x2 / ( float ) alltiles.sx ); // iy2 = ( int ) floor( ( float ) y2 / ( float ) alltiles.sy ); // } // don't need to be so aggressive about tile tags since we're not doing moblur if( ix1 < 0 ) ix1 = 0; if( iy1 < 0 ) iy1 = 0; if( ix2 > alltiles.dice-1 ) ix2 = alltiles.dice-1; if( iy2 > alltiles.dice-1 ) iy2 = alltiles.dice-1; for( ix = ix1; ix <= ix2; ix++ ) for( iy = iy1; iy <= iy2; iy++ ) { skipit = 0; //if ((ix==LASTix)&&(iy==LASTiy)&&(hairID==LASThairID)) skipit=1; LASTix = ix; LASTiy = iy; LASThairID = hairID; same = skipit; add = ix + iy * alltiles.dice; if( skipit == 0 ) if( ( ix < alltiles.dice ) && ( ix >= 0 ) && ( iy < alltiles.dice ) && ( iy >= 0 ) ) { if( alltiles.totaltiles > add ) { curtile = &alltiles.tile[add]; if( curtile ) { // if (TILEMODE==1) // curtile->totalhits++; curtile->triangles += triangles; if( TILEMODE == 2 ) { //printf ("hairID = %d nodeID = %d passID = %d\n",GhairID,nodeID,passID);fflush(stdout); // if this hair didn't just hit it, add it to the stack if( curtile->totalnodes < 5255 ) { if( curtile->totalhits > 0 ) { if( ( curtile->hairhits[curtile->totalhits - 1] != ( unsigned int ) hairID ) // this is for mult hairs ||( curtile->slghairhits[curtile->totalhits - 1] != ( unsigned int ) slg ) // this is for mult hairs ||( curtile->nodehairhits[curtile->totalhits - 1] != ( unsigned int ) nodeID ) // this is for mult hairs ||( curtile->passhairhits[curtile->totalhits - 1] != ( unsigned int ) passID ) // this is for mult hairs ) { if( curtile->totalhits > curtile->sizehairhits - 3 ) { curtile->sizehairhits += 11400; curtile->passhairhits = ( unsigned int * ) realloc( curtile->passhairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->hairhits = ( unsigned int * ) realloc( curtile->hairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->slghairhits = ( unsigned int * ) realloc( curtile->slghairhits, curtile->sizehairhits * sizeof( unsigned int ) ); curtile->nodehairhits = ( unsigned int * ) realloc( curtile->nodehairhits, curtile->sizehairhits * sizeof( unsigned int ) ); } curtile->slghairhits[curtile->totalhits] = ( unsigned int ) slg; curtile->nodehairhits[curtile->totalhits] = ( unsigned int ) nodeID; curtile->hairhits[curtile->totalhits] = ( unsigned int ) hairID; curtile->passhairhits[curtile->totalhits] = ( unsigned int ) passID; curtile->totalhits++; } } if( curtile->totalhits == 0 ) { { curtile->sizehairhits += 11400; curtile->hairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->slghairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->nodehairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); curtile->passhairhits = ( unsigned int * ) malloc( curtile->sizehairhits * sizeof( unsigned int ) ); } curtile->slghairhits[curtile->totalhits] = ( unsigned int ) slg; curtile->nodehairhits[curtile->totalhits] = ( unsigned int ) nodeID; curtile->hairhits[curtile->totalhits] = ( unsigned int ) hairID; curtile->passhairhits[curtile->totalhits] = ( unsigned int ) passID; curtile->totalhits++; } // add node hits if( curtile->totalnodes < 5255 ) { if( curtile->totalnodes > 0 ) if( curtile->nodeids[curtile->totalnodes - 1] != ( unsigned int ) nodeID ) { curtile->nodeids[curtile->totalnodes] = ( unsigned int ) nodeID; curtile->totalnodes++; } if( curtile->totalnodes == 0 ) { curtile->nodeids[curtile->totalnodes] = ( unsigned int ) nodeID; curtile->totalnodes++; } } } } if( TILEMODE == 3 ) curtile->totalpolyhits++; if( TILEMODE == 4 ) { // if this hair didn't just hit it, add it to the stack if( curtile->totalpolyhits > 0 ) if( curtile->polyhits[curtile->totalpolyhits - 1] != ( unsigned int ) hairID ) { curtile->polyhits[curtile->totalpolyhits] = hairID; curtile->totalpolyhits++; } // first hit if( curtile->totalpolyhits == 0 ) { curtile->polyhits[curtile->totalpolyhits] = hairID; curtile->totalpolyhits++; } } } } } } } // ix/iy return ( same ); } extern void SHAVEmult_vox_size(float mult) { Gvox_mult=mult; } static float dither2OLD( float in ) { //#ifdef crap float flip; float rem; float base; float out; flip = ( float ) drand98( ); base = ( float ) floor( in ); rem = in - base; if( flip > rem ) out = in; else out = in + 1.0f; if( out > 255.0 ) out = 255.0f; return ( out ); //#endif //return(in); } static void freetilebuff( LIGHTINFO * cam ) { if (cam->ibuff) free( cam->ibuff ); cam->ibuff=NULL; if (cam->geombuff) free( cam->geombuff ); cam->geombuff=NULL; if (cam->zbuff) free( cam->zbuff ); cam->zbuff=NULL; cam->ibound = 0; cam->gbound = 0; cam->zbound = 0; } static void mktilebuff( LIGHTINFO * cam, int xr, int yr ) { int low_mem=0; { int x; int es; // es = Gextrasamp + 1; es = 1; cam->ibuff = NULL; cam->lumbuff = NULL; cam->geombuff = NULL; cam->zbuff = NULL; if( low_mem == 0 ) { cam->ibuff = ( unsigned char * ) malloc( Gmotion_samp*GLOBALSAMP * GLOBALSAMP * 4 * es * sizeof( unsigned char ) * xr * ( yr + 4 * GLOBALSAMP ) *Gtransp_depth); cam->geombuff = ( float * ) malloc( Gmotion_samp*GLOBALSAMP * GLOBALSAMP * es * sizeof( float ) * xr * ( yr + 4 * GLOBALSAMP ) ); cam->ibound = ( GLOBALSAMP * GLOBALSAMP * 4 * es * xr * ( yr ) *Gtransp_depth*Gmotion_samp); cam->gbound = ( GLOBALSAMP * GLOBALSAMP * es * xr * ( yr ) *Gmotion_samp); cam->iPage = ( GLOBALSAMP * GLOBALSAMP * ( xr ) * ( yr ) *4 ); } if( cam->geombuff == NULL ) { low_mem = 1; if( GLOBAL_VERBOSE ) printf( "**** ERROR **** out of memory (allocating image buffers)\n" ); cam->xres = 0; cam->yres = 0; free( cam->ibuff ); free( cam->geombuff ); cam->ibuff = NULL; cam->lumbuff = NULL; cam->geombuff = NULL; } if( low_mem == 0 ) { float *gb; unsigned char *ib; gb= &cam->geombuff[0]; ib= &cam->ibuff[0]; for( x = 0; x < ( int ) cam->gbound; x++ ) *(gb+x) = 1000000.0f; for( x = 0; x < ( int ) cam->ibound; x++ ) *(ib+x) = 0; } } cam->zbuff = NULL; if( low_mem == 0 ) { int x; int es; // es = Gextrasamp; es = 1; cam->zbuff = NULL; if( low_mem == 0 ) cam->zbuff = ( float * ) malloc( Gmotion_samp*GLOBALSAMP * GLOBALSAMP * sizeof( float ) * ( xr ) * ( yr + 4 * GLOBALSAMP ) * es *Gtransp_depth); cam->zbound = ( GLOBALSAMP * GLOBALSAMP * ( xr ) * ( yr ) * Gmotion_samp*Gtransp_depth ); cam->zPage = ( GLOBALSAMP * GLOBALSAMP * ( xr ) * ( yr ) ); // used for indexing cam->timePage=cam->zPage*Gtransp_depth; if( cam->zbuff == NULL ) { low_mem = 1; if( GLOBAL_VERBOSE ) printf( "*** ERROR *** Out of memory (allocating depth buffer\n" ); if (cam->zbuff) free( cam->zbuff ); cam->zbuff = NULL; cam->xres = 0; cam->yres = 0; cam->ibound = 0; cam->zbound = 0; cam->gbound = 0; } // cam->geombuff=(float *) malloc (sizeof(float)*(cam->xres+1)*(cam->yres+2)*es); // for (x=0;x< cam->xres*cam->yres*oversamp*es; x++) cam->zbuff[x]=100000000000.0f; if( low_mem == 0 ) { float *zb; zb= &cam->zbuff[0]; for( x = 0; x < ( int ) cam->zbound; x++ ) *(zb+x) = 1000000.0f; } // printf ("done with init\n");fflush(stdout); // for (x=0;x< cam->xres*cam->yres*es; x++) cam->geombuff[x]=1000000.0f; #ifndef RENDERLW // cam->Gzbuff=(float *) malloc (sizeof(float)*(cam->xres+1)*(cam->yres+2)*oversamp*es); // for (x=0;x< cam->xres*cam->yres*oversamp*es; x++) cam->Gzbuff[x]=100000000000.0f; #endif } } static void set_cachemode( int sw ); static void draw_lotsROOTS( int cs ); static int draw_oneROOT( int slg, int xid, int cs ); static void free_maps( void ); static VERT world2cam1( LIGHTINFO * cam, VERT in ); static int trivial_reject( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */ ); static void MTdisplace_kinky( BASEHAIR * h, float ss, float freqq, GLOBS * gs ); static void MTdisplace_clumpy( BASEHAIR * h, GLOBS * gs ); static void displace_randscale( BASEHAIR * ); static void MTdisplace_randscale( BASEHAIR *, GLOBS * gs ); static void color_a_hair( BASEHAIR * h ); //static int GLOBAL_CLIPIT = 0; typedef struct { VERT rest[15]; VERT current[15]; VERT color[15]; // add in params later } GUIDE; static BASEHAIR displace_wiggle( BASEHAIR h, float ss, float freqq ); int SHAVEfetch_guideface(int curface, GUIDE *guide1,GUIDE *guide2, GUIDE *guide3) { int y; for (y=0;y<15;y++) { int add; add=facelist[face_start[curface]+0]; guide1->rest[y]=hair[add].resthv[y]; guide1->current[y]=hair[add].hv[y]; guide1->color[y]=hair[add].color[y]; add=facelist[face_start[curface]+1]; guide2->rest[y]=hair[add].resthv[y]; guide2->current[y]=hair[add].hv[y]; guide2->color[y]=hair[add].color[y]; add=facelist[face_start[curface]+2]; guide3->rest[y]=hair[add].resthv[y]; guide3->current[y]=hair[add].hv[y]; guide3->color[y]=hair[add].color[y]; } return(totalfaces); } //int round(float f); // // // these functions are for building a full data set of all the hair that's on the stack // you've already built using all the add_hair functions. this can be kind of a memory pig // so don't keep that data around any longer than you have to // // for example: // // HAIRTYPE exp; // SHAVEinit_hairtype(&exp); // SHAVEexport_hair(&exp); // // do your thing here with the hair information // // SHAVEfree_hairtype(&exp); // // all done and cleaned up // (you could also do a SHAVEclear_stack() at this point) // typedef struct { int totalp; int *plist; } POLYVOX; /* object info */ typedef struct { POLYVOX ***pvox; VERT *v; VERT *bk; VERT *vn; VERT *vnrest; VERT *neutral; VERT *Dface_norm; VERT *Dv; VERT *Drv; VERT *Dvn; int *splinelist; // face refferenced list of splines int *vert2guide; int *guide2vert; int *pbtag; int *facelist; int *face_start; int *face_link; int *face_end; int *vertgroup; int *mtlgroup; int *vlink; int *Duvfacelist; int *Duvface_start; int *Duvface_end; int *Dfacelist; int *Dface_start; int *Dface_end; int *Dvertgroup; int *Dvertlink; int *Dmtlgroup; int *Dtag; int *Dlink; int *Dflink; int *D2UTface_link; int *DUTmtlgroup; int *DUTfacelist; int *DUTface_start; int *DUTface_end; int *DUTofaceID; double *poly_weight; float *tagvert; float *rvcolor; float *gvcolor; float *bvcolor; // float *ucord; // float *vcord; float *Ducord; float *Dvcord; float *Drvcolor; float *Dgvcolor; float *Dbvcolor; float *RDrvcolor; float *RDgvcolor; float *RDbvcolor; float *DD; FREEZETYPE *freeze, *freezetmp, *freezetmp1, *freezetmp2; BASEHAIR *hairbuffer; BASEHAIR *hair; BASEHAIR *hairvelocity; BASEHAIR *lasthair; BASEHAIR *thishair; BASEHAIR *resthair; BASEHAIR *Shair; BASEHAIR *Slasthair; BASEHAIR *Shairvelocity; BASEHAIR *Sresthair; BASEHAIR *Sthishair; int Duvtotalfaces; int Duvtotalfverts; int Duvtotalverts; int subdiv; int flip_norms; int G_current_pass; int newMODE; int GMetaNurb; int uvtotalfaces; int global_lores; int totalverts; int totalguides; int Dtotalfaces; int Dtotalverts; int Dtotalfverts; int DUTtotalfaces; int DUTtotalfverts; int beard; int eyebrow; int eyelash; int head; int splines; int skull_sphere; int colorlock; int totalENABLEDverts; int totalfverts; int totalfaces; int totalgroups; int totalsplits; int total_splines; float restBOUNDLENGTH; SLIDER sliders[60][6]; char group_names[555][255]; int group_enable[555]; } GLOBALSTYPE; static void init_gnode( GLOBALSTYPE * gg ) { gg->pvox = NULL; // gg->vcord = NULL; gg->bk = NULL; gg->vn = NULL; gg->vnrest = NULL; gg->neutral = NULL; gg->Dface_norm = NULL; gg->Dv = NULL; gg->Drv = NULL; gg->Dvn = NULL; gg->splinelist = NULL; // face refferenced list of splines gg->vert2guide = NULL; gg->guide2vert = NULL; gg->pbtag = NULL; gg->facelist = NULL; gg->face_start = NULL; gg->face_link = NULL; gg->face_end = NULL; gg->vertgroup = NULL; gg->mtlgroup = NULL; gg->vlink = NULL; gg->Duvfacelist = NULL; gg->Duvface_start = NULL; gg->Duvface_end = NULL; gg->Dfacelist = NULL; gg->Dface_start = NULL; gg->Dface_end = NULL; gg->Dvertgroup = NULL; gg->Dvertlink = NULL; gg->Dmtlgroup = NULL; gg->Dtag = NULL; gg->Dlink = NULL; gg->Dflink = NULL; gg->D2UTface_link = NULL; gg->DUTmtlgroup = NULL; gg->DUTfacelist = NULL; gg->DUTface_start = NULL; gg->DUTface_end = NULL; gg->DUTofaceID = NULL; gg->poly_weight = NULL; gg->tagvert = NULL; gg->rvcolor = NULL; gg->gvcolor = NULL; gg->bvcolor = NULL; // gg->ucord = NULL; // gg->vcord = NULL; gg->Ducord = NULL; gg->Dvcord = NULL; gg->Drvcolor = NULL; gg->Dgvcolor = NULL; gg->Dbvcolor = NULL; gg->RDrvcolor = NULL; gg->RDgvcolor = NULL; gg->RDbvcolor = NULL; gg->DD = NULL; gg->freeze = NULL; gg->freezetmp = NULL; gg->freezetmp1 = NULL; gg->freezetmp2 = NULL; gg->hairbuffer = NULL; gg->hair = NULL; gg->hairvelocity = NULL; gg->lasthair = NULL; gg->thishair = NULL; gg->resthair = NULL; gg->Shair = NULL; gg->Slasthair = NULL; gg->Shairvelocity = NULL; gg->Sresthair = NULL; gg->Sthishair = NULL; gg->Duvtotalfaces = 0; gg->Duvtotalfverts = 0; gg->Duvtotalverts = 0; gg->subdiv = 0; gg->flip_norms = 0; gg->G_current_pass = 0; gg->newMODE = 0; gg->GMetaNurb = 0; gg->uvtotalfaces = 0; gg->global_lores = 0; gg->totalverts = 0; gg->totalguides = 0; gg->Dtotalfaces = 0; gg->Dtotalverts = 0; gg->Dtotalfverts = 0; gg->DUTtotalfaces = 0; gg->DUTtotalfverts = 0; gg->beard = -1; gg->eyebrow = -1; gg->eyelash = -1; gg->head = -1; gg->splines = -1; gg->skull_sphere = -1; gg->colorlock = -1; gg->totalENABLEDverts = 0; gg->totalfverts = 0; gg->totalfaces = 0; gg->totalgroups = 0; gg->totalsplits = 0; gg->total_splines = 0; gg->restBOUNDLENGTH = 0.0f; } static void displace_scale( BASEHAIR * h, float rs ); #include "swatch.h" #include "mesh_swatch.h" //#ifdef crap static void alloc_cache( void ) { int t; t = 0; t = LOCAL_CNT[0] * LOCAL_PASSES[0] * ( ( int ) sliders[27][0].value + 1 ); t += LOCAL_CNT[4] * LOCAL_PASSES[4] * ( ( int ) sliders[27][4].value + 1 ); Nfree( base_cache ); Nfree( cinfo_cache ); if( t != 0 ) { base_cache = ( BASEHAIR * ) malloc( t * sizeof( BASEHAIR ) ); cinfo_cache = ( CURVEINFO * ) malloc( t * sizeof( CURVEINFO ) ); } total_base_cache = t; } static void set_cachemode( int sw ) { if( sw == NONE ) { Nfree( base_cache ); free( cinfo_cache ); total_base_cache = 0; current_cachehair = 0; cachemode = NONE; } if( sw == PLAYBACK_CACHE ) { cachemode = PLAYBACK_CACHE; current_cachehair = 0; } if( sw == CREATE_CACHE ) { cachemode = CREATE_CACHE; alloc_cache( ); current_cachehair = 0; } } static void color_a_hairROOT( BASEHAIR * h ); static void add_cache( BASEHAIR * h, CURVEINFO * cinfo ) { if( total_base_cache != 0 ) { // current_cachehair=place; // if (current_cachehair>total_base_cache-1) current_cachehair=total_base_cache-1; memcpy( &base_cache[current_cachehair], h, sizeof( BASEHAIR ) ); memcpy( &cinfo_cache[current_cachehair], cinfo, sizeof( CURVEINFO ) ); current_cachehair++; if( current_cachehair > total_base_cache - 1 ) current_cachehair = total_base_cache - 1; } } static void fetch_cache( BASEHAIR * h, CURVEINFO * cinfo ) { if( total_base_cache != 0 ) { // currrent_cachehair=place; // if (current_cachehair>total_base_cache-1) current_cachehair=total_base_cache-1; memcpy( h, &base_cache[current_cachehair], sizeof( BASEHAIR ) ); memcpy( cinfo, &cinfo_cache[current_cachehair], sizeof( CURVEINFO ) ); current_cachehair++; if( current_cachehair > total_base_cache - 1 ) current_cachehair = total_base_cache - 1; } } static void draw_lotsWFFAST( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo ); void SHAVEfast_eval( int onoff ) // 1==fast 0==qual { Gfast_eval = onoff; } void SHAVEdrag_mode( int onoff ) // this func is really only appropriate for soft { Gdrag_hair = onoff; } static int Gvoxdim = 0; static CHNG Gvoxname[2255]; extern void VXtest( int xres, int yres, unsigned char *image ); extern VERT SHAVEworld2cam( VERT in ); static void color_a_hairSOFT( BASEHAIR * h ); extern float SHAVEset_ambient( VERT ambient_light ); extern void SHAVEdestroy_buffers( void ); extern void SHAVExformNOSTAT( WFTYPE * objstruct, MEMFILE * a, MEMFILE * b, int run_dyn ); extern void SHAVEreset_to_rest( SHAVENODE * sn ); #ifndef XSI_SOFT3D_ONLY float SHAVEapply_falloff( int lightNUM, VERT pos, float cone ); #endif void SHAVEset_verbose (int i) { GLOBAL_VERBOSE=i; } void TESTPRIMclear_hairstack( void ) { Gvoxdim = 0; SHAVEclear_stack( ); } int TESTPRIMfetch_bbox( int index, VERT * obound1, VERT * obound2 ) // return -1 if fails { int addx, addy, addz; int voxdim = 0; int ret; ret = -1; voxdim = Gvoxdim; if( index < ( voxdim ) * ( voxdim ) * ( voxdim ) ) if( voxdim > 0 ) { addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; ////printf ("addx,addy,addz = %d %d %d\n",addx,addy,addz);fflush(stdout); //printf ("Gvoxname = %s\n",Gvoxname);fflush(stdout); ret = SHAVEimport_archive_voxel_bbox( Gvoxname, addx, addy, addz, obound1, obound2 ); } return ( ret ); } void TESTPRIMfetch_voxel( int index, HAIRTYPE * outhair, int isShadow ) { int addx, addy, addz; int voxdim; voxdim = Gvoxdim; addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; SHAVEinit_hairtype( outhair ); if( index < ( voxdim ) * ( voxdim ) * ( voxdim ) ) SHAVEimport_archive_voxel( Gvoxname, addx, addy, addz, outhair, isShadow ); } void TESTPRIMfree_hairtype( HAIRTYPE * geom ) // this is for freeing the hairtype allocated by PRIMfetch_voxel { SHAVEfree_hairtype( geom ); } void TESTPRIMinit_hairtype( HAIRTYPE * geom ) // this is for freeing the hairtype allocated by PRIMfetch_voxel { SHAVEinit_hairtype( geom ); } int TESTPRIMinit_hairstack( CHNG *fname ) { FILE *fp = NULL; int ret = -1; Gvoxdim = 0; fp = fopen( fname, "r" ); if( fp ) // found a file { fclose( fp ); fp = NULL; memcpy( &Gvoxname, fname, sizeof( CHNG ) * strlen( fname ) + 1 ); //printf ("debug1 = %s\n",Gvoxname);fflush(stdout); // SHAVEinit(); ret = SHAVEinit_hairstack_from_archive( fname ); ret = ret * ret * ret; } if( fp ) fclose( fp ); // printf ("_init hairstack with %s\n",Gvoxname);fflush(stdout); return ( ret ); } // (create) return the number of voxels, init's the engine void TESTPRIMfetch_voxel_by_name( int index, char *nodename, HAIRTYPE * outhair, int isShadow ) { int addx, addy, addz; int voxdim; int x; UVSETS uv; voxdim = Gvoxdim; addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; SHAVEinit_hairtype( outhair ); for( x = 0; x < totalhairfiles; x++ ) { //printf ("\n vox [ %d %d %d] = ",addx,addy,addz); if( strcmp( nodename, Gshavep[x].name ) == 0 ) { //extern void SHAVEimport_archive_voxel_by_node( char *fname, int xxx, // int yyy, int zzz, // UVSETS * outuv, // int isShadow, // int node_id ); SHAVEimport_archive_voxel_by_node( Gvoxname, addx, addy, addz, outhair, &uv, 0, x ); //printf ("%d",outhair->totalfaces); SHAVEfree_UV( &uv ); } } } // Note: i had to ifdef these function out since STANDALONESDK_API is not defined. // // Pierre Baillargeon, Innobec, 13 September 2006 #ifndef XSI_SOFT3D_ONLY static int GPRIMdiag = 0; static char GPRIMdiagfile[777]; STANDALONESDK_API void PRIMDiagnosticON( CHNG *fname ) { sprintf( GPRIMdiagfile, "%s", fname ); GPRIMdiag = 1; } STANDALONESDK_API void PRIMclear_hairstack( void ) { FILE *fpdiag = NULL; if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMclear_hairstackentry\n" ); Gvoxdim = 0; SHAVEclear_stack( ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMclear_hairstackexit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); } STANDALONESDK_API int PRIMfetch_bbox( int index, VERT * obound1, VERT * obound2 ) // return -1 if fails { int addx, addy, addz; int voxdim = 0; int ret; FILE *fpdiag = NULL; if( Gplog ) { if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_bbox entry\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "index = %d\n", index ); ret = -1; voxdim = Gvoxdim; if( index < ( voxdim ) * ( voxdim ) * ( voxdim ) ) if( voxdim > 0 ) { addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; ////printf ("addx,addy,addz = %d %d %d\n",addx,addy,addz);fflush(stdout); //printf ("Gvoxname = %s\n",Gvoxname);fflush(stdout); ret = SHAVEimport_archive_voxel_bbox( Gvoxname, addx, addy, addz, obound1, obound2 ); } if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_bbox exit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); } return ( ret ); } STANDALONESDK_API void PRIMfetch_voxel( int index, HAIRTYPE * outhair, int isShadow ) { int addx, addy, addz; int voxdim; FILE *fpdiag = NULL; if( Gplog ) { if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_voxel entry\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "index = %d\n", index ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "isShadow = %d\n", isShadow ); voxdim = Gvoxdim; addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; SHAVEinit_hairtype( outhair ); if( index < ( voxdim ) * ( voxdim ) * ( voxdim ) ) SHAVEimport_archive_voxel( Gvoxname, addx, addy, addz, outhair, isShadow ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "hairs returned = %d\n", outhair->totalverts ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_voxel exit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); } } STANDALONESDK_API void PRIMfetch_voxel_by_name2( int index, char *nodename, HAIRTYPE * outhair, UVSETS * uv, int isShadow ); // This function is now deprecated. Use PRIMfetch_voxel_by_name2 instead. STANDALONESDK_API void PRIMfetch_voxel_by_name( int index, char *nodename, HAIRTYPE * outhair, int isShadow ) { PRIMfetch_voxel_by_name2( index, nodename, outhair, NULL, isShadow ); } STANDALONESDK_API void PRIMfetch_voxel_by_name2( int index, char *nodename, HAIRTYPE * outhair, UVSETS * uv, int isShadow ) { int addx, addy, addz; int voxdim; int x; FILE *fpdiag = NULL; if( Gplog ) { if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_voxel_by_name2 entry\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "index = %d\n", index ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "isShadow = %d\n", isShadow ); voxdim = Gvoxdim; addz = ( int ) floor( ( float ) index / ( float ) ( voxdim * voxdim ) ); index -= addz * ( voxdim * voxdim ); addy = ( int ) floor( ( float ) index / ( float ) ( voxdim ) ); index -= addy * ( voxdim ); addx = ( int ) index; SHAVEinit_hairtype( outhair ); for( x = 0; x < totalhairfiles; x++ ) { if( strcmp( nodename, Gshavep[x].name ) == 0 ) { // If the caller didn't pass us a UVSETS struct, then use a // temporary one. UVSETS tempUV; SHAVEinit_UV(&tempUV); if( uv == NULL ) uv = &tempUV; SHAVEinit_UV( uv ); SHAVEimport_archive_voxel_by_node( Gvoxname, addx, addy, addz, outhair, uv, 0, x ); // If we're using 'tempUV' then free it. SHAVEfree_UV( &tempUV ); // There should only be one node with this name, so we're // done. break; } } if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "hairs returned = %d\n", outhair->totalverts ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfetch_voxel_by_name2 exit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); //if (index<(voxdim)*(voxdim)*(voxdim)) //SHAVEimport_archive_voxel(Gvoxname,addx,addy,addz,outhair,isShadow); } } STANDALONESDK_API void PRIMfree_hairtype( HAIRTYPE * geom ) // this is for freeing the hairtype allocated by PRIMfetch_voxel { FILE *fpdiag = NULL; if( Gplog ) { if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfree_hairtype entry\n" ); SHAVEfree_hairtype( geom ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMfree_hairtype exit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); } } STANDALONESDK_API void PRIMfree_uvset( UVSETS * uvs ) // this is for freeing the UVSET allocated by PRIMfetch_voxel { } STANDALONESDK_API int PRIMlogin( void ) { Gplog=1; SHAVEinit( ); return 1; } STANDALONESDK_API int PRIMlogout( void ) { Gplog = 0; SHAVEclear_stack( ); // july 2011 // SHAVEcleanup(); return ( 1 ); } STANDALONESDK_API int PRIMinit_hairstack( CHNG *fname ) { FILE *fp = NULL; int ret = -1; FILE *fpdiag = NULL; if( Gplog ) { if( GPRIMdiag ) fpdiag = fopen( GPRIMdiagfile, "a" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMinit_hairstack entry\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "filename = %s\n", fname ); Gvoxdim = 0; #ifdef DOUNICODE fp = MYfopen( fname, L"r" ); #else fp = MYfopen( fname, "r" ); #endif if( !fp ) if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "unable to read the file !!! The init will fail ******************\n" ); if( Gplog ) if( fp ) // found a file { fclose( fp ); fp = NULL; // Gvoxname=fname; memcpy( &Gvoxname, fname, sizeof( char ) * strlen( fname ) + 1 ); //printf ("debug1 = %s\n",Gvoxname);fflush(stdout); // SHAVEinit(); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "found file, doing the init\n" ); ret = SHAVEinit_hairstack_from_archive( fname ); ret = ret * ret * ret; if( ret == -1 ) if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "init failed !!! ******************\n" ); } if( fp ) fclose( fp ); // printf ("_init hairstack with %s\n",Gvoxname);fflush(stdout); if( ( GPRIMdiag ) && ( fpdiag ) ) fprintf( fpdiag, "PRIMinit_hairstack exit\n" ); if( ( GPRIMdiag ) && ( fpdiag ) ) fclose( fpdiag ); } return ( ret ); } // (create) return the number of voxels, init's the engine #endif /* xsi_soft3d_only */ extern void MAYAalloc( FREEZETYPE * ret ); extern void MAYANfree( FREEZETYPE * ret ); extern void MAYAset_state( MEMFILE *, MEMFILE *, float uu, char *stat1, char *stat2 ); extern void MAYAset_stateglue( WFTYPE *, MEMFILE *, MEMFILE *, float uu, char *stat1, char *stat2 ); extern void MAYAset_stateMEM( MEMFILE * node, MEMFILE * state, float uu, MEMFILE * stat1, MEMFILE * stat2 ); extern void MAYAflush_state( MEMFILE * node, MEMFILE * state ); extern void MAYAxplant( CHNG *xfile ); extern void MAYAxplantNOMAT( CHNG *xfile ); extern void MAYArefresh( CHNG *objfilename, MEMFILE *, MEMFILE *, SHAVEPARMS * ); extern void MAYAwrite_hairDISK( CHNG *hairfilename ); extern void MAYAread_hairDISK( CHNG *hairfilename, MEMFILE *, MEMFILE * ); //extern void MAYAread_hairMEM( MEMFILE *,MEMFILE *); extern void MAYAxform2( WFTYPE * objfile, MEMFILE * node, MEMFILE * node_state, int run_dyn, char *stat, SHAVEPARMS * shavep ); extern void MAYAxform2FAST( WFTYPE * objfile, int run_dyn); extern void MAYAxform( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn, char *statfile ); extern void MAYAmake_a_hair( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO * cinfo ); extern void MAYAmake_view_matrix( Matrix vm, VERT vv, VERT nn, VERT wpos, float fov ); extern void MAYAclear_scene( void ); extern void MAYAclear_scene( void ); extern void MAYAinit_scene( void ); extern int MAYAadd_light( float r, float g, float b, Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip, float fuzz, int shadsamps, float shadred, float shadgreen, float shadblue, int trace, int type /* 0=point 1=spot */ ); extern void MAYAset_cameraOPEN( Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip ); extern void MAYAset_cameraCLOSE( Matrix vm, VERT wpos ); extern void MAYAadd_hairOPEN( MEMFILE * hairdataREST, MEMFILE * hairstateOPEN ); extern void MAYAadd_hairCLOSE( MEMFILE * hairstateCLOSE, SHAVEPARMS * sparms ); //extern int MAYArender_frame(WFTYPE *geom_open, WFTYPE *geom_close, int oversampling, unsigned char *image, float *zbuff,int clipx0,int clipy0,int clipx1,int clipy1,int deep_shadows); extern void MAYAadd_hairOPEN2( MEMFILE * hairdataREST, MEMFILE * hairstateOPEN, int index ); extern void MAYAadd_hairCLOSE2( MEMFILE * hairstateCLOSE, SHAVEPARMS * sparms, int index ); extern int MAYArender_shadows( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, int deep_shadows ); extern int MAYArender_cam( WFTYPE * geom_open, WFTYPE * geom_close, int antialiasing, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice ); extern void MAYAwrite_targa( char filename[255], short width, short height, unsigned char *image ); extern int SOFTfetch_guideNOISESPACE( int vertno, SOFTGUIDE * ); extern int SOFTfetch_guide( int vertno, SOFTGUIDE * ); extern void SOFTput_guide( int vertno, SOFTGUIDE * ); extern void SOFTput_guideNOCALC( int vertno, SOFTGUIDE * ); extern void SOFTset_vert_parm( int vertno, int chan, float value ); extern void MAYAset_parms( SHAVEPARMS * shavep ); extern void MAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * ); extern void MAYAxformNOSTAT( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn ); extern void SOFTcomb_select( VERT direction ); extern void SOFTscale_select( float factor ); extern void SOFTpop_zero( void ); extern void SOFTlock_select( void ); extern void SOFTunlock_select( void ); extern void SOFTget_instance( char *objfilename ); extern void SOFTattenuate_len( void ); extern void SOFTcut_select( void ); extern void SOFTsplit_select( void ); extern void SOFTmerge_select( void ); extern void SOFTshatter_select( void ); extern void MAYAfetch_parms( SHAVEPARMS * shavep ); extern void MAYAdump_stats( char *statname ); extern void MAYAfech_node( MEMFILE *, MEMFILE *, SHAVEPARMS * shavep ); extern void SOFTset_vert_parm( int vertno, int chan, float value ); extern float SOFTget_vert_parm( int vertno, int chan ); extern void MAYAset_parms( SHAVEPARMS * shavep ); extern void MAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * ); extern void MAYAxformNOSTAT( WFTYPE * objfile, MEMFILE *, MEMFILE *, int run_dyn ); extern void MAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE *, CURVEINFO * ); extern void MAYAmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE *, CURVEINFO * ); extern void MAYAmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE * ret, CURVEINFO * cret ); static int make_spline_hairROOT( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); static void MTdraw_lotsWFROOT( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * gs ); static int make_spline_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); extern void MAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret ); static int MTmake_spline_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo, GLOBS * gs ); void MTdraw_lotsWF( int slg, int ind, VERT offs, int clone, BASEHAIR * outhair, CURVEINFO * cinfo, GLOBS * gs ); void SHAVEmake_a_curveMT( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf, CURVEINFO * cret, int threadID ); void SHAVEmake_a_splineMT( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf, int threadID ); extern void MTMAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE *, GLOBS * gs ); static int MTmake_spline_hair( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo, GLOBS * gs ); static void MTcolor_a_hairROOT( BASEHAIR * h, GLOBS * gs ); int Gsculpt_cursors = 0; static void set_inst( WFTYPE * wf ); static void store_inst( WFTYPE * wf ); WFTYPE *GLOBALocclude=NULL; extern void SHAVEdraw_tile_callback(VERT *a,VERT *b); extern void SHAVEadd_occlusions( WFTYPE * wf ) { GLOBALocclude = wf; } extern int SHAVEfetch_guide( int vertno, SOFTGUIDE * sg ) { int ret; int x; ret = SOFTfetch_guide( vertno, sg ); //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertFROMSHAVE( &sg->guide[x] ); return ( ret ); } extern int SHAVEfetch_guideNOISE( int vertno, SOFTGUIDE * sg ) { int ret; int x; ret = SOFTfetch_guideNOISESPACE( vertno, sg ); //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertFROMSHAVE( &sg->guide[x] ); return ( ret ); } void SHAVEput_guide( int vertno, SOFTGUIDE * sg ) { int ret; int x; //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertTOSHAVE( &sg->guide[x] ); SOFTput_guide( vertno, sg ); //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertFROMSHAVE( &sg->guide[x] ); } void SHAVEput_guideNOCALC( int vertno, SOFTGUIDE * sg ) { int ret; int x; //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertTOSHAVE( &sg->guide[x] ); SOFTput_guideNOCALC( vertno, sg ); //for (x=0;x<15;x++) sg->guide[x].z*= -1.0f; for( x = 0; x < 15; x++ ) SHAVEcoord_convertFROMSHAVE( &sg->guide[x] ); } #ifdef EXTERNAL_COLLISION extern void SOFTput_guide( int vertno, SOFTGUIDE * ); // this function will force an eval as well // to re-validate lengths. #endif static void free_extra( void ); static VERT Ggravity_vector; static int make_spline_hairROOT( int slg, int hairnum, int clone, int segs, WFTYPE * geom, CURVEINFO * cinfo ); #ifdef SOFTIMAGE extern void MAYAdo_external_forces( int ); // 1 or 0 extern void MAYAset_gravity_vector( VERT ); #endif // returns 1 if success - u and v are stored in x and y extern int MAYAinsert_uv_coords( WFTYPE * ); // Note: these functions are provided by XSI and there is only one instance // of each of them, so they must not be declared inside the namespaces. // // So I moved them to shaveSDKCALLBACKS.h instead. // // Pierre Baillargeon, Innobec, September 2006. #ifndef XSI_SOFT3D_ONLY extern void MAYAexternal_collision( SOFTGUIDE * lastpos, SOFTGUIDE * vect, float seglen ); extern void MAYAexternal_forces( VERT *, VERT *, int y ); // position and direction/velcocity (this is a CALLBACK from shave to host app) extern void MAYAcache_forces(int clearCache); extern void MAYAapply_cached_forces(int guideNum, int vertNum, VERT* vect); #endif extern void clear_shave_engine( void ); extern int MAYAquery_shave_ID( void ); extern void SOFTput_guideSELECTONLY( int vertno, SOFTGUIDE * guide ); CHNG * MAYAquery_version( void ) { return ( version_info ); } extern void SOFTpop_select( float scale ); extern void MAYAfetch_node( MEMFILE * a, MEMFILE * b, SHAVEPARMS * shavep ); extern void MAYAfetch_node_for_game( MEMFILE * a, MEMFILE * b, SHAVEPARMS * shavep ); // wrapper stuff here void SHAVEcalibrate( float x, float y ) { calibrateX = x; calibrateY = y; } //extern void MAYAread_hairMEM(MEMFILE *restMEM,MEMFILE *statMEM) //{ //MAYAflush_state( restMEM,statMEM); //} void SHAVEflush_state( SHAVENODE * sn ) { global_lastID = -1; SHAVEID = (unsigned long )sn->restMEM.ID; MAYAflush_state( &sn->restMEM, &sn->statMEM ); MAYAset_parms( &sn->shavep ); #ifdef diagnose_trouble fprintf(stdout,"ID = %d clumps = %d shaveflushstate\n",SHAVEID,Gclumps); #endif } void SHAVEset_parms( SHAVEPARMS * shavep ) { // if (!DEGENERATE_OBJECT) MAYAset_parms( shavep ); // SHAVEmutex_lock(&Gtile_render_mutex); #ifdef diagnose_trouble fprintf(stdout,"ID = %d clumps = %d shavesetparms\n",SHAVEID,Gclumps); #endif } void SHAVEset_state( MEMFILE * a, MEMFILE * b, float uu,CHNG *stat1, CHNG *stat2 ) { MAYAset_state( a, b, uu, stat1, stat2 ); } void SHAVEset_stateMEM( MEMFILE * node, MEMFILE * state, float uu, MEMFILE * stat1, MEMFILE * stat2 ) { MAYAset_stateMEM( node, state, uu, stat1, stat2 ); } void SHAVEset_native(int nat) { Gnative_lighting=nat; } void SHAVExplant( CHNG *xfile, SHAVENODE * sn ) { SHAVEPARMS tmpparms; int istat; WFTYPE wf; // MAYArefresh(NULL,&sn->restMEM,&sn->statMEM,&sn->shavep); //if (totalhairfiles==0) we'll allow this in render context { SHAVEflush_state( sn ); SHAVEreplace_rest( sn ); SHAVEfetch_parms( &tmpparms ); reset_noisespace( ); istat = sn->shavep.instancing_status; init_geomWF( &wf ); store_inst( &wf ); NEWxplant( xfile ); SHAVEset_parms( &tmpparms ); Gbeen_scaled = 1; reset_rest( ); set_inst( &wf ); free_geomWF( &wf ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); sn->shavep.instancing_status = istat; } } void SHAVExplantNOMAT( CHNG *xfile, SHAVENODE * sn ) { SHAVEPARMS tmpparms; int istat; WFTYPE wf; SHAVEflush_state( sn ); SHAVEreplace_rest( sn ); SHAVEfetch_parms( &tmpparms ); reset_noisespace( ); istat = sn->shavep.instancing_status; init_geomWF( &wf ); store_inst( &wf ); NEWxplant( xfile ); SHAVEset_parms( &tmpparms ); Gbeen_scaled = 1; reset_rest( ); set_inst( &wf ); free_geomWF( &wf ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); sn->shavep.instancing_status = istat; } extern void SHAVEfetch_node( SHAVENODE * sn ); extern void SHAVEflush_state( SHAVENODE * sn ); extern void SHAVEreplace_rest( SHAVENODE * sn ); extern void SHAVEupgrade_node( SHAVENODE * sn ) { int x; int y; char shaveVersion2=0; int BADFILE=0; RW_CONTEXT=RW_LOCAL; read_hair( &sn->restMEM ); if( &sn->restMEM ) if (sn->restMEM.size>2) { shaveVersion2= sn->restMEM.data[2]; } for( x = 0; x < totalverts; x++ ) { for (y=0;y<15;y++) { hair[x].select[y]=1; } } for( x = 0; x < total_splines; x++ ) { for (y=0;y<15;y++) { Shair[x].select[y]=1; } } if (totalverts>0) { for( x = 0; x < totalverts; x++ ) if( hair[x].restlength < 0.0001f ) { VERT qq; hair[x].restlength = 0.0f; qq = v[x]; for( y = 0; y < 15; y++ ) hair[x].hv[y] = qq; } // this necessary ?? I don't think it isreset_rest(); //4.5.10 // got rid of it in 4.5.27 if (shaveVersion2!='s') { printf ("upgrading Node from version %c\n",shaveVersion2); reset_rest(); // we've upgraded; } } MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); // SHAVEflush_state( sn ); //fflush(stdout); //#endif } void SHAVEwrite_hairDISK( CHNG *hairfilename, SHAVENODE * sn ) { SHAVEflush_state( sn ); // MAYArefresh(NULL,&sn->restMEM,&sn->statMEM,&sn->shavep); SHAVEreplace_rest( sn ); reset_noisespace( ); MAYAset_parms( &sn->shavep ); MAYAwrite_hairDISK( hairfilename ); } void SHAVEwrite_hairDISKMAX( CHNG *hairfilename, SHAVENODE * sn ) { SHAVEreplace_rest( sn ); reset_noisespace( ); // SHAVEflush_state(sn); // MAYArefresh(NULL,&sn->restMEM,&sn->statMEM,&sn->shavep); MAYAset_parms( &sn->shavep ); // MAXMODE=1; MAYAwrite_hairDISK( hairfilename ); MAXMODE = 0; } void SHAVEmake_a_hair( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf ) { int x; CURVEINFO cinfo; cinfo.hairID=hairnum; //cinfo.nodeID=SHAVEID; cinfo.nodeID=GnodeID; //GnodeID=SHAVEID; cinfo.groupID=slg; Gslg=slg; cinfo.killme = 1; // MAYAmake_a_hair( current_samp, slg, hairnum, segs, wf, &cinfo ); MAYAmake_a_hair( 0, slg, hairnum, segs, wf, &cinfo ); // if (cinfo.killme==1) free_geomWF(wf); // watch out for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); SHAVEcoord_convertFROMSHAVE( &wf->vn[x] ); SHAVEcoord_convertFROMSHAVE( &wf->velocity[x] ); } if( 0 == 1 ) if( flip_norms ) { int buffi[555]; int z; int y; for( x = 0; x < wf->totalfaces; x++ ) { z = 0; for( y = wf->face_start[x]; y < wf->face_end[x]; y++ ) { buffi[z] = wf->facelist[y]; z++; } z = wf->face_end[x] - 1 - wf->face_end[x]; for( y = wf->face_start[x]; y < wf->face_end[x]; y++ ) { wf->facelist[y] = buffi[z]; z--; } } } cinfo.hairID=hairnum; cinfo.shaveID=SHAVEID; cinfo.nodeID=GnodeID; //GnodeID=SHAVEID; cinfo.groupID=slg; Gslg=slg; } void SHAVEgetobj( CHNG *name, WFTYPE * wfdata ) { // int x; MAYAgetobj( name, wfdata ); } static void FRAME_BOX( VERT a, VERT b ); void SHAVEmake_view_matrix( Matrix vm, VERT vv, VERT nn, VERT wpos, float fov ) { fov /= 2.0f; nn.z = -nn.z; vv.z = -vv.z; wpos.z = -wpos.z; SHAVEcoord_convertTOSHAVE( &vv ); SHAVEcoord_convertTOSHAVE( &nn ); SHAVEcoord_convertTOSHAVE( &wpos ); MAYAmake_view_matrix( vm, vv, nn, wpos, fov ); } void SHAVEclear_scene( void ) { if( undo ) { free( undo ); undo = NULL; } if( Sundo ) { free( Sundo ); Sundo = NULL; } MAYAclear_scene( ); if( Global_debug ) fclose( Global_debug ); } static void VXinit( void ); static void init_freeze( void ); static void alloc_freeze( void ); static void xforminst( int num ); static void xforminstMT(WFTYPE *ret,int ind, GLOBS *gs ); VERT Gspec_tint; VERT Gspec_tint2; // this initializes everything shave - call it on entry void SHAVEinit( void ) { int x, y; float zr = 0.0f; int th; th=SHAVEnum_processors(); GthreadGroup= SHAVEstart_thread_group(th); // windows only leak detection #ifdef _WIN32 _CrtDumpMemoryLeaks(); #endif // NaN = zr / zr; NaN = 0.0f; lsSHAVEID = -2; Gspec_tint.x = 1.0f; Gspec_tint.y = 1.0f; Gspec_tint.z = 1.0f; Gspec_tint2.x = 0.0f; Gspec_tint2.y = 0.0f; Gspec_tint2.z = 0.0f; Dinitverts(); //Global_debug=fopen("c:\\shavelog.txt","w"); for( x = 0; x < 255; x++ ) LWlight[x].Gzbuff = NULL; for( x = 0; x < 255; x++ ) { LWlight[x].zbuff = NULL; LWlight[x].xres = 0; LWlight[x].ibound = 0; LWlight[x].gbound = 0; LWlight[x].zbound = 0; } for( x = 0; x < 60; x++ ) { init_geomWF( &Guv_sets[x] ); } for( x = 0; x < 255; x++ ) for( y = 0; y < 5; y++ ) { Gtex_totalchannels[x][y] = 0; Gtex_cacheinfo[x][y] = NULL; Gtex_cachedisplace[x][y] = NULL; } for( x = 0; x < 60; x++ ) init_geomWF( &Guv_sets[x] ); for( x = 0; x < 60; x++ ) for( y = 0; y < 5; y++ ) Gtex_channellink[x][y] = -1; init_threads( ); VXinit( ); init_freeze( ); MAYAinit_scene( ); init_noise( ); Gclumps=0; Gindex=NULL; Gtotal_splinelocks= 0; if (0==1) { long seed=1; fprintf (stdout,"test rand \n");fflush(stdout); for (x=0;x<10000;x++) fprintf (stdout,"%f ",randcl(seed+=500)); fprintf (stdout,"\n");fflush(stdout); } } // this cleans up everything shave - call it on exit void SHAVEcleanup( void ) { fprintf(stdout,"SHAVEcleanup()");fflush(stdout); if( undo ) { free( undo ); undo = NULL; } if( Sundo ) { free( Sundo ); Sundo = NULL; } destroy_threads( ); SHAVEclear_stack(); MAYAclear_scene( ); Dfreeverts( ); Dtotalverts = 0; Stotalverts = 0; totalverts = 0; total_splines = 0; Stotalverts = 0; Dtotallines = 0; Dtotalverts = 0; Dtotalfverts = 0; Dtotalfaces = 0; Dtotalverts = 0; Dtotalfverts = 0; Dtotalfaces = 0; DUTtotalfaces = 0; DUTtotalfverts = 0; if( undo ) free( undo ); undo = NULL; if( Sundo ) free( Sundo ); Sundo = NULL; undo_totalverts = 0; Sundo_totalverts = 0; last_totalverts = -2; last_total_splines = -2; clear_uvsets( ); Gtotal_splinelocks= 0; //if (Gindex) //free(Gindex); //kd_free(Gkd); free_clumping(); free_renderstate_stack(); SHAVEend_thread_group(GthreadGroup); } static void mkmatrix( Matrix m, VERT xx, VERT yy, VERT zz, VERT b ); static VERT Vcross( VERT a, VERT b ); int SHAVEadd_light( float r, float g, float b, Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float fuzz, int shadsamps, float shadr, float shadg, float shadb, int trace, float nearClip ) { int ret1; VERT up, forward, right; float ffov = 0; ffov = ( ( float ) fuzz / ( float ) ( xres / 2 ) ) / 45.0f; fov += ffov; // adjust fov to include fuzz; // fov/= 2.0f; SHADOWS_DONE = 0; SHAVEcoord_convertTOSHAVE( &wpos ); wpos.z = -wpos.z; if( trace == 1 ) { xres = 0; yres = 0; printf( "added a traced light\n" ); } LWlight[totallights].isroot = 1; ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, shadsamps, shadr, shadg, shadb, trace, 1 ); return ( ret1 ); } int SHAVEadd_point_light( float r, float g, float b, VERT wpos, int xres, int yres, float fuzz, int shadsamps, float shadr, float shadg, float shadb, int trace, float nearClip ) { // fov/= 2.0f; float aspect = 1.0; VERT up, forward, right; int ret = 0; int ret1 = 0; Matrix vm; // float fov=44.0f; // float fov=45.9999f; float fov = 46.9999f; float ffov = 0; ffov = ( ( float ) fuzz / ( float ) ( xres / 2 ) ) / 45.0f; fov += ffov; // adjust fov to include fuzz; yres = xres; // make it square SHADOWS_DONE = 0; SHAVEcoord_convertTOSHAVE( &wpos ); wpos.z = -wpos.z; // r=255.0f;g=255.0f;b=255.0f; if( trace == 1 ) { xres = 0; yres = 0; printf( "added a traced light\n" ); } // 1st light up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; forward.x = 0.0f; forward.y = 0.0f; forward.z = 1.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); LWlight[totallights].isroot = 1; ret = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); // 2nd light LWlight[totallights].isroot = 0; up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; forward.x = 0.0f; forward.y = 0.0f; forward.z = -1.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); // 3rd light LWlight[totallights].isroot = 0; up.x = 0.0f; up.y = 0.0f; up.z = 1.0f; forward.x = 0.0f; forward.y = 1.0f; forward.z = 0.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); // 4th light LWlight[totallights].isroot = 0; up.x = 0.0f; up.y = 0.0f; up.z = 1.0f; forward.x = 0.0f; forward.y = -1.0f; forward.z = 0.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); // 5th light LWlight[totallights].isroot = 0; up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; forward.x = 1.0f; forward.y = 0.0f; forward.z = 0.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); // 6th light LWlight[totallights].isroot = 0; up.x = 0.0f; up.y = 1.0f; up.z = 0.0f; forward.x = -1.0f; forward.y = 0.0f; forward.z = 0.0f; MAYAmake_view_matrix( vm, up, forward, wpos, fov ); ret1 = MAYAadd_light( r, g, b, vm, wpos, xres, yres, aspect, fov, nearClip, fuzz, 1, shadr, shadg, shadb, trace, 0 ); return ( ret ); // temporary // return ( MAYAadd_light // ( r, g, b, vm, wpos, xres, yres, aspect, fov, fuzz, shadsamps, // shadr, shadg, shadb, trace ) ); } void SHAVEset_cameraOPEN( Matrix vm, VERT wpos, int xres, int yres, float aspect, float fov, float nearClip ) { fov /= 2.0f; LWCamOPEN.fov=fov; SHAVEcoord_convertTOSHAVE( &wpos ); wpos.z = -wpos.z; MAYAset_cameraOPEN( vm, wpos, xres, yres, aspect, fov, nearClip ); } void SHAVEset_cameraCLOSE( Matrix vm, VERT wpos ) { LWCamCLOSE.fov=LWCamOPEN.fov; SHAVEcoord_convertTOSHAVE( &wpos ); wpos.z = -wpos.z; MAYAset_cameraCLOSE( vm, wpos ); } //extern void SHAVEwrite_targa( CHNG filename[255], short width, short height, unsigned char *image ) { MAYAwrite_targa( filename, width, height, image ); } void SHAVEmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf ) { int x; MAYAmake_a_spline( current_samp, slg, hairnum, segs, wf ); for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); } } void SHAVEmake_a_splineMT( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf, int threadid ) { int x; MTMAYAmake_a_spline( current_samp, slg, hairnum, segs, wf, >hreads[threadid] ); for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); } } extern void SHAVEGAMExform (VERT *in,MINIKERNAL *k, int run_dyn) { int x; WFTYPE wf; init_geomWF(&wf); SHAVEflush_state(&k->shavenode); wf.totalverts=Dtotalverts; wf.totalfaces=Dtotalfaces; wf.totalfverts=Dtotalfverts; alloc_geomWF(&wf); for (x=0;xshavenode.restMEM, &k->shavenode.statMEM, run_dyn ); SHAVEupdate_kernal(k,&k->shavenode.shavep); //SHAVEfetch_node(&k->shavenode); free_geomWF(&wf); } void SHAVExformNOSTAT( WFTYPE * objstruct, MEMFILE * a, MEMFILE * b, int run_dyn ) { int x; // for (x=0;xtotalverts;x++) objstruct->v[x].z *= -1.0f; MAYAxformNOSTAT( objstruct, a, b, run_dyn ); // for (x=0;xtotalverts;x++) objstruct->v[x].z *= -1.0f; // if (hair) // if (Gclumps>3) } void SHAVEfetch_parms( SHAVEPARMS * shavep ) { MAYAfetch_parms( shavep ); } void SHAVEdump_stats( CHNG *statname ) { MAYAdump_stats( statname ); } extern void MTMAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret, GLOBS * gs ); void SHAVEmake_a_curveROOT( int current_samp, int slg, int hairnum, WFTYPE * wf, CURVEINFO * cret ) { int x; cret->killme = 1; #ifdef NOLIB segs = 15; // badhack #endif // MTMAYAmake_a_curve( current_samp, slg, hairnum, 0, wf, cret, >hreads[0] ); MAYAmake_a_curveROOT( current_samp, slg, hairnum, wf, cret ); for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; // wf->velocity[x].z= -wf->velocity[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); SHAVEcoord_convertFROMSHAVE( &wf->velocity[x] ); } } void SHAVEmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf, CURVEINFO * cret ) { int x; cret->killme = 1; #ifdef NOLIB segs = 15; // badhack #endif MTMAYAmake_a_curve( current_samp, slg, hairnum, segs, wf, cret, >hreads[0] ); for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; // wf->velocity[x].z= -wf->velocity[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); SHAVEcoord_convertFROMSHAVE( &wf->velocity[x] ); } } extern void MTMAYAmake_a_curve( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, CURVEINFO * cret, GLOBS * gs ); extern void MTMAYAmake_a_spline( int current_samp, int slg, int hairnum, int segs, WFTYPE * ret, GLOBS * gs ); static BASEHAIR MTgen_resthair_ROOT( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); static BASEHAIR MTgen_resthair_ROOTRS( int id, int slg, CURVEINFO * cinfo, GLOBS * gs ); void SHAVEmake_a_curveMT( int current_samp, int slg, int hairnum, int segs, WFTYPE * wf, CURVEINFO * cret, int threadID ) { int x; GLOBS *gs; cret->killme = 1; //if (totalfaces>0) { #ifdef NOLIB segs = 15; // badhack #endif if( threadID >= SHAVE_MAX_THREADS ) { printf( "error:threadID too high\n" ); fflush( stdout ); threadID = SHAVE_MAX_THREADS - 1; } gthreads[threadID].threadID = threadID; gs = >hreads[threadID]; gs->Gcurpass = current_samp; Gcurpass=current_samp; gs->GhairID = hairnum; gs->Gslg = slg; gs->hairnumber = hairnum; Gslg=slg; GhairID=hairnum; cursamp=current_samp; //printf ("running MTMayamake_a_curve\n");fflush(stdout); MTMAYAmake_a_curve( current_samp, slg, hairnum, segs, wf, cret, >hreads[threadID] ); for( x = 0; x < wf->totalverts; x++ ) { // wf->v[x].z= -wf->v[x].z; // wf->velocity[x].z= -wf->velocity[x].z; SHAVEcoord_convertFROMSHAVE( &wf->v[x] ); SHAVEcoord_convertFROMSHAVE( &wf->velocity[x] ); } } } //extern void MAYAdo_external_forces(int); // 1 or 0 //extern void MAYAset_gravity_vector(VERT); int SHAVEinsert_uv_coords( WFTYPE * wf, SHAVENODE * sn ) { MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); return ( MAYAinsert_uv_coords( wf ) ); } /////void MAYAexternal_forces(VERT *,VERT *); // position and direction/velcocity (this is a CALLBACK from shave to host app) /////void MAYAexternal_collision(SOFTGUIDE *lastpos, SOFTGUIDE *vect, float seglen); /////void MAYAexternal_forces(VERT *lastpos, VERT *vect) unsigned long SHAVEquery_shave_ID( void ) { return ( MAYAquery_shave_ID( ) ); } CHNG * SHAVEquery_version( void ) { return ( MAYAquery_version( ) ); } #ifndef XSI_SOFT3D_ONLY float SHAVEapply_falloff( int lightNUM, VERT pos, float cone ); #endif static void Gilluminate_strand( WFTYPE * pos, int ll, float hambient ); float illum_box_cursamp( float inz, int lgt, int lx, int ly, int hx, int hy, int pass ); float illum_box( float inz, int lgt, int lx, int ly, int hx, int hy ); static VERT cast_shadows_lgt_simpleRS( VERT worldPt, int lgt,GLOBS *gs ); // new stuff void SHAVEcreate_node( CHNG *objfilename, SHAVENODE * sn ) { FILE *fp = NULL; FILE *dg = NULL; int low_mem=0; CHNG tmpname[1555]; // dg = fopen ("c:\\temp.txt","a"); RW_CONTEXT=RW_DISK; SHAVEID=sn->restMEM.ID; //fprintf (dg,"maxtest: create_node1\n");fflush(stdout); #ifdef DOUNICODE swprintf( tmpname, L"%s", objfilename ); fp = MYfopen( tmpname, L"r" ); // fp = MYfopen( objfilename, L"r" ); #else sprintf( tmpname, "%s", objfilename ); fp = MYfopen( objfilename, "r" ); #endif if( fp != NULL ) { fclose( fp ); // fp=fopen("c:\\filename.txt","w"); // fprintf(fp,"%s\n",objfilename); // fclose(fp); // SHAVErefresh(objfilename,&sn->restMEM,&sn->statMEM,&sn->shavep); //fprintf (dg,"maxtest: create_node2\n"); MAYArefresh( objfilename, &sn->restMEM, &sn->statMEM, &sn->shavep ); set_defaults(); MAYAfetch_parms( &sn->shavep ); //fprintf (dg,"totalverts = %d\n",totalverts); } // else // fprintf(dg, "couldn't find %s in SHAVEcreate_node\n", objfilename ); //printf ("maxtest: create_node3\n"); SHAVEreplace_rest( sn ); // fclose(dg ); low_mem = 0; } void SHAVEread_hairDISK( CHNG *hairfilename, SHAVENODE * sn ) { int low_mem=0; free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAread_hairDISK( hairfilename, &sn->restMEM, &sn->statMEM ); SHAVEfetch_parms( &sn->shavep ); make_normals( ); Gbeen_scaled = 1; reset_noisespace( ); //printf ("totalverts in the .hair file === %d\n",Dtotalverts); reset_rest( ); reset_dynamics( ); mkHandles( ); mkbounds( ); SHAVEreplace_rest( sn ); low_mem = 0; } void SHAVEfetch_node( SHAVENODE * sn ) { MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); } void SHAVEfetch_node_for_game( SHAVENODE * sn ) { MAYAfetch_node_for_game( &sn->restMEM, &sn->statMEM, &sn->shavep ); } void SHAVEadd_hairOPEN( SHAVENODE * sn ) { // SHAVEflush_state(sn); // MAYAset_parms(&sn->shavep); // MAYAfetch_node(&sn->restMEM,&sn->statMEM,NULL); SHAVEdestroy_buffers(); MAYAadd_hairOPEN( &sn->restMEM, &sn->statMEM ); } void SHAVEadd_hairCLOSE( SHAVENODE * sn ) { SHAVEdestroy_buffers(); // SHAVEflush_state(sn); // MAYAfetch_node(&sn->restMEM,&sn->statMEM,NULL); //if (sn->statMEM.size==hairfiles[totalhairfiles].statMEM.size) // if (sn->restMEM.size==hairfiles[totalhairfiles].size) MAYAadd_hairCLOSE( &sn->statMEM, &sn->shavep ); //else totalhairfiles++; // MAYAset_parms(&sn->shavep); } static void MAYAset_stack_max( int index ); void SHAVEset_stack_max( int index ) { MAYAset_stack_max( index ); } void SHAVEadd_hairOPEN2( SHAVENODE * sn, int index ) { SHAVEdestroy_buffers(); // SHAVEflush_state(sn); // MAYAset_parms(&sn->shavep); // MAYAfetch_node(&sn->restMEM,&sn->statMEM,NULL); MAYAadd_hairOPEN2( &sn->restMEM, &sn->statMEM, index ); } void SHAVEadd_hairCLOSE2( SHAVENODE * sn, int index ) { // SHAVEflush_state(sn); // MAYAset_parms(&sn->shavep); // MAYAfetch_node(&sn->restMEM,&sn->statMEM,NULL); MAYAadd_hairCLOSE2( &sn->statMEM, &sn->shavep, index ); } void SHAVExform( WFTYPE * objstruct, SHAVENODE * sn, int run_dyn, CHNG *statfile ) { int x; //printf ("doing an xform\n"); //GnodeID=sn->restMEM.ID; SHAVEID = sn->restMEM.ID; for( x = 0; x < objstruct->totalverts; x++ ) SHAVEcoord_convertTOSHAVE( &objstruct->v[x] ); MAYAxform2( objstruct, &sn->restMEM, &sn->statMEM, run_dyn, statfile, &sn->shavep ); for( x = 0; x < objstruct->totalverts; x++ ) SHAVEcoord_convertFROMSHAVE( &objstruct->v[x] ); if( !DEGENERATE_OBJECT ) MAYAset_parms( &sn->shavep ); #ifdef diagnose_trouble fprintf(stdout,"xform ID = %d clumps = %d shavexforms\n",SHAVEID,Gclumps);fflush(stdout); #endif } void SHAVEreset_to_rest( SHAVENODE * sn ) { MAYAflush_state( &sn->restMEM, &sn->statMEM ); reset_dynamics( ); reset_rest( ); } void SHAVEset_state_between( SHAVENODE * sn, float uu, CHNG *stat1, CHNG *stat2 ) { SHAVEID = sn->restMEM.ID; MAYAset_state( &sn->restMEM, &sn->statMEM, uu, stat1, stat2 ); MAYAset_parms( &sn->shavep ); // fprintf(stdout,"state between ID = %d clumps = %d set_state_between\n",SHAVEID,Gclumps);fflush(stdout); } void SHAVEset_state_between_and_glue( WFTYPE * wf, SHAVENODE * sn, float uu, CHNG *stat1, CHNG *stat2 ) { int x; for (x=0;xtotalverts;x++) { wf->v[x].z*= -1.0f; } MAYAset_stateglue( wf, &sn->restMEM, &sn->statMEM, uu, stat1, stat2 ); // for (x=0;xtotalverts;x++) // { // wf->v[x].z*= -1.0f; // } SHAVEID = sn->restMEM.ID; MAYAset_parms( &sn->shavep ); // fprintf(stdout,"set_state_and_glue ID = %d clumps = %d set state between and glue\n",SHAVEID,Gclumps);fflush(stdout); } void SHAVEcopy_node( SHAVENODE * sn, SHAVENODE * snsource, long newID ) { copy_MEMFILE( &sn->restMEM, &snsource->restMEM ); copy_MEMFILE( &sn->statMEM, &snsource->statMEM ); memcpy( &sn->shavep, &snsource->shavep, sizeof( SHAVEPARMS ) ); sn->restMEM.ID = newID; sn->statMEM.ID = newID; } void clear_texcache( void ) { int x; int y; TEXCACHEMODE = 0; for( x = 0; x < totalhairfiles; x++ ) for( y = 0; y < 5; y++ ) { if( Gtex_cacheinfo[x][y] ) free( Gtex_cacheinfo[x][y] ); if( Gtex_cachedisplace[x][y] ) free( Gtex_cachedisplace[x][y] ); Gtex_cacheinfo[x][y] = NULL; Gtex_cachedisplace[x][y] = NULL; Gtex_totalchannels[x][y] = 0; } for( x = 0; x < totalhairfiles; x++ ) for( y = 0; y < 60; y++ ) { Gtex_channellink[x][y] = -1; } } void free_renderstate_stack(void); void SHAVEclear_stack( void ) { int x, y; if( DIAGNOSTIC ) printf( "clearing stack\n" ); for( x = 0; x < totalhairfiles; x++ ) for( y = 0; y < 5; y++ ) { // if (TEXCACHEMODE) { if (Gtex_cacheinfo[x][y]); free( Gtex_cacheinfo[x][y] ); if( Gtex_cachedisplace[x][y] ); free( Gtex_cachedisplace[x][y] ); } Gtex_cacheinfo[x][y] = NULL; Gtex_cachedisplace[x][y] = NULL; Gtex_totalchannels[x][y] = 0; } TEXCACHEMODE = 0; lsSHAVEID = -2; if( stack_is_from_archive ) { if( GLOBALocclude ) { free_geomWF( GLOBALocclude ); free( GLOBALocclude ); GLOBALocclude = NULL; } } stack_is_from_archive = 0; if( undo ) { free( undo ); undo = NULL; } if( Sundo ) { free( Sundo ); Sundo = NULL; } for( x = 0; x < totalhairfiles; x++ ) for( y = 0; y < 60; y++ ) { Gtex_channellink[x][y] = -1; } free_freeze( ); // joe - dec 2 // MAYAclear_scene( ); if( totalhairfiles > 0 ) { for( x = 0; x < totalhairfiles; x++ ) { if( hairfiles[x].data ) free( hairfiles[x].data ); hairfiles[x].data=NULL; } for( x = 0; x < totalhairfiles; x++ ) { if( hairstate[x].data ) free( hairstate[x].data ); hairstate[x].data=NULL; // if (Gindex_stack[x]) free(Gindex_stack[x]); // if (Gkd_stack[x]) kd_free(Gkd_stack[x]); } hairfiles[x].size = 0; hairfiles[x].pos = 0; hairstate[x].size = 0; hairstate[x].pos = 0; } destroy_buffers( ); totalhairfiles = 0; totallights = 0; totallights=0; Gmaps_active = 0; GIThairfile = 0; GITlasthairfile = -1; GIThairnumber = 0; GITpassnumber = 0; global_lastID = -1; VXclear( ); lsSHAVEID = -2; //SHAVEID = 0; free_renderstate_stack(); totalhairfiles=0; } void SHAVEfree_node( SHAVENODE * sn ) { free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); //clear_shave_engine(); } void SHAVEalloc_node( SHAVENODE * sn ) { alloc_MEMFILE( &sn->restMEM ); alloc_MEMFILE( &sn->statMEM ); } static void camspace_clipit( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ); static void camspace_clipitDEANE( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ); static void camspace_clipitDEANERS( POLYDAT pp, WFTYPE * ret, float xl, float yl, float xs, float ys, float nc /* near clip */ ,GLOBS *gs ); static void camspace_clipLine( POLYDAT * pp, float xl, float yl, float xs, float ys, float nc /* near clip */ ); static int draw_line2( POLYDAT pp, int layer, unsigned char lum ); static int draw_line( POLYDAT pp, int layer, unsigned char lum ); void SHAVEinit_node( SHAVENODE * sn, long ID ) { int x; set_defaults( ); init_MEMFILE( &sn->restMEM, ID ); init_MEMFILE( &sn->statMEM, ID ); SHAVEID=(unsigned long )ID; MAYAfetch_parms( &sn->shavep ); } void SHAVEactivate_texture( int x ) { Gmaps_active = x; } void SHAVEflip_normals( void ) { flip_norms = 1; } void SHAVEinsert_color_texturefilename( int slg, CHNG *texturefilename, int mapmethod, SHAVENODE * sn ) // slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline // insert/replace texture file name (TGA 24) // filename = '' means turn off texturing // mapmethod : // 0 = x projection (on rest model) // 1 = y projection // 2 = z projection // 3 = UV coords { long id; if( slg < 0 ) slg = 0; if( slg > 5 ) slg = 5; if( mapmethod < 0 ) mapmethod = 0; if( mapmethod > 3 ) mapmethod = 3; MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); sprintf( colmap[slg].name, "%s", texturefilename ); colmap[slg].flags = mapmethod; read_targa( colmap[slg].name, &colmap[slg] ); id = sn->restMEM.ID; free_MEMFILE( &sn->restMEM ); init_MEMFILE( &sn->restMEM, id ); MAYAfetch_node( &sn->restMEM, NULL, &sn->shavep ); } void SHAVEinsert_densiy_texturefilename( int slg, CHNG *texturefilename, int mapmethod, SHAVENODE * sn ) // slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline // insert/replace texture file name (TGA 24) // filename = '' means turn off texturing // mapmethod : // 0 = x projection (on rest model) // 1 = y projection // 2 = z projection // 3 = UV coords { long id; if( slg < 0 ) slg = 0; if( slg > 5 ) slg = 5; if( mapmethod < 0 ) mapmethod = 0; if( mapmethod > 3 ) mapmethod = 3; MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); sprintf( densemap[slg].name, "%s", texturefilename ); read_targa( densemap[slg].name, &densemap[slg] ); densemap[slg].flags = mapmethod; id = sn->restMEM.ID; free_MEMFILE( &sn->restMEM ); init_MEMFILE( &sn->restMEM, id ); MAYAfetch_node( &sn->restMEM, NULL, &sn->shavep ); } void SHAVEinsert_cutmap_texturefilename( int slg, CHNG *texturefilename, int mapmethod, SHAVENODE * sn ) // slg : 0=hair 2=beard 3=eyebrow 4=eyelash 5=spline // insert/replace texture file name (TGA 24) // filename = '' means turn off texturing // mapmethod : // 0 = x projection (on rest model) // 1 = y projection // 2 = z projection // 3 = UV coords { long id; if( slg < 0 ) slg = 0; if( slg > 5 ) slg = 5; if( mapmethod < 0 ) mapmethod = 0; if( mapmethod > 3 ) mapmethod = 3; MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); sprintf( lenmap[slg].name, "%s", texturefilename ); read_targa( lenmap[slg].name, &lenmap[slg] ); lenmap[slg].flags = mapmethod; id = sn->restMEM.ID; free_MEMFILE( &sn->restMEM ); init_MEMFILE( &sn->restMEM, id ); MAYAfetch_node( &sn->restMEM, NULL, &sn->shavep ); } void SHAVEget_instance( CHNG *objfilename, SHAVENODE * sn ) { MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); SHAVEset_parms( &sn->shavep ); global_lastID = -1; { SOFTget_instance( objfilename ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); //SHAVEfetch_node(&sn); } } void SHAVEget_instanceWF( WFTYPE * obj, SHAVENODE * sn ) { MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); SHAVEset_parms( &sn->shavep ); global_lastID = -1; { set_inst( obj ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); //SHAVEfetch_node(&sn); } } //void SOFTclear_instance(void); void SHAVEclear_instance( SHAVENODE * sn ) { // if (sn->restMEM.data!=NULL) MAYArefresh( NULL, &sn->restMEM, &sn->statMEM, &sn->shavep ); // if (sn->shavep.instancing_status) if( freeze.totalverts > 0 ) { free_freeze( ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); } } static void show_bg( void ); static void grab_bg( void ); int SHAVErender_cam( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice ) { int x; int ret = 1; int p; int th = 0; int low_mem=0; NOBLUR = 0; dice = 2; if( low_mem == 0 ) { if( GLOBAL_VERBOSE ) printf( "Motion Blur==ON\n" ); for( x = 0; x < totalhairfiles; x++ ) { int y; for( y = 0; y < 5; y++ ) { int n; n = ( int ) Gshavep[x].slider_val[25][y]; if( n < 1 ) n = 1; th += Gshavep[x].haircount[y] * (Gshavep[x].segs[y]*3) * n; } } dice = 2; GLOBALSAMP = 1; p = 1; if( ( oversampling > 2 ) && ( oversampling < 8 ) ) { GLOBALSAMP = 2; p = 1; } if( ( oversampling >= 8 ) && ( oversampling < 15 ) ) { GLOBALSAMP = 2; p = 3; dice *= 1; } if( ( oversampling >= 15 ) && ( oversampling < 20 ) ) { GLOBALSAMP = 3; p = 7; dice *= 2; } if( ( oversampling >= 20 ) && ( oversampling <= 120 ) ) { GLOBALSAMP = 3; dice *= 3; p = 14; } if( geom_open->totalverts != geom_close->totalverts ) SHAVEclear_stack( ); if( Global_debug ) fprintf( Global_debug, "SHAVErender_cam()\n" ); if( totalhairfiles == 0 ) { if( image ) for( x = 0; x < LWcam.xres * ( LWcam.yres ) * 4; x++ ) image[x] = 0; if( zbuff ) for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) zbuff[x] = 1000000.0f; } if( totalhairfiles > 0 ) { Gmaps_active = 1; GLOBALSAMP = 1; p = 1; if( ( oversampling > 2 ) && ( oversampling < 8 ) ) { GLOBALSAMP = 2; p = 1; } if( ( oversampling >= 8 ) && ( oversampling < 15 ) ) { GLOBALSAMP = 2; p = 3; } if( ( oversampling >= 15 ) && ( oversampling < 20 ) ) { GLOBALSAMP = 3; p = 7; } if( ( oversampling >= 20 ) && ( oversampling <= 120 ) ) { GLOBALSAMP = 3; p = 14; } oversampling = 1; //oversampling=p; Gmotion_samp = p; #ifndef MAX3D //dice = 3* xres/720; //dice*=p; //dice*=GLOBALSAMP; dice += 1; #endif if( GLOBAL_VERBOSE ) fflush( stdout ); { int pixbyte; int xr,yr; int sq; int target; float dc; int total_threads; target=Gtile_memory_limit; total_threads=SHAVEnum_processors(); pixbyte= (8*Gtransp_depth*Gmotion_samp +4*Gmotion_samp)*GLOBALSAMP*GLOBALSAMP*total_threads; target*=1024*1024; dc= ((float)target/(float)pixbyte); dc= sqrt((float)dc); if (dc>0.0f) dc=(float)xres/dc; else dc=1; if (dc*dc20)) GLOBALSAMP=6; //dice*=GLOBALSAMP; // for (x=0;xtotalverts;x++) SHAVEcoord_convertTOSHAVE(&geom_open->v[x]); // for (x=0;xtotalverts;x++) SHAVEcoord_convertTOSHAVE(&geom_close->v[x]); ret = MAYArender_cam( geom_open, geom_close, oversampling, image, zbuff, clipx0, clipy0, clipx1, clipy1, xres, yres, dice ); // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom_open->v[x]); // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom_close->v[x]); GLOBALSAMP = 1; Gmaps_active = 0; } } //if (low_mem) let's always cleanup { SHAVEclear_stack(); // SHAVEcleanup(); } if( GLOBAL_VERBOSE ) fflush( stdout ); low_mem = 0; return ( ret ); } int SHAVErender_camNOBLUR( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, unsigned char *image, float *zbuff, int clipx0, int clipy0, int clipx1, int clipy1, int xres, int yres, int dice ) { int x; int ret = 1; int th = 0; int low_mem=0; NOBLUR = 1; if( low_mem == 0 ) { if( GLOBAL_VERBOSE ) printf( "Motion Blur==OFF\n" ); for( x = 0; x < totalhairfiles; x++ ) { int y; for( y = 0; y < 5; y++ ) { int n; n = ( int ) Gshavep[x].slider_val[25][y]; if( n < 1 ) n = 1; th += Gshavep[x].haircount[y] * (Gshavep[x].segs[y]*3) * n; } } dice = 2; if( th > 100000 ) { dice = 3; if( GLOBAL_VERBOSE ) printf( "tiles bumped up to 3 by haircount\n" ); } if( th > 99999 ) { dice = ( int ) ( ( float ) th * ( ( float ) 5.0f / ( float ) ( 8000000 - 100000 ) ) + 3 ); if( GLOBAL_VERBOSE ) printf( "tiles bumped up to %d by triangle count of %d\n", dice, th * 2 ); if( GLOBAL_VERBOSE ) fflush( stdout ); } //{ // int gs; // gs=MAXPASSES/3; //if (gs<1) gs=1; //dice*=gs; //} GLOBALSAMP = 1; if( ( oversampling > 2 ) && ( oversampling < 8 ) ) { GLOBALSAMP = 2; } if( ( oversampling >= 8 ) && ( oversampling < 15 ) ) { GLOBALSAMP = 3; } if( ( oversampling >= 15 ) && ( oversampling < 20 ) ) { GLOBALSAMP = 4; } if( ( oversampling >= 20 ) && ( oversampling <= 120 ) ) { GLOBALSAMP = 5; } if( GLOBAL_VERBOSE ) printf( "tiles = %d\n", dice ); if( Global_debug ) fprintf( Global_debug, "SHAVErender_camNOBLUR()\n" ); if( geom_open->totalverts != geom_close->totalverts ) SHAVEclear_stack( ); if( totalhairfiles == 0 ) { if( image ) for( x = 0; x < LWcam.xres * ( LWcam.yres ) * 4; x++ ) image[x] = 0; if( zbuff ) for( x = 0; x < LWcam.xres * ( LWcam.yres ); x++ ) zbuff[x] = 1000000.0f; } if( totalhairfiles > 0 ) { int p = 1; Gmaps_active = 1; GLOBALSAMP = 1; if( ( oversampling > 2 ) && ( oversampling < 8 ) ) { GLOBALSAMP = 2; p = 1; } if( ( oversampling >= 8 ) && ( oversampling < 15 ) ) { GLOBALSAMP = 3; p = 2; } if( ( oversampling >= 15 ) && ( oversampling < 20 ) ) { GLOBALSAMP = 4; p = 4; } if( ( oversampling >= 20 ) && ( oversampling <= 120 ) ) { GLOBALSAMP = 5; p = 7; } oversampling = 1; Gmotion_samp = 1; { int pixbyte; int xr,yr; int sq; int target; float dc; int total_threads; target=Gtile_memory_limit; total_threads=SHAVEnum_processors(); pixbyte= (8*Gtransp_depth*Gmotion_samp +4*Gmotion_samp)*GLOBALSAMP*GLOBALSAMP*total_threads; target*=1024*1024; dc= ((float)target/(float)pixbyte); dc= sqrt((float)dc); if (dc>0.0f) dc=(float)xres/dc; else dc=1; if (dc*dc20)) GLOBALSAMP=6; //dice*=GLOBALSAMP; // for (x=0;xtotalverts;x++) SHAVEcoord_convertTOSHAVE(&geom_open->v[x]); // for (x=0;xtotalverts;x++) SHAVEcoord_convertTOSHAVE(&geom_close->v[x]); ret = MAYArender_cam( geom_open, geom_close, p, image, zbuff, clipx0, clipy0, clipx1, clipy1, xres, yres, dice ); // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom_open->v[x]); // for (x=0;xtotalverts;x++) SHAVEcoord_convertFROMSHAVE(&geom_close->v[x]); GLOBALSAMP = 1; Gmaps_active = 0; } } //if (low_mem) let's always clean up // {SHAVEclear_stack();SHAVEcleanup();} // SHAVEclear_stack(); low_mem = 0; if( GLOBAL_VERBOSE ) fflush( stdout ); return ( ret ); } int SHAVErender_shadows( WFTYPE * geom_open, WFTYPE * geom_close, int oversampling, int deep_shadows ) { int x; int ret = 1; int low_mem=0; if( Global_debug ) fprintf( Global_debug, "SHAVErender_shadows()\n" ); if( geom_open->totalverts != geom_close->totalverts ) { printf( "ERROR: geom_open!=geom_close! Shutting down shadow render\n" ); SHAVEclear_stack( ); } destroy_buffers(); if( undo ) free( undo ); undo = NULL; if( Sundo ) free( Sundo ); Sundo = NULL; //MAYArender_camDUMMY(1,0,0,120,120,3); if( totalhairfiles > 0 ) { int doit = 0; WFTYPE ggg; cursamp = 0; Gmaps_active = 1; oversampling = 1; deep_shadows = 1; SHADOWS_DONE = 0; init_geomWF( &ggg ); if( GLOBALocclude ) { ggg.totalverts = GLOBALocclude->totalverts; ggg.totalfverts = GLOBALocclude->totalfverts; ggg.totalfaces = GLOBALocclude->totalfaces; copy_geomWF( &ggg, GLOBALocclude ); for( x = 0; x < ggg.totalverts; x++ ) { ggg.v[x].x += ggg.velocity[x].x; ggg.v[x].y += ggg.velocity[x].y; ggg.v[x].z += ggg.velocity[x].z; } } for( x = 0; x < totallights; x++ ) { if( LWlight[x].trace ) { doit = 1; } } // if( Gtrace == 0 ) if( doit ) { printf( "trace init\n" ); SHAVEtrace_init( ); Gtrace = 1; } if( !GLOBALocclude ) ret = MAYArender_shadows( geom_open, geom_close, 1, 1 ); if( GLOBALocclude ) ret = MAYArender_shadows( GLOBALocclude, &ggg, 1, 1 ); SHADOWS_DONE = 1; Gmaps_active = 0; free_geomWF( &ggg ); } if( low_mem > 0 ) { SHAVEclear_stack( ); SHAVEcleanup( ); } low_mem = 0; if( GLOBAL_VERBOSE ) printf( "shadow render finished\n" ); for( x = 0; x < totallights; x++ ) { int xx = 0; float last = 0; int done = 0; int blank = 1; if( LWlight[x].zbuff ) last = LWlight[x].zbuff[0]; if( LWlight[x].zbuff ) while( done == 0 ) { if( LWlight[x].zbuff[xx] != last ) { blank = 0; done = 1; } xx++; if( xx >= ( LWlight[x].xres - 2 ) * ( LWlight[x].yres - 2 ) ) done = 1; } LWlight[x].blank = blank; if( blank ) { if( LWlight[x].zbuff ) free( LWlight[x].zbuff ); if( LWlight[x].Gzbuff ) free( LWlight[x].Gzbuff ); LWlight[x].zbuff = NULL; LWlight[x].Gzbuff = NULL; } } return ( ret ); } void SHAVEgen_roots( void ) { int pass; int mb = 1; int xx, x; float tt = 0; for( pass = 0; pass < MAXPASSES; pass++ ) { int yy; LWcam.sx = campass[mb].x; LWcam.sy = campass[mb].y; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; // this is temporary ///// current_cam = &LWcam; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; current_cam = &LWcam; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; for( xx = 0; xx < totalhairfiles; xx++ ) { itsalight = 3; fetch_hair( xx, tt ); { TILEMODE = 2; // tag hair draw_lotsROOTS( pass ); } } } } void SHAVEclear_textures( SHAVENODE * sn ) { int x, y; MAYAflush_state( &sn->restMEM, &sn->statMEM ); SHAVEID = sn->restMEM.ID; MAYAset_parms( &sn->shavep ); // fprintf(stdout,"clear textures ID = %d clumps = %d shaveclear_textures\n",SHAVEID,Gclumps);fflush(stdout); SHAVEID = (unsigned long )sn->restMEM.ID; free_maps( ); for( x = 0; x < 5; x++ ) { densemap[x].name[0] = 0; colmap[x].name[0] = 0; lenmap[x].name[0] = 0; } for( x = 0; x < total_splines; x++ ) for( y = 0; y < 60; y++ ) { Sresthair[x].slider[y] = 1.0f; Shair[x].slider[y] = 1.0f; Sthishair[x].slider[y] = 1.0f; Slasthair[x].slider[y] = 1.0f; } for( x = 0; x < totalverts; x++ ) for( y = 0; y < 60; y++ ) { //resthair[x].slider[y]=1.0f; hair[x].slider[y] = 1.0f; //thishair[x].slider[y]=1.0f; //lasthair[x].slider[y]=1.0f; } SHAVEfetch_node( sn ); } static int VXtrace( float nearClip, float farClip, VERT rbase, VERT rdir, int shademe, VOXSAMP * vsamp ); void reset_noisespace( void ) { int x, y; set_cachemode( NONE ); global_lastID = -1; for( x = 0; x < totalverts; x++ ) { for( y = 0; y < 15; y++ ) hair[x].noisev[y] = hair[x].hv[y]; if( Gbeen_scaled == 1 ) { float d=0; for( y = 0; y < 5; y++ ) d+=Distance(hair[x].hv[y],hair[x].hv[y+1]); d=d/5.0f; hair[x].restlength = d; hair[x].sparerestlength = d; // resthair[x].restlength=Distance(resthair[x].hv[2],resthair[x].hv[1]); // thishair[x].restlength=Distance(thishair[x].hv[2],thishair[x].hv[1]); // lasthair[x].restlength=Distance(lasthair[x].hv[2],lasthair[x].hv[1]); Gbeen_scaled = 0; } } for( x = 0; x < total_splines; x++ ) { for( y = 0; y < 15; y++ ) { Shair[x].noisev[y] = Shair[x].hv[y]; Sresthair[x].noisev[y] = Shair[x].hv[y]; Sthishair[x].noisev[y] = Shair[x].hv[y]; Slasthair[x].noisev[y] = Shair[x].hv[y]; Shair[x].hv[y] = Shair[x].hv[y]; Sresthair[x].hv[y] = Shair[x].hv[y]; Sthishair[x].hv[y] = Shair[x].hv[y]; Slasthair[x].hv[y] = Shair[x].hv[y]; } if( Gbeen_scaled == 1 ) { //== Shair[x].restlength = Distance( Shair[x].hv[0], Shair[x].hv[1] ); //== Shair[x].sparerestlength=Shair[x].restlength; //== Sresthair[x].restlength = //== Distance( Sresthair[x].hv[0], Sresthair[x].hv[1] ); //== Sthishair[x].restlength = //== Distance( Sthishair[x].hv[0], Sthishair[x].hv[1] ); //== Slasthair[x].restlength = //== Distance( Slasthair[x].hv[0], Slasthair[x].hv[1] ); Gbeen_scaled = 0; } } mkbounds( ); make_normals( ); mkHandles( ); Smake_restlengths( ); } void SOFTreset_noisespace( void ) { reset_noisespace( ); } static void resize_base_hair( BASEHAIR * h, WFTYPE * ft, CURVEINFO * cinfo, int segs ); static VERT2 world2camRS( LIGHTINFO * cam, VERT2 in,GLOBS *gs ); VERT SHAVEworld2cam( VERT in ) { VERT2 in2; in2.x = in.x; in2.y = in.y; in2.z = in.z; in2.clip = 0; in2 = world2cam( &LWcam, in2 ); in.x = in2.x; in.y = in2.y; in.z = in2.z; return ( in ); } void SHAVErecomb_select( void ) { recomb_select( ); } void SHAVErender_swatch( unsigned char *image, float *zbuff, int res, SHAVEPARMS * shavep ) { int x, y; float fov; VERT wpos, nn, vv; WFTYPE occlude; Matrix vm; DOING_SWATCH = 1; init_geomWF( &occlude ); Gdone=0; // loading up the nodes from static data SHAVEinit_node( &Gswatch, 1 ); if( shavep->haircount[0] < shavep->haircount[4] ) // it's a spline growth so use the spline swatch { Gswatch.restMEM.size = snode_rest_size; Gswatch.statMEM.size = snode_stat_size; Gswatch.restMEM.data = ( char * ) malloc( Gswatch.restMEM.size * sizeof( char ) ); Gswatch.statMEM.data = ( char * ) malloc( Gswatch.statMEM.size * sizeof( char ) ); //SHAVEalloc_node(&Gswatch); for( x = 0; x < snode_rest_size; x++ ) Gswatch.restMEM.data[x] = snode_rest_data[x]; for( x = 0; x < snode_stat_size; x++ ) Gswatch.statMEM.data[x] = snode_stat_data[x]; // ok now lets create a camera and a light //SHAVEset_parms(SHAVEPARMS *shavep); memcpy( &Gswatch.shavep, shavep, sizeof( SHAVEPARMS ) ); if( shavep->haircount[0] > shavep->haircount[4] ) // it's not a spline groth, so copy { int x; Gswatch.shavep.passes[4] = Gswatch.shavep.passes[0]; for( x = 0; x < 60; x++ ) Gswatch.shavep.slider_val[x][4] = Gswatch.shavep.slider_val[x][0]; } Gswatch.shavep.haircount[0] = 0; Gswatch.shavep.segs[0] = 8; Gswatch.shavep.passes[0] = 0; if( shavep->haircount[0] < shavep->haircount[4] ) // it's a spline groth, so copy { Gswatch.shavep.haircount[4] = 520; Gswatch.shavep.segs[4] = 30; } if( shavep->haircount[0] < shavep->haircount[4] ) // it's not a spline groth, so copy { int n; n = 420; //if (Gswatch.shavep.passes[4]>1) //n/=Gswatch.shavep.passes[4]; if( Gswatch.shavep.slider_val[25][4] > 1 ) n /= ( int ) Gswatch.shavep.slider_val[25][4]; Gswatch.shavep.haircount[4] = n; } if( Gswatch.shavep.passes[4] < 1 ) Gswatch.shavep.passes[4] = 1; SHAVEclear_stack( ); global_lastID = -1; SHAVEflush_state( &Gswatch ); SHAVEfree_node( &Gswatch ); global_lastID = -1; SHAVEfetch_node( &Gswatch ); SHAVEclear_stack( ); SHAVEadd_hairOPEN( &Gswatch ); SHAVEadd_hairCLOSE( &Gswatch ); fov = 40.0f; wpos.x = -4.0f; wpos.y = 6.0f; wpos.z = 4.0f; nn = wpos; nn.x = -nn.x; // this is the lookat vector nn.y = -nn.y; // we're just lookin at 0,0,0 nn.z = -nn.z; // nn.y+=0.3f; // move the lookat up a bit nn = Vnorm( nn ); vv.x = 0.0f; // up vector (for roll) vv.y = 0.0f; vv.z = 1.0f; } if( shavep->haircount[0] >= shavep->haircount[4] ) // it's not a spline growth so use the mesh swatch { printf( " ------------------> mesh node <-------------------------------\n" ); Gswatch.restMEM.size = msnode_rest_size; Gswatch.statMEM.size = msnode_stat_size; Gswatch.restMEM.data = ( char * ) malloc( Gswatch.restMEM.size * sizeof( char ) ); Gswatch.statMEM.data = ( char * ) malloc( Gswatch.statMEM.size * sizeof( char ) ); //SHAVEalloc_node(&Gswatch); for( x = 0; x < msnode_rest_size; x++ ) Gswatch.restMEM.data[x] = msnode_rest_data[x]; for( x = 0; x < msnode_stat_size; x++ ) Gswatch.statMEM.data[x] = msnode_stat_data[x]; // ok now lets create a camera and a light memcpy( &Gswatch.shavep, shavep, sizeof( SHAVEPARMS ) ); SHAVEflush_state( &Gswatch ); SHAVEfetch_node( &Gswatch ); init_clumping(); { int n; n = 6420; //if (Gswatch.shavep.passes[0]>1) //n/=Gswatch.shavep.passes[0]; if( Gswatch.shavep.slider_val[25][0] > 1 ) n /= ( int ) Gswatch.shavep.slider_val[25][0]; Gswatch.shavep.haircount[0] = n; } Gswatch.shavep.segs[0] = 7; //Gswatch.shavep.passes[0]=1; if( Gswatch.shavep.passes[0] < 1 ) Gswatch.shavep.passes[0] = 1; { int count, passes, mult; mult = Gswatch.shavep.slider_val[25][0]; passes = Gswatch.shavep.passes[0]; if( mult < 1 ) mult = 1; if( passes < 1 ) passes = 1; count = ( int ) ( ( float ) 12300 / ( float ) passes / ( float ) mult ); Gswatch.shavep.haircount[0] = count; } SHAVEclear_stack( ); SHAVEadd_hairOPEN( &Gswatch ); SHAVEadd_hairCLOSE( &Gswatch ); fov = 40.0f; wpos.x = 0.0f; wpos.y = 18.0f; wpos.z = -18.0f; nn = wpos; nn.x = -nn.x; // this is the lookat vector nn.y = -nn.y; // we're just lookin at 0,0,0 nn.z = -nn.z; // nn.y+=0.3f; // move the lookat up a bit nn = Vnorm( nn ); vv.x = 0.0f; // up vector (for roll) vv.y = 0.0f; vv.z = 1.0f; } SHAVEclear_stack( ); SHAVEfree_node( &Gswatch ); DOING_SWATCH = 0; } void free_renderstate(RENDERSTATE *gl); //#endif typedef struct { int nodeID; int totalhairs; int pass; int tileIndex; int *list; } DrawHairArgs; static void drawHairThread( unsigned threadID, void *data ) { DrawHairArgs *args = ( DrawHairArgs * ) data; int i; int ii; for( i = 0; i <= args->totalhairs; i++ ) { ii=args->list[i]; if( alltiles.tile[args->tileIndex].nodehairhits[ii] == ( unsigned long ) args->nodeID ) { MTdraw_oneHAIR( alltiles.tile[args->tileIndex].slghairhits[ii], alltiles.tile[args->tileIndex].hairhits[ii], args->pass, args->tileIndex, >hreads[threadID] ); } } } static int MTdraw_oneHAIRRS( int slg, int xid, int cs, int curtile, GLOBS * gs ); static void draw_tile(unsigned current_thread, void *qqq) { WFTYPE geom; int add2, add1; int x; int pass=0;// we don't do this anymore int ret = 0; int progress = 0; int finish = 0; int tcount = 0; int low_mem=0; int th; int total; int done=0; int aa,bb,samp; float *zbuff; int xx; unsigned char *ibuff; GLOBS *gs; xx=(int)(qqq); ibuff=global_ibuff; zbuff=global_zbuff; th=1; th=SHAVEnum_processors(); //th=1; if (th<2) th=1; //th=1; if( xx < alltiles.totaltiles ) { int total_triangles = 0; if (th>=2) SHAVEmutex_lock(&Gtile_render_mutex); gs= >hreads[current_thread]; // alocate tile imagebuff here gs->tilebuff.xres = LWcam.xres; gs->tilebuff.yres = LWcam.yres; gs->tilebuff.wpos = LWcam.wpos; gs->tilebuff.aspect = LWcam.aspect; gs->tilebuff.zoom = LWcam.zoom; total = alltiles.tile[xx].triangles; alltiles.tile[xx].triangle_limit = 000; alltiles.tile[xx].triangle_cache = NULL; memcpy( gs->tilebuff.view, &LWcam.view, sizeof( Matrix ) ); memcpy( gs->tilebuff.iview, &LWcam.iview, sizeof( Matrix ) ); mktilebuff( &gs->tilebuff, alltiles.sx, alltiles.sy ); gs->rs.current_cam = &gs->tilebuff; gs->rs.itsalight = 0; gs->rs.TILEMODE = 6; current_cam = &gs->tilebuff; itsalight=0; TILEMODE=0; if (th>=2) SHAVEmutex_unlock(&Gtile_render_mutex); add2 = alltiles.tile[xx].x1 + alltiles.tile[xx].y1 * LWcam.xres; gs->rs.Gclipx0 = alltiles.tile[xx].x1; gs->rs.Gclipy0 = alltiles.tile[xx].y1; gs->rs.Gclipx1 = alltiles.tile[xx].x2; gs->rs.Gclipy1 = alltiles.tile[xx].y2; gs->rs.TILEMODE = 6; init_geomWF( &geom ); for( x = 0; x < ( int ) alltiles.tile[xx].totalpolyhits; x++ ) { int pid; int y; pid = alltiles.tile[xx].polyhits[x]; for( y = alltiles.occlude->face_start[pid]; y < alltiles.occlude->face_end[pid]; y++ ) { geom.totalverts++; geom.totalfverts++; } geom.totalfaces++; } alloc_geomWF( &geom ); geom.totalverts = 0; geom.totalfaces = 0; geom.totalfverts = 0; for( x = 0; x < ( int ) alltiles.tile[xx].totalpolyhits; x++ ) { int pid; int y; pid = alltiles.tile[xx].polyhits[x]; geom.face_start[geom.totalfaces] = geom.totalfverts; for( y = alltiles.occlude->face_start[pid]; y < alltiles.occlude->face_end[pid]; y++ ) { int g; g = alltiles.occlude->facelist[y]; geom.v[geom.totalverts] = alltiles.occlude->v[g]; geom.color[geom.totalverts] = alltiles.occlude->color[g]; geom.uv[geom.totalverts] = alltiles.occlude->uv[g]; geom.velocity[geom.totalverts] = alltiles.occlude->velocity[g]; geom.facelist[geom.totalfverts] = geom.totalverts; geom.totalverts++; geom.totalfverts++; } geom.face_end[geom.totalfaces] = geom.totalfverts; geom.totalfaces++; } // we used to draw the occlusions here gs->rs.itsalight = 0; for( x = 0; x < ( int ) alltiles.tile[xx].totalnodes; x++ ) tcount += alltiles.tile[xx].totalhits; total_triangles = alltiles.tile[xx].triangles; alltiles.tile[xx].triangles = 0; // printf ("cache triangles\n"); Gmax_geom_screen= 1000000.0f; // we're going to use this global to test against as a // rejection for max zdepth the tile is totall occluded at //printf ("clearing tile %d\n",xx);fflush(stdout); { int tm,xxx,aaa; aaa=gs->tilebuff.zPage; // clear buffs again // for( xxx = 0; xxx < aaa*Gmotion_samp; xxx++ ) // gs->tilebuff.geombuff[xxx] = 1000000.0f; // if( gs->rs.current_cam->zbuff ) // for( xxx = 0; xxx < tilebuff.timePage*Gmotion_samp; xxx++ ) // gs->tilebuff.zbuff[xxx] = ( float ) 1000000.0f; } //#ifdef crap gs->rs.itsalight = 2; gs->rs.TILEMODE=6; if( geom.totalverts > 0 ) { draw_geomWFRS( &geom, 0,gs ); } gs->rs.current_cam = &gs->tilebuff; gs->rs.itsalight = 0; gs->rs.TILEMODE = 6; for( x = 0; x < ( int ) alltiles.tile[xx].totalnodes; x++ ) { int hitsPerThread; int numHits; int y; if (th>=2) SHAVEmutex_lock(&Gtile_render_mutex); { fetch_hair( alltiles.tile[xx].nodeids[x], 0.0 ); //GnodeID=alltiles.tile[xx].nodeids[x]; push_renderstate(>hreads[current_thread],1); // init_engine(); // totalskulls = 0; // totalsplits = 1; // DEGENERATE_OBJECT = 0; // if( total_splines > 0 ) // free_splines( ); // SNfree( ); // Dfreeverts( ); // freeverts( ); // free_maps( ); // set_defaults( ); // clear_uvsets( ); } if (th>=2) SHAVEmutex_unlock(&Gtile_render_mutex); gs->rs.current_cam = &gs->tilebuff; gs->rs.itsalight = 0; gs->rs.TILEMODE = 6; numHits = ( int ) alltiles.tile[xx].totalhits; for( y = 0; y < numHits; y++ ) { if( finish == 0 ) { int g; int slg; unsigned int hnode; g = alltiles.tile[xx].hairhits[y]; slg = alltiles.tile[xx].slghairhits[y]; hnode = alltiles.tile[xx].nodehairhits[y]; gs->Gslg=slg; gs->GhairID=g; // gs->rs.nodeID=hnode; // progress += hitsPerThread; progress++; if( 0 == 1 ) if( progress > tcount / 5 ) { progress = 0; global_progress++; finish = SHAVEprogress( global_progress, estimated_total ); if( finish == 1 ) { ret = finish; low_mem = 1; if( GLOBAL_VERBOSE ) printf( "INTERRUPT!\n" ); break; } } if( freeze.totalverts == 0 ) { //printf ("passID = %d\n",alltiles.tile[xx].passhairhits[y]);fflush(stdout); if( hnode == alltiles.tile[xx].nodeids[x] ) MTdraw_oneHAIRRS( alltiles.tile[xx].slghairhits[y], alltiles.tile[xx].hairhits[y],alltiles.tile[xx].passhairhits[y], xx, >hreads[current_thread] ); } { if( freeze.totalverts != 0 ) if( hnode == alltiles.tile[xx].nodeids[x] ) { WFdraw_oneINST( g, slg, pass ); } } } } // if (freeze.totalverts == 0) if (th>=2) SHAVEmutex_lock(&Gtile_render_mutex); { // totalskulls = 0; // totalsplits = 1; // DEGENERATE_OBJECT = 0; // if( total_splines > 0 ) // free_splines( ); // SNfree( ); // Dfreeverts( ); // freeverts( ); // free_maps( ); // set_defaults( ); // clear_uvsets( ); // pop_renderstate(>hreads[current_thread].rs); // totalskulls = 0; // totalsplits = 1; // DEGENERATE_OBJECT = 0; // if( total_splines > 0 ) // free_splines( ); // SNfree( ); // Dfreeverts( ); // freeverts( ); //free_renderstate(>hreads[current_thread].rs); } if (th>=2) SHAVEmutex_unlock(&Gtile_render_mutex); } if( alltiles.tile[xx].triangles > 0 ) if( alltiles.tile[xx].triangles > alltiles.tile[xx].triangle_limit - 1 ) { // printf( "triangle cache overflow in tile[%d]. estimate:%d real %d\n", xx, alltiles.tile[xx].triangle_limit, alltiles.tile[xx].triangles ); alltiles.tile[xx].triangles = alltiles.tile[xx].triangle_limit - 1; } // if( ( alltiles.tile[xx].totalhits == 0 ) // || ( alltiles.tile[xx].totalnodes == 0 ) ) // global_progress += 5; } if( geom.totalverts > 0 ) free_geomWF( &geom ); //if (0==1) { { int xx1; for (xx1=0;xx1tilebuff.zPage;xx1++) { int add1,addi1; add1=xx1; addi1=xx1*4; if (add1tilebuff.zbound) //if (gs->tilebuff.zbuff[add1] < 1000000.0f) <-- this doesn't work if there's motion blur composite_pixel(&gs->tilebuff,add1,addi1); } } if (done==0) if( low_mem == 0 ) for( aa = alltiles.tile[xx].x1; aa < alltiles.tile[xx].x2; aa += 1 ) for( bb = alltiles.tile[xx].y1; bb < alltiles.tile[xx].y2; bb += 1 ) if( aa < LWcam.xres ) if( bb < LWcam.yres ) { int add1; int add2; int ox, oy; int add4; int add14; float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f; float g2; add1 = aa + bb * LWcam.xres; add14 = add1 * 4; g2 = 0.0f; samp = 0; // this was samp = 1 // this is causing clipping if (add1tilebuff.zbound) { int sqq,sqq1,sqq2; sqq=samp * alltiles.sx * GLOBALSAMP * alltiles.sy * GLOBALSAMP; sqq1= alltiles.sx * GLOBALSAMP * GLOBALSAMP; sqq2= alltiles.sx * GLOBALSAMP; for( ox = 0; ox < GLOBALSAMP; ox++ ) for( oy = 0; oy < GLOBALSAMP; oy++ ) { add2 = ( ( aa - alltiles.tile[xx].x1 ) ) * GLOBALSAMP + ox + ( ( bb - alltiles.tile[xx].y1 ) )*sqq1 + oy * sqq2; add2 += sqq; add4 = add2 * 4; if( ( unsigned int ) ( add4 + 4 ) < ( unsigned int ) gs->tilebuff.ibound ) { unsigned char *sss; g2 += 1.0f; sss= &gs->tilebuff.ibuff[add4]; r += ( float ) *(sss); g += ( float ) *(sss+1); b += ( float ) *(sss+2); a += ( float ) *(sss+3); } if( ( unsigned int ) gs->tilebuff.zbound > ( unsigned int ) add2 ) if( gs->tilebuff.zbuff[add2] < 999998.0f ) { VERT2 con; VERT wpt; float avgz; con.x = ( float ) aa; con.y = ( float ) bb; con.z = ( float ) gs->tilebuff.zbuff[add2]; con = cam2world( &LWcam, con ); wpt.x = con.x; wpt.y = con.y; wpt.z = con.z; avgz = Distance( wpt, gs->tilebuff.wpos ); if( avgz < zbuff[add1] ) zbuff[add1] = avgz; } } } { if( g2 != 0 ) { //#ifdef crap0 r = dither2RS( r / g2,gs ); g = dither2RS( g / g2,gs ); b = dither2RS( b / g2,gs ); a = dither2RS( a / g2,gs ); //#endif } } if( Gmotion_samp > 0 ) { unsigned int rr, gg, bb, aa; unsigned char *ib; ib= &ibuff[add14]; rr = ( unsigned int ) *(ib); gg = ( unsigned int ) *(ib+1); bb = ( unsigned int ) *(ib+2); aa = ( unsigned int ) *(ib+3); rr += ( unsigned int ) dither2RS( ( ( float ) r ),gs ); gg += ( unsigned int ) dither2RS( ( ( float ) g ),gs ); bb += ( unsigned int ) dither2RS( ( ( float ) b ),gs ); aa += ( unsigned int ) dither2RS( ( ( float ) a ),gs ); if( rr > 255 ) rr = 255; if( gg > 255 ) gg = 255; if( bb > 255 ) bb = 255; if( aa > 255 ) aa = 255; *(ib) = ( unsigned char ) rr; *(ib+1) = ( unsigned char ) gg; *(ib+2) = ( unsigned char ) bb; *(ib+3) = ( unsigned char ) aa; } } freetilebuff( &gs->tilebuff ); //if (th>=2) } // 0==1 //SHAVEmutex_lock(&Gtile_render_mutex); //if (th>=2) //SHAVEmutex_unlock(&Gtile_render_mutex); } static void draw_lotsHAIRNEW( int cs ); static void draw_lotsHAIR_multipass( void ); static void tile_render( WFTYPE * occlude, unsigned char *ibuff, float *zbuff, int dice ) { int MP; int stopit = 0; int pass; int mb = 1; int est=0; int xx, x; float tt = 0; TILETYPE *ti; int finish = 0; int done = 0; void* threadGroup=NULL; FILE *fp; int cur=0; int low_mem=0; int th=0; global_zbuff=zbuff; global_ibuff=ibuff; // th=getThreadSettings(dice*dice, NULL); th=SHAVEnum_processors(); //th=1; if (th<2) th=1; //th=1; // COUNT UP ALL THE HAIR for( xx = 0; xx < totalhairfiles; xx++ ) //if (stopit!=1) { int qq; fetch_hair( xx, 0 ); if (LOCAL_CNT[0]) { int mult; mult=(int)sliders[25][0].value; if (mult<1) mult=1; est+=LOCAL_CNT[0]*mult*LOCAL_PASSES[0]; } if (LOCAL_CNT[4]) { int mult; mult=(int)sliders[25][4].value; if (mult<1) mult=1; est+=LOCAL_CNT[4]*mult*LOCAL_PASSES[4]; } } for (x=0;x=2) // threadGroup= SHAVEstart_thread_group(th); alltiles.occlude = occlude; alltiles.dice = dice; MP = MAXPASSES; // for( pass = 0; pass < MP; pass++ ) if( low_mem == 0 ) { int yy; pass=0; if( done == 0 ) { LWcam.sx = campass[mb].x; LWcam.sy = campass[mb].y; // if( GLOBAL_VERBOSE ) // printf( "pass=%d\n", pass ); init_tiles( ); // if( GLOBAL_VERBOSE ) // printf( "alloc_tiles?\n" ); alloc_tiles( ); Gpass = pass; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; // this is temporary ///// current_cam = &LWcam; itsalight = 3; TILEMODE = 3; // count occlusions // if( GLOBAL_VERBOSE ) // printf( "allocating occlusions\n" ); draw_geomWF( occlude, 0 ); ///////////////////////// // if( GLOBAL_VERBOSE ) // printf( "tagging occlusions\n" ); for( x = 0; x < alltiles.totaltiles; x++ ) { ti = &alltiles.tile[x]; ti->polyhits = NULL; // if (ti->totalpolyhits>0) ti->polyhits = ( unsigned int * ) malloc( ( ti->totalpolyhits + 5 ) * sizeof( unsigned int ) ); ti->totalpolyhits = 0; ti->triangles = 0; } if( low_mem == 0 ) { current_cam = &LWcam; itsalight = 3; TILEMODE = 4; // tag occlusions draw_geomWF( occlude, 0 ); Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; current_cam = &LWcam; Gclipx0 = 0; Gclipy0 = 0; Gclipx1 = LWcam.xres; Gclipy1 = LWcam.yres; // printf ("mmtest :forming the cache\n"); if( low_mem == 0 ) for( xx = 0; xx < totalhairfiles; xx++ ) if( low_mem == 0 ) //if (stopit!=1) { int qq; itsalight = 3; fetch_hair( xx, tt ); GnodeID=xx; // push_renderstate(>hreads[0],1); if( freeze.totalverts == 0 ) { TILEMODE = 2; // tag hair draw_lotsHAIR_multipass( ); } else if( ( stack_is_from_archive == 0 ) ) { TILEMODE = 2; // tag inst hair WFdraw_lotsINST( pass ); } // free_renderstate(>hreads[0].rs); } #ifdef progress_update SHAVEprogress( -1, alltiles.totaltiles ); SHAVEprogress( 0, alltiles.totaltiles ); #endif estimated_total=alltiles.totaltiles; global_progress = 0; // for( xx = 0; xx < alltiles.totaltiles; xx+=th ) cur=0; while (cur=2) threadGroup= SHAVEstart_thread_group(th); //for (qqq=0;qqq=2) if (alltiles.tile[gg].totalhits>0) if( Gdone == 0 ) { SHAVEstart_thread(threadGroup,draw_tile,(void*)gg ); gthreads[qqq].tilequeue=gg; qqq++; } if (Gdone==0) if (th<2) if (alltiles.tile[gg].totalhits>0) if( done == 0 ) { draw_tile(0,(void*)gg); gthreads[qqq].tilequeue=gg; qqq++; } cur++; } if (th>=2) SHAVEend_thread_group(threadGroup); // we want to close out threads first for (qqq=0;qqq=0) { VERT aa,bb; aa.x=alltiles.tile[gthreads[qqq].tilequeue].x1; aa.y=alltiles.tile[gthreads[qqq].tilequeue].y1; aa.z=0; bb.x=alltiles.tile[gthreads[qqq].tilequeue].x2; bb.y=alltiles.tile[gthreads[qqq].tilequeue].y2; bb.z=0; SHAVEdraw_tile_callback(&aa,&bb); } } } // if (th>=2) //for (xx=0;xx=2) SHAVEmutex_lock(&Gtile_render_mutex); SHAVEclear_stack();// why does this crash? //SHAVEcleanup(); // purge the whole engine if (th>=2) SHAVEmutex_unlock(&Gtile_render_mutex); } static int draw_poly2new( POLYDAT pp, int layer, unsigned char lum ); static int draw_poly2newZ( POLYDAT pp, int layer, unsigned char lum ); static int draw_poly2newRS( POLYDAT pp, int layer, unsigned char lum,GLOBS *gs ); static int draw_poly2newZRS( POLYDAT pp, int layer, unsigned char lum,GLOBS *gs ); static void shade_a_curve_rt( CURVEINFO * hp, WFTYPE * wf ); static void shade_a_curve( CURVEINFO * hp, WFTYPE * wf ); static void precalc_shadow_curve( WFTYPE * h, WFTYPE * bh, CURVEINFO * hp ); static int draw_a_curve( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ); static int draw_a_bunch( WFTYPE * wf, CURVEINFO * h, int cs, int curtile ); static int draw_a_curveRS( WFTYPE * wf, CURVEINFO * h, int cs, int curtile,GLOBS *gs ); VERT SHAVEapply_GI( VERT vv, CURVEINFO * ci ); #ifdef EXTPRIM // Callback functions (shave calls you) void SHAVE22apply_inst_color( WFTYPE * instance_geom, int hairID, int slgID, unsigned long shaveINSTID ) { } VERT SHAVE22displace_root( VERT * root, CURVEINFO * ci, int ID ) { VERT ret; ret.x = 0; ret.y = 0; ret.z = 0; // this is usedfull for subdiv surfaces. You return a vector to displace the whole // hair by (should be the difference between the position on the subdiv and root return ( ret ); } int SHAVE22progress( int actual, int estimated_total ) { int killit = 0; return ( killit ); } void SHAVE22coord_convertTOSHAVE( VERT * in ) { } void SHAVE22coord_convertFROMSHAVE( VERT * in ) { } // float SHAVE22apply_texture( CURVEINFO * ci, VERT rest_root_worldpos, unsigned long shaveINSTID, int parm, float inbound_value ) { return ( inbound_value ); } // this needs to be here as well, but you won't be using it // the 'MAYA' in the name is due to back compatibility with a MAYAShave version void MAYA22external_forces( VERT * lastpos, VERT * velocity, int y ) { } void MAYA22cache_forces(int clearCache) {} void MAYA22apply_cached_forces(int guideNum, int vertNum, VERT* vect) {} // this is an illumination callback (see docs) VERT SHAVE22apply_illumination( int LIGHTID, VERT wpos, VERT vector, VERT color ) { return ( color ); } float SHAVE22apply_falloff( int lightNUM, VERT pos, float cone ) { return ( cone ); } VERT SHAVE22apply_GI( VERT tmp, CURVEINFO * ci ) { VERT t; t.x = 0.0f; t.y = 0.0f; t.z = 0.0f; return ( t ); } void SHAVE22apply_illuminationWF( int LIGHTID, WFTYPE * samples ) { } //shaveSDKEXT.lib(shavelib1forAW.obj) : error LNK2001: unresolved external symbol _MAYAexternal_forces //shaveSDKEXT.lib(shavelib1forAW.obj) : error LNK2001: unresolved external symbol _SHAVEdisplace_root //Release/draTest.exe : fatal error LNK1120: 2 unresolved externals // this is a callback for applying atmospherics/depth cueing VERT SHAVE22apply_atmosphere( VERT wpos, VERT inbound_color ) { return ( inbound_color ); } float SHAVE22apply_VMAP( long SHAVEINSTID, int VERTID, int chan, float inbound_value ) { return ( inbound_value ); } void SHAVEdraw_tile_callback22(VERT *a, VERT *b) { } #endif extern void SHAVEclear_uvsets( SHAVENODE * sn ) { int x; SHAVEflush_state( sn ); clear_uvsets( ); free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); } void clear_uvsets( void ) { int x; for( x = 0; x < 60; x++ ) { free_geomWF( &Guv_sets[x] ); init_geomWF( &Guv_sets[x] ); } Guv_totalsets = 0; for( x = 0; x < 60; x++ ) Guv_link[x] = -1; global_lastID = -1; } void init_uvsets( void ) { int x; for( x = 0; x < 60; x++ ) { init_geomWF( &Guv_sets[x] ); } Guv_totalsets = 0; for( x = 0; x < 60; x++ ) Guv_link[x] = -1; global_lastID = -1; } void geom_triangulateWF( WFTYPE * wf ); int SHAVEadd_uvset( SHAVENODE * sn, WFTYPE * uvset ) { int x; int ret = -1; global_lastID = -1; SHAVEflush_state( sn ); global_lastID = -1; Guv_sets[Guv_totalsets].totalverts = uvset->totalverts; Guv_sets[Guv_totalsets].totalfaces = uvset->totalfaces; Guv_sets[Guv_totalsets].totalfverts = uvset->totalfverts; // if( uvset->totalfverts != DUTtotalfverts ) // { // fprintf( stderr, "failed to add the uv set since the facevert count does not match\n" ); // } // else { alloc_geomWF( &Guv_sets[Guv_totalsets] ); ret = Guv_totalsets; for( x = 0; x < uvset->totalverts; x++ ) Guv_sets[ret].v[x] = uvset->v[x]; for( x = 0; x < uvset->totalfverts; x++ ) Guv_sets[ret].facelist[x] = uvset->facelist[x]; for( x = 0; x < uvset->totalfaces; x++ ) Guv_sets[ret].face_start[x] = uvset->face_start[x]; for( x = 0; x < uvset->totalfaces; x++ ) Guv_sets[ret].face_end[x] = uvset->face_end[x]; geom_triangulateWF( &Guv_sets[ret] ); Guv_totalsets++; free_MEMFILE( &sn->restMEM ); free_MEMFILE( &sn->statMEM ); MAYAfetch_node( &sn->restMEM, &sn->statMEM, &sn->shavep ); } return ( ret ); } void geom_triangulateWF( WFTYPE * wf ) { int fvcount = 0; int fcount = 0; int x, ff, fv; WFTYPE tmp; init_geomWF( &tmp ); for( ff = 0; ff < wf->totalfaces; ff++ ) for( fv = wf->face_start[ff] + 2; fv < wf->face_end[ff]; fv++ ) { fvcount += 3; fcount++; } ////printf ("3 fvcount = %d fcount = %d\n",fvcount,fcount); tmp.totalfaces = fcount; tmp.totalverts = wf->totalverts; tmp.totalfverts = fvcount; alloc_geomWF( &tmp ); //tmp.totalverts=0; tmp.totalfverts = 0; tmp.totalfaces = 0; for( x = 0; x < wf->totalverts; x++ ) tmp.v[x] = wf->v[x]; //for (x=0;xtotalverts;x++) tmp.color[x]=wf->color[x]; fvcount = 0; for( ff = 0; ff < wf->totalfaces; ff++ ) // if (wf->face_end[ff]-wf->face_start[ff] > 3) { for( fv = wf->face_start[ff] + 2; fv < wf->face_end[ff]; fv++ ) { tmp.face_start[tmp.totalfaces] = tmp.totalfverts; tmp.facelist[tmp.totalfverts] = wf->facelist[wf->face_start[ff]]; tmp.totalfverts++; tmp.facelist[tmp.totalfverts] = wf->facelist[fv - 1]; tmp.totalfverts++; tmp.facelist[tmp.totalfverts] = wf->facelist[fv]; tmp.totalfverts++; tmp.face_end[tmp.totalfaces] = tmp.totalfverts; tmp.totalfaces++; } } free_geomWF( wf ); wf->totalverts = tmp.totalverts; wf->totalfaces = tmp.totalfaces; wf->totalfverts = tmp.totalfverts; alloc_geomWF( wf ); for( x = 0; x < wf->totalfaces; x++ ) wf->face_start[x] = tmp.face_start[x]; for( x = 0; x < wf->totalfaces; x++ ) wf->face_end[x] = tmp.face_end[x]; for( x = 0; x < wf->totalfverts; x++ ) wf->facelist[x] = tmp.facelist[x]; for( x = 0; x < wf->totalverts; x++ ) wf->v[x] = tmp.v[x]; free_geomWF( &tmp ); } static int OLDtotalverts = 0; static int OLDtotalfverts = 0; static int OLDtotalfaces = 0; extern void SHAVErecomb_splines_from_guides( WFTYPE * wf, SHAVENODE * sn ) { } static void init_hair( void ); static void init_hair2( void ); //void guides2WF(WFTYPE *wf) void make_splines2( void ); void restructure_hair( void ); void re_param_splines( WFTYPE * wf ); void re_param_base( BASEHAIR * h ); static VERT cam2world1( LIGHTINFO * cam, VERT in ); void sm2poly( POLYDATSM * in, POLYDAT * out ) { int x; VERT2 tmp; for( x = 0; x < 4; x++ ) { int q; q = x; if( q == 3 ) q = 0; out->p[x] = in->p[q]; out->v[x] = in->v[q]; out->c[x].x = ( float ) ( ( float ) in->c[q].x ); out->c[x].y = ( float ) ( ( float ) in->c[q].y ); out->c[x].z = ( float ) ( ( float ) in->c[q].z ); out->alpha[x] = ( float ) in->alpha[q]; } out->w[3] = out->w[0]; out->wv[3] = out->wv[0]; out->p[3] = out->p[0]; out->v[3] = out->v[0]; out->c[3] = out->c[0]; out->alpha[3] = out->alpha[0]; } extern void fetch_geomWF(WFTYPE *wf) { int x; int y; init_geomWF(wf); wf->totalverts=Dtotalverts; wf->totalfaces=Dtotalfaces; wf->totalfverts=Dtotalfverts; alloc_geomWF(wf); Dmake_normals(); for (x=0;xv[x]=Dv[x]; wf->vn[x]=Dvn[x]; wf->v[x].z*= -1.0f; wf->vn[x].z*= -1.0f; wf->alpha[x]=1.0f; } for (x=0;xfacelist[x]=Dfacelist[x]; } for (x=0;xface_start[x]=Dface_start[x]; wf->face_end[x]=Dface_end[x]; if (skull_sphere>=0) { if (Dmtlgroup[x]==skull_sphere) for (y=Dface_start[x];yalpha[Dfacelist[y]]=0.0f; } } } //#include "targa.c" static float dot( VERT a, VERT b ); // obsolete_gui.c stuff #ifdef _WIN32 #include // this is needed only for the Sleep statement we are using in this example // otherwise, just include the following 3 #endif #ifndef _WIN32 #include #include #ifndef _MAC // Mac gets malloc from stdlib.h #include #endif #endif #ifdef NOLIB #ifdef OSMac_MachO_ #include #else #include #endif #endif #ifdef NOLIB #ifdef _WIN32 #include "glut.h" #endif #endif #include static void free_depth( void ); typedef struct { char lable[255]; char name[255]; // GLuint *img; int axis; short flags; int xres, yres; float sx, sy, sz; int x, y; int paintbutton; int sliderlink; } MAPTYPE; typedef struct { char lable[255]; char name[255]; // GLuint *img; int axis; short flags; int xres, yres; float sx, sy, sz; int x, y; int paintbutton; int sliderlink; } AXISTYPE; typedef struct { char lable[255]; // GLuint *img; short flags; int xres, yres; float sx, sy, sz; int x, y; VERT bgcolor; } PUSHBUTTONTYPE; AXISTYPE axis_tools[20][5]; PUSHBUTTONTYPE pushme[20][5]; MAPTYPE cmap[5]; MAPTYPE dmap[5]; MAPTYPE lnmap[5]; static int BUTTON_CHECK( int a, int b, int a1, int b1 ); static void aDRAW_STATUS( char name[655] ); static void circs( Scoord x, Scoord y, Scoord radius ); void draw_toolbars(void); void scan_toolbars(void); static void cmov2( float a, float b ); static void rectfs( Scoord ax, Scoord ay, Scoord bx, Scoord by ); static void rectf( float ax, float ay, float bx, float by ); //int G_MOUSEX,G_MOUSEY; #define MOUSEX 266 /* 10+VALOFFSET */ #define MOUSEY 267 /* 11+VALOFFSET */ static WINDOW G_Window[10]; static WINDOW G_Module; static WINDOW G_Work; /* work area used by view windows, frame bar, module window */ static WINDOW G_Framewind; static WINDOW Previewwind; static TOOLCHEST G_TB[2]; static VERT setVERT( float a, float b, float c ); static void DRAW_TOOLBOX( int n ); static void pFILL_BUTTON_OUT( VERT a, VERT b ); /* make button inside region */ static void pFILL_BUTTON_IN( VERT a, VERT b ); /* make button inside region */ static void pFILL_BUTTON_IN_HIGHLIGHT( VERT a, VERT b ); /* make button inside region */ /* scene info */ static int GGos; static int M_save_model_stat; static int M_save_model_seq_stat; static int M_save_poses_stat; static int M_save_phoneme_stat; static int M_save_performance_stat; static int M_save_audio_stat; static int M_load_audio_stat; static int M_edit_neutral_stat; static int M_replace_neutral_stat; static int M_deform_poses_stat; static int M_load_model_stat; static int M_load_target_stat; static int M_load_poses_stat; static int M_load_phoneme_stat; static int M_load_performance_stat; static int M_select_strands = 0; static int M_select_ends = 1; static int M_select_verts = 0; static int M_select_roots = 0; static int freeze_texg = 1; static int freeze_texl = 0; static void resample( BASEHAIR h, RENDERHAIR * ret ); static void reset_hair( void ); #define ESCKEY 7 /* BUT6 */ #define TABKEY 9 /* BUT8 */ #define SPACEKEY 83 /* BUT82 */ static int GTimerON = 1; #include "shave_kernal_setup.c" void init_renderstate(RENDERSTATE *gl) { int x; int xx; { gl->hair=NULL; gl->Shair=NULL; gl->Sresthair=NULL; gl->Shairvelocity=NULL; // gl->sliders=NULL; // don't free this gl->Dv=NULL; gl->v=NULL; gl->vn=NULL; gl->Dvn=NULL; gl->facelist=NULL; gl->face_start=NULL; gl->face_end=NULL; gl->Dfacelist=NULL; gl->Dface_start=NULL; gl->Dface_end=NULL; gl->totalfaces=0; gl->totalfverts=0; gl->totalverts=0; gl->Dtotalfaces=0; gl->Dtotalfverts=0; gl->Dtotalverts=0; gl->face_link=NULL; gl->D2UTface_link=NULL; gl->Dlink=NULL; for (xx=0;xx<5;xx++) { gl->total_slgfaces[xx]=0; gl->slgfaces[xx]=NULL; } gl->vlink=NULL; for (xx=0;xx< 60;xx++) { init_geomWF(&gl->Guv_sets[xx]); gl->Guv_link[xx]=0; } gl->Guv_totalsets=0; gl->DUTtotalfaces=0; gl->total_splines=0; gl->Gdontinterp=0; gl->Sresthair=NULL; gl->nodeID=0; gl->head=0; gl->beard=0; gl->eyebrow=0; gl->eyelash=0; gl->splines=0; gl->Gsquirrel=0; gl->Gclumps=0; //gl->Gkd=NULL; gl->Gflyaway_percent=0.0f; gl->Gindex=NULL; //*gl->Gkd=NULL; } } void copy_int (int *dest,int *src,int sz) { if (sz>0) { int x; dest=(int *) malloc (sz*sizeof(int)); for (x=0;x0) { int x; dest=(float *) malloc (sz*sizeof(float)); for (x=0;x0) { int x; dest=(double *) malloc (sz*sizeof(double)); for (x=0;x0) { int x; dest=(VERT *) malloc (sz*sizeof(VERT)); for (x=0;x0) { int x; dest=(BASEHAIR *) malloc (sz*sizeof(BASEHAIR)); for (x=0;xrs; if (push_hair) free_renderstate( gl); gl->total_splines=total_splines; gl->SHAVEID=SHAVEID; gl->nodeID=GnodeID; //fprintf (stdout,"pushing hair node ID %d local_cnt=%d\n",GnodeID,LOCAL_CNT[Gslg]);fflush(stdout); gl->genON=genON; gl->DEGENERATE_OBJECT=DEGENERATE_OBJECT; if (push_hair) if (totalverts) { gl->hair=(BASEHAIR *) malloc (totalverts*sizeof(BASEHAIR)); gl->v=(VERT *) malloc(totalverts*sizeof(VERT)); gl->vn=(VERT *) malloc(totalverts*sizeof(VERT)); for (x=0;xv[x]=v[x]; gl->vn[x]=vn[x]; } } if (push_hair) if (total_splines) { gl->Shair=(BASEHAIR *) malloc (total_splines*sizeof(BASEHAIR)); gl->Sresthair=(BASEHAIR *) malloc (total_splines*sizeof(BASEHAIR)); gl->Shairvelocity=(BASEHAIR *) malloc (total_splines*sizeof(BASEHAIR)); } if (push_hair) if (totalfaces) { gl->poly_weight=(double *) malloc (totalfaces*sizeof(double)); gl->face_end=(int *) malloc (totalfaces*sizeof(int)); gl->face_start=(int *) malloc (totalfaces*sizeof(int)); for (x=0;xpoly_weight[x]=poly_weight[x]; gl->face_end[x]=face_end[x]; gl->face_start[x]=face_start[x]; } } if (push_hair) if (totalfverts) { gl->facelist=(int *) malloc (totalfverts*sizeof(int)); for (x=0;xfacelist[x]=facelist[x]; } if (push_hair) if (Dtotalverts) { gl->Dv=(VERT *) malloc (Dtotalverts*sizeof(VERT)); gl->Dvn= (VERT *) malloc (Dtotalverts*sizeof(VERT)); gl->Dlink = (int *) malloc (Dtotalverts*sizeof (int)); gl->vlink= (int *) malloc(Dtotalverts*sizeof(int)); for (x=0;xvlink[x]=vlink[x]; gl->Dv[x]=Dv[x]; gl->Dvn[x]=Dvn[x]; gl->Dlink[x]=Dlink[x]; } } if (push_hair) if (Dtotalfaces) { gl->Dface_start = (int *) malloc (Dtotalfaces*sizeof(int)); gl->Dface_end = (int *) malloc (Dtotalfaces*sizeof(int)); gl->face_link= (int *) malloc(Dtotalfaces*sizeof(int)); gl->D2UTface_link = (int *) malloc (Dtotalfaces*sizeof(int)); for (x=0;xDface_start[x]=Dface_start[x]; gl->Dface_end[x]=Dface_end[x]; gl->face_link[x]=face_link[x]; gl->D2UTface_link[x]=D2UTface_link[x]; } } if (push_hair) if (Dtotalfverts) { gl->Dfacelist=(int *) malloc (Dtotalfverts*sizeof(int)); for (x=0;xDfacelist[x]=Dfacelist[x]; } } if (push_hair) for (x=0;xhair[x],&hair[x],sizeof(BASEHAIR)); } if (push_hair) for (x=0;xShair[x],&Shair[x],sizeof(BASEHAIR)); memcpy(&gl->Sresthair[x],&Sresthair[x],sizeof(BASEHAIR)); memcpy(&gl->Shairvelocity[x],&Shairvelocity[x],sizeof(BASEHAIR)); } //copy_basehair(gl->hair,hair,totalverts); //copy_basehair(gl->Shair,Shair,total_splines); //copy_basehair(gl->Shairvelocity,Shairvelocity,total_splines); gl->Gbacklighting=Gbacklighting; gl->Gsquirrel=Gsquirrel; gl->random_seed_offset=Grandom_seed_offset; gl->beard=beard; gl->eyebrow=eyebrow; gl->eyelash=eyelash; gl->splines=splines; //memcpy(&(gl->sliders[0][0]),&(sliders[0][0]),sizeof(SLIDER)*45*6); // don't free this //printf ("push renderstate\n");fflush(stdout); for (x=0;x< 60;x++) for (y=0;y<5;y++) { gl->sliders[x][y]=sliders[x][y]; } for (x=0;x<5;x++) { gl->LOCAL_CNT[x]=LOCAL_CNT[x]; gl->LOCAL_SHADCNT[x]=LOCAL_SHADCNT[x]; gl->LOCAL_PASSES[x]=LOCAL_PASSES[x]; gl->LOCAL_SEGS[x]=LOCAL_SEGS[x]; gl->total_slgfaces[x]=total_slgfaces[x]; //memcpy(&gl->LOCAL_CNT,&LOCAL_CNT,sizeof(int)*5); //memcpy(&gl->LOCAL_SHADCNT,&LOCAL_SHADCNT,sizeof(int)*5); //memcpy(&gl->LOCAL_PASSES,&LOCAL_PASSES,sizeof(int)*5); //memcpy(&gl->LOCAL_SEGS,&LOCAL_SEGS,sizeof(int)*5); //memcpy(&gl->total_slgfaces,total_slgfaces,sizeof(int)*5); } //printf ("2\n");fflush(stdout); //printf ("3\n");fflush(stdout); gl->totalfaces= totalfaces; gl->totalfverts= totalfverts; gl->totalverts= totalverts; gl->Dtotalfaces= Dtotalfaces; gl->Dtotalfverts= Dtotalfverts; gl->Dtotalverts= Dtotalverts; for (xx=0;xx<5;xx++) { gl->total_slgfaces[xx]=total_slgfaces[xx]; if (push_hair) gl->slgfaces[xx]=(int *) malloc (gl->total_slgfaces[xx]*sizeof(int)); for (x=0;xtotal_slgfaces[xx];x++) { gl->slgfaces[xx][x]= slgfaces[xx][x]; } } gl->calibrateX=calibrateX; gl->calibrateY=calibrateY; //printf ("4\n");fflush(stdout); if (push_hair) for (xx=0;xxGuv_sets[xx],&Guv_sets[xx]); gl->Guv_link[xx]=Guv_link[xx]; } gl->Guv_totalsets=Guv_totalsets; gl->DUTtotalfaces=DUTtotalfaces; gl->total_splines=total_splines; gl->Gdontinterp=Gdontinterp; gl->nodeID=GnodeID; gl->head=head; gl->beard=beard; gl->eyebrow=eyebrow; gl->eyelash=eyelash; gl->splines=splines; gl->BOUNDLENGTH=BOUNDLENGTH; gl->restBOUNDLENGTH=restBOUNDLENGTH; //printf ("5\n");fflush(stdout); gl->Gspec_tint=Gspec_tint; gl->Gspec_tint2=Gspec_tint2; gl->Gsquirrel=Gsquirrel; init_geomWF(&gl->freeze); if (push_hair) { init_geomWF(&gl->freeze); gl->freeze.totalverts=freeze.totalverts; gl->freeze.totalfaces=freeze.totalfaces; gl->freeze.totalfverts=freeze.totalfverts; alloc_geomWF(&gl->freeze); } //gl->Gkd=Gkd; //gl->Gindex=Gindex; //Gkd=NULL; // intentionally creating a leak here - make sure it works gl->Gclumps=Gclumps; //gl->Gindex= Gindex_stack[SHAVEID]; //gl->Gkd= &Gkd_stack[SHAVEID]; if (push_hair) init_clumpingRS(gs); gl->Gflyaway_percent=Gflyaway_percent; //clear_shave_engine(); //test_roots(); } void init_engine(void) // now we need to open a leak here to protect the cached ones { int xx; // for (xx=0;xx<20000;xx++) Gindex[xx]=xx; hair=NULL; Shair=NULL; Shairvelocity=NULL; // sliders=NULL; // don't free this Dv=NULL; v=NULL; vn=NULL; vnrest=NULL; Dvn=NULL; facelist=NULL; face_start=NULL; face_end=NULL; Dfacelist=NULL; Dface_start=NULL; Dface_end=NULL; poly_weight=NULL; Dpoly_weight=NULL; face_link=NULL; D2UTface_link=NULL; Dlink=NULL; //Gkd=NULL; Gsquirrel=0; for (xx=0;xx<5;xx++) { total_slgfaces[xx]=0; slgfaces[xx]=NULL; } vlink=NULL; for (xx=0;xx< 60;xx++) { init_geomWF(&Guv_sets[xx]); free_geomWF(&Guv_sets[xx]); Guv_link[xx]=0; } totalfaces=0; totalfverts=0; totalverts=0; Dtotalfaces=0; Dtotalfverts=0; Dtotalverts=0; Guv_totalsets=0; DUTtotalfaces=0; total_splines=0; Gdontinterp=0; Sresthair=NULL; head=0; beard=0; eyebrow=0; eyelash=0; splines=0; Gindex=NULL; } void pop_renderstate( RENDERSTATE *gl) { int xx,x,y; //printf ("pop render state\n");fflush(stdout); hair= gl->hair; Shair= gl->Shair; Shairvelocity= gl->Shairvelocity; SHAVEID=(unsigned long)gl->nodeID; beard=gl->beard; eyebrow=gl->eyebrow; eyelash=gl->eyelash; splines=gl->splines; Gbacklighting=gl->Gbacklighting; Gsquirrel=gl->Gsquirrel; //memcpy (&(sliders[0][0]),&(gl->sliders[0][0]),sizeof(SLIDER)*45*6); //memcpy(&total_slgfaces,&gl->total_slgfaces,sizeof(int)*5); for (xx=0;xx<5;xx++) slgfaces[xx]=gl->slgfaces[xx]; hair= gl->hair; Shair=gl->Shair; Shairvelocity=gl->Shairvelocity; //printf ("2\n");fflush(stdout); //memcpy(&LOCAL_CNT,&gl->LOCAL_CNT,sizeof(int)*5); //memcpy(&LOCAL_SHADCNT,&gl->LOCAL_SHADCNT,sizeof(int)*5); //memcpy(&LOCAL_PASSES,&gl->LOCAL_PASSES,sizeof(int)*5); //memcpy(&LOCAL_SEGS,&gl->LOCAL_SEGS,sizeof(int)*5); for (x=0;x<5;x++) { LOCAL_CNT[x]=gl->LOCAL_CNT[x]; LOCAL_SHADCNT[x]=gl->LOCAL_SHADCNT[x]; LOCAL_PASSES[x]=gl->LOCAL_PASSES[x]; LOCAL_SEGS[x]=gl->LOCAL_SEGS[x]; total_slgfaces[x]=gl->total_slgfaces[x]; //memcpy(&gl->LOCAL_CNT,&LOCAL_CNT,sizeof(int)*5); //memcpy(&gl->LOCAL_SHADCNT,&LOCAL_SHADCNT,sizeof(int)*5); //memcpy(&gl->LOCAL_PASSES,&LOCAL_PASSES,sizeof(int)*5); //memcpy(&gl->LOCAL_SEGS,&LOCAL_SEGS,sizeof(int)*5); //memcpy(&gl->total_slgfaces,total_slgfaces,sizeof(int)*5); } //printf ("3\n");fflush(stdout); Dv=gl->Dv; v=gl->v; vn=gl->vn; Dvn=gl->Dvn; poly_weight=gl->poly_weight; Dpoly_weight=gl->Dpoly_weight; facelist=gl-> facelist; face_start=gl-> face_start; face_end=gl-> face_end; Dfacelist=gl-> Dfacelist; Dface_start=gl-> Dface_start; Dface_end=gl-> Dface_end; totalfaces= totalfaces; totalfverts= totalfverts; totalverts= totalverts; Dtotalfaces= Dtotalfaces; Dtotalfverts= Dtotalfverts; Dtotalverts= Dtotalverts; face_link=gl-> face_link; D2UTface_link=gl-> D2UTface_link; Dlink=gl-> Dlink; for (xx=0;xx<5;xx++) { total_slgfaces[xx]=gl->total_slgfaces[xx]; slgfaces[xx]=gl->slgfaces[xx]; } vlink= gl->vlink; for (xx=0;xx< 60;xx++) { // Guv_sets[xx]=&gl->Guv_sets[xx]; Guv_link[xx]=gl->Guv_link[xx]; } Guv_totalsets=gl->Guv_totalsets; DUTtotalfaces=gl->DUTtotalfaces; total_splines=gl->total_splines; Gdontinterp=gl->Gdontinterp; Sresthair= gl->Sresthair; SHAVEID=(int)gl->nodeID; BOUNDLENGTH=gl->BOUNDLENGTH; restBOUNDLENGTH=gl->restBOUNDLENGTH; head=gl->head; beard=gl->beard; eyebrow=gl->eyebrow; eyelash=gl->eyelash; splines=gl->splines; Gspec_tint=gl->Gspec_tint; Gspec_tint2=gl->Gspec_tint2; Gsquirrel=gl->Gsquirrel; calibrateX=gl->calibrateX; calibrateY=gl->calibrateY; //Gkd=gl->Gkd; Gclumps=gl->Gclumps; Gflyaway_percent=gl->Gflyaway_percent; //printf ("4\n");fflush(stdout); for (x=0;x< 60;x++) for (y=0;y<5;y++) { sliders[x][y]=gl->sliders[x][y]; } //memcpy(&(sliders[0][0]),&(gl->sliders[0][0]),sizeof(SLIDER)*45*6); // don't free this for (x=0;x<5;x++) { LOCAL_CNT[x]=gl->LOCAL_CNT[x]; LOCAL_SHADCNT[x]=gl->LOCAL_SHADCNT[x]; LOCAL_PASSES[x]=gl->LOCAL_PASSES[x]; LOCAL_SEGS[x]=gl->LOCAL_SEGS[x]; } //printf ("5\n");fflush(stdout); //printf ("pop render state\n");fflush(stdout); } void free_renderstate(RENDERSTATE *gl) { int xx; if (gl) { if (gl->hair) free(gl->hair); gl->hair=NULL; if (gl->Shair) free(gl->Shair); gl->Shair=NULL; //if (0==1) // dissable clumping if (gl->Gclumps>0) { if (gl->Gindex) { kd_free(gl->Gkd); free(gl->Gindex); gl->Gindex=NULL; } } //gl->Gclumps=0; if (total_splines) if (gl->Shair) free(gl->Shair); gl->Shair=NULL; if (gl->Shairvelocity) free(gl->Shairvelocity); gl->Shairvelocity=NULL; if (gl->Dv) free(gl->Dv); gl->Dv=NULL; if (gl->v) free(gl->v); gl->v=NULL; if (gl->vn) free(gl->vn); gl->vn=NULL; if (gl->Dvn) free(gl->Dvn); gl->Dvn=NULL; if (gl->facelist) free(gl-> facelist); gl->facelist=NULL; if (gl->face_start) free(gl-> face_start); gl->face_start=NULL; if (gl->face_end) free(gl-> face_end); gl->face_end=NULL; if (gl->Dfacelist) free(gl-> Dfacelist); gl->Dfacelist=NULL; if (gl->Dface_start) free(gl-> Dface_start); gl->Dface_start=NULL; if (gl->Dface_end) free(gl-> Dface_end); gl->Dface_end=NULL; if (gl->face_link) free(gl-> face_link); gl->face_link=NULL; if (gl->D2UTface_link) free(gl-> D2UTface_link); gl->D2UTface_link=NULL; if (gl->poly_weight) free(gl->poly_weight); gl->poly_weight=NULL; if (gl->Dlink) free(gl-> Dlink); gl->Dlink=NULL; for (xx=0;xx<5;xx++) { if (gl->slgfaces[xx]) free(gl->slgfaces[xx]); gl->slgfaces[xx]=NULL; } if (gl->vlink) free(gl->vlink); gl->vlink=NULL; for (xx=0;xx< 60;xx++) { free_geomWF(&gl->Guv_sets[xx]); init_geomWF( &gl->Guv_sets[xx] ); } gl->Guv_totalsets=0; for( xx = 0; xx < 60; xx++ ) gl->Guv_link[xx] = -1; if (gl->Sresthair) free(gl->Sresthair); gl->Sresthair=NULL; if (gl->freeze.totalverts>0) free_geomWF(&gl->freeze); } } void free_renderstate_stack(void) { int x; int th; th=SHAVEnum_processors(); for (x=0;x