diff options
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 1 | ||||
-rw-r--r-- | source/blender/radiosity/intern/source/radrender.c | 124 | ||||
-rw-r--r-- | source/blender/render/extern/include/render.h | 11 | ||||
-rw-r--r-- | source/blender/render/extern/include/render_types.h | 11 | ||||
-rw-r--r-- | source/blender/render/intern/source/envmap.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderHelp.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 72 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderdatabase.c | 170 | ||||
-rw-r--r-- | source/blender/render/intern/source/texture.c | 9 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 4 | ||||
-rw-r--r-- | source/blender/renderconverter/intern/convertBlenderScene.c | 250 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 9 |
14 files changed, 388 insertions, 287 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index c9c1b4fa98d..b0c57eef25d 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -596,7 +596,7 @@ void init_render_material(Material *ma) if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA; } - if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND)) needuv= 1; + if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1; else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT)) needuv= 1; else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index bbe7d0f8125..ff2eb7194eb 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -221,6 +221,7 @@ typedef struct Material { #define TEXCO_OPTIM 4096 /* stored in vertex->accum, 1 D */ #define TEXCO_STRAND 8192 +#define TEXCO_STRESS 16384 /* mapto */ #define MAP_COL 1 diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c index 50b9569c09f..a6ff8657d0c 100644 --- a/source/blender/radiosity/intern/source/radrender.c +++ b/source/blender/radiosity/intern/source/radrender.c @@ -399,100 +399,16 @@ static void vecaddfac(float *vec, float *v1, float *v2, float fac) } -#if 0 -/* unused now, doesnt work... */ -static void filter_rad_values(void) -{ - VlakRen *vlr=NULL; - VertRen *v1=NULL; - RadFace *rf; - float n1[3], n2[3], n3[4], n4[3], co[4]; - int a; - - /* one filter pass */ - for(a=0; a<R.totvert; a++) { - if((a & 255)==0) v1= R.blove[a>>8]; else v1++; - if(v1->accum>0.0) { - v1->rad[0]= v1->rad[0]/v1->accum; - v1->rad[1]= v1->rad[1]/v1->accum; - v1->rad[2]= v1->rad[2]/v1->accum; - v1->accum= 0.0; - } - } - /* cosines in verts accumulate in faces */ - for(a=0; a<R.totvlak; a++) { - if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++; - - if(vlr->radface) { - rf= vlr->radface; - - /* calculate cosines of angles, for weighted add (irregular faces) */ - VecSubf(n1, vlr->v2->co, vlr->v1->co); - VecSubf(n2, vlr->v3->co, vlr->v2->co); - Normalise(n1); - Normalise(n2); - - if(vlr->v4==NULL) { - VecSubf(n3, vlr->v1->co, vlr->v3->co); - Normalise(n3); - - co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2])/M_PI; - co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI; - co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI; - co[0]= co[1]= co[2]= 1.0/3.0; - } - else { - VecSubf(n3, vlr->v4->co, vlr->v3->co); - VecSubf(n4, vlr->v1->co, vlr->v4->co); - Normalise(n3); - Normalise(n4); - - co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2])/M_PI; - co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI; - co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI; - co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2])/M_PI; - co[0]= co[1]= co[2]= co[3]= 1.0/4.0; - } - - rf->totrad[0]= rf->totrad[1]= rf->totrad[2]= 0.0; +/* unused now, doesnt work..., find it in cvs of nov 2005 or older */ +/* static void filter_rad_values(void) */ - vecaddfac(rf->totrad, rf->totrad, vlr->v1->rad, co[0]); - vecaddfac(rf->totrad, rf->totrad, vlr->v2->rad, co[1]); - vecaddfac(rf->totrad, rf->totrad, vlr->v3->rad, co[2]); - if(vlr->v4) { - vecaddfac(rf->totrad, rf->totrad, vlr->v4->rad, co[3]); - } - } - } - - /* accumulate vertexcolors again */ - for(a=0; a<R.totvlak; a++) { - if((a & 255)==0) vlr= R.blovl[a>>8]; else vlr++; - - if(vlr->radface) { - rf= vlr->radface; - - vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); - vlr->v1->accum+= rf->area; - vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); - vlr->v2->accum+= rf->area; - vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); - vlr->v3->accum+= rf->area; - if(vlr->v4) { - vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); - vlr->v4->accum+= rf->area; - } - } - } - -} -#endif static void make_vertex_rad_values() { VertRen *v1=NULL; VlakRen *vlr=NULL; RadFace *rf; + float *col; int a; RG.igamma= 1.0/RG.gamma; @@ -515,26 +431,34 @@ static void make_vertex_rad_values() if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g; if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b; - vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); - vlr->v1->accum+= rf->area; - vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); - vlr->v2->accum+= rf->area; - vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); - vlr->v3->accum+= rf->area; + col= RE_vertren_get_rad(vlr->v1, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + + col= RE_vertren_get_rad(vlr->v2, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + + col= RE_vertren_get_rad(vlr->v3, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + if(vlr->v4) { - vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); - vlr->v4->accum+= rf->area; + col= RE_vertren_get_rad(vlr->v4, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; } } } /* make vertex colors */ for(a=0; a<R.totvert; a++) { - if((a & 255)==0) v1= R.blove[a>>8]; else v1++; - if(v1->accum>0.0) { - v1->rad[0]/= v1->accum; - v1->rad[1]/= v1->accum; - v1->rad[2]/= v1->accum; + if((a & 255)==0) v1= RE_findOrAddVert(a); else v1++; + col= RE_vertren_get_rad(v1, 0); + if(col[3]>0.0) { + col[0]/= col[3]; + col[1]/= col[3]; + col[2]/= col[3]; } } diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h index ec724b55846..5f8ceb45b15 100644 --- a/source/blender/render/extern/include/render.h +++ b/source/blender/render/extern/include/render.h @@ -199,7 +199,7 @@ void init_ao_sphere(float *sphere, int tot, int iter); /* --------------------------------------------------------------------- */ -/* renderdatabase (3) */ +/* renderdatabase () */ /* --------------------------------------------------------------------- */ struct VlakRen *RE_findOrAddVlak(int nr); struct VertRen *RE_findOrAddVert(int nr); @@ -207,6 +207,15 @@ struct HaloRen *RE_findOrAddHalo(int nr); HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize, float vectsize, int seed); +float *RE_vertren_get_sticky(struct VertRen *ver, int verify); +float *RE_vertren_get_stress(struct VertRen *ver, int verify); +float *RE_vertren_get_rad(struct VertRen *ver, int verify); +float *RE_vertren_get_strand(struct VertRen *ver, int verify); +float *RE_vertren_get_tangent(struct VertRen *ver, int verify); + +void RE_free_vertex_tables(void); +void RE_init_vertex_tables(void); + /** * callbacks (11): * diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/extern/include/render_types.h index 531a7fc5ceb..dc2f5616f29 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/extern/include/render_types.h @@ -89,7 +89,7 @@ typedef struct ShadeInput /* texture coordinates */ float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; - float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3]; + float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress; /* dx/dy OSA coordinates */ float dxco[3], dyco[3]; @@ -110,6 +110,7 @@ typedef struct ShadeInput } ShadeInput; struct MemArena; +struct VertTableNode; /* here only stuff to initalize the render itself */ typedef struct RE_Render @@ -149,7 +150,7 @@ typedef struct RE_Render ListBase lights; struct LampRen **la; struct VlakRen **blovl; - struct VertRen **blove; + struct VertTableNode *vertnodes; struct HaloRen **bloha; /* arena for allocating data for use during render, for @@ -198,13 +199,11 @@ typedef struct VertRen float co[3]; float n[3]; float ho[4]; - float rad[3]; /* result radio rendering */ float *orco; - float *sticky; - void *svert; /* smooth vert, only used during initrender */ short clip; - short flag; /* in use for clipping ztra parts */ + short flag; /* in use for clipping ztra parts, temp setting stuff in convertBlenderscene.c */ float accum; /* accum for radio weighting, and for strand texco static particles */ + int index; /* index allows extending vertren with any property */ } VertRen; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index f7c31fa099a..aba3a34929c 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -289,7 +289,7 @@ static void env_rotate_scene(float mat[][4], int mode) } for(a=0; a<R.totvert; a++) { - if((a & 255)==0) ver= R.blove[a>>8]; + if((a & 255)==0) ver= RE_findOrAddVert(a); else ver++; MTC_Mat4MulVecfl(tmat, ver->co); diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 1f1ffc20cf5..ba9216fa80e 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -479,11 +479,12 @@ static void init_def_material(void) init_render_material(ma); } +/* this is called in creator.c, on startup */ void RE_init_render_data(void) { memset(&R, 0, sizeof(RE_Render)); - R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove"); + RE_init_vertex_tables(); R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl"); R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha"); @@ -491,10 +492,11 @@ void RE_init_render_data(void) init_filt_mask(); } +/* called in usiblender.c on exit, also for blender -b render */ void RE_free_render_data() { - MEM_freeN(R.blove); - R.blove= NULL; + MEM_freeN(R.vertnodes); + R.vertnodes= NULL; MEM_freeN(R.blovl); R.blovl= NULL; MEM_freeN(R.bloha); diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c index aa966268aca..aba78079472 100644 --- a/source/blender/render/intern/source/renderHelp.c +++ b/source/blender/render/intern/source/renderHelp.c @@ -149,7 +149,7 @@ void setzbufvlaggen( void (*projectfunc)(float *, float *) ) /* calculate view coordinates (and zbuffer value) */ for(a=0; a< R.totvert;a++) { - if((a & 255)==0) ver= R.blove[a>>8]; + if((a & 255)==0) ver= RE_findOrAddVert(a); else ver++; if(R.r.mode & R_PANORAMA) { diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 99e9384f5b8..3ca504e2ce4 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2141,9 +2141,20 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->orn[2]= -shi->vn[2]; } if(mode & MA_RADIO) { - shi->rad[0]= (l*v3->rad[0] - u*v1->rad[0] - v*v2->rad[0]); - shi->rad[1]= (l*v3->rad[1] - u*v1->rad[1] - v*v2->rad[1]); - shi->rad[2]= (l*v3->rad[2] - u*v1->rad[2] - v*v2->rad[2]); + float *r1, *r2, *r3; + + r1= RE_vertren_get_rad(v1, 0); + r2= RE_vertren_get_rad(v2, 0); + r3= RE_vertren_get_rad(v3, 0); + + if(r1 && r2 && r3) { + shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]); + shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]); + shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]); + } + else { + shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; + } } else { shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; @@ -2152,7 +2163,19 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i /* mirror reflection colour textures (and envmap) */ calc_R_ref(shi); } - + if(texco & TEXCO_STRESS) { + float *s1, *s2, *s3; + + s1= RE_vertren_get_stress(v1, 0); + s2= RE_vertren_get_stress(v2, 0); + s3= RE_vertren_get_stress(v3, 0); + if(s1 && s2 && s3) { + shi->stress= l*s3[0] - u*s1[0] - v*s2[0]; + if(shi->stress<1.0f) shi->stress-= 1.0f; + else shi->stress= (shi->stress-1.0f)/shi->stress; + } + else shi->stress= 0.0f; + } } else { shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; @@ -2225,7 +2248,7 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa VECCOPY(rco, col); } else if( (facenr & 0x7FFFFF) <= R.totvlak) { - VertRen *v1, *v2, *v3; + VertRen *v1; Material *mat; MaterialLayer *ml; float alpha, fac, zcor; @@ -2349,17 +2372,24 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa } /* after this the u and v AND shi.dxuv and shi.dyuv are incorrect */ if(shi.mat->texco & TEXCO_STICKY) { - if(v1->sticky) { + VertRen *v2, *v3; + float *s1, *s2, *s3; + + if(facenr & 0x800000) { + v2= vlr->v3; v3= vlr->v4; + } else { + v2= vlr->v2; v3= vlr->v3; + } + + s1= RE_vertren_get_sticky(v1, 0); + s2= RE_vertren_get_sticky(v2, 0); + s3= RE_vertren_get_sticky(v3, 0); + + if(s1 && s2 && s3) { extern float Zmulx, Zmuly; - float *o1, *o2, *o3, hox, hoy, l, dl, u, v; + float hox, hoy, l, dl, u, v; float s00, s01, s10, s11, detsh; - if(facenr & 0x800000) { - v2= vlr->v3; v3= vlr->v4; - } else { - v2= vlr->v2; v3= vlr->v3; - } - s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3]; s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3]; s10= v3->ho[0]/v3->ho[3] - v2->ho[0]/v2->ho[3]; @@ -2376,12 +2406,8 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01; l= 1.0+u+v; - o1= v1->sticky; - o2= v2->sticky; - o3= v3->sticky; - - shi.sticky[0]= l*o3[0]-u*o1[0]-v*o2[0]; - shi.sticky[1]= l*o3[1]-u*o1[1]-v*o2[1]; + shi.sticky[0]= l*s3[0]-u*s1[0]-v*s2[0]; + shi.sticky[1]= l*s3[1]-u*s1[1]-v*s2[1]; shi.sticky[2]= 0.0; if(shi.osatex) { @@ -2391,11 +2417,11 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa shi.dyuv[1]= s00/Zmuly; dl= shi.dxuv[0]+shi.dxuv[1]; - shi.dxsticky[0]= dl*o3[0]-shi.dxuv[0]*o1[0]-shi.dxuv[1]*o2[0]; - shi.dxsticky[1]= dl*o3[1]-shi.dxuv[0]*o1[1]-shi.dxuv[1]*o2[1]; + shi.dxsticky[0]= dl*s3[0]-shi.dxuv[0]*s1[0]-shi.dxuv[1]*s2[0]; + shi.dxsticky[1]= dl*s3[1]-shi.dxuv[0]*s1[1]-shi.dxuv[1]*s2[1]; dl= shi.dyuv[0]+shi.dyuv[1]; - shi.dysticky[0]= dl*o3[0]-shi.dyuv[0]*o1[0]-shi.dyuv[1]*o2[0]; - shi.dysticky[1]= dl*o3[1]-shi.dyuv[0]*o1[1]-shi.dyuv[1]*o2[1]; + shi.dysticky[0]= dl*s3[0]-shi.dyuv[0]*s1[0]-shi.dyuv[1]*s2[0]; + shi.dysticky[1]= dl*s3[1]-shi.dyuv[0]*s1[1]-shi.dyuv[1]*s2[1]; } } } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index b2f7cdfca48..4c7453bf1b1 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -44,7 +44,7 @@ * offset in a 256-entry block. * * - If the 256-entry block entry has an entry in the - * blove/bloha/blovl array of the current block, the i-th entry in + * vertnodes/bloha/blovl array of the current block, the i-th entry in * that block is allocated to this entry. * * - If the entry has no block allocated for it yet, memory is @@ -74,11 +74,24 @@ /* ------------------------------------------------------------------------- */ -#if 0 -/* proposal for more dynamic allocation of options for render vertices, so we dont - have to reserve this space inside vertices */ + +/* More dynamic allocation of options for render vertices, so we dont + have to reserve this space inside vertices. + Important; vertices should have been created already (to get tables checked) + that's a reason why the calls demand VertRen * as arg, not the index */ + +/* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */ + +#define RE_STICKY_ELEMS 2 +#define RE_STRESS_ELEMS 1 +#define RE_RAD_ELEMS 4 +#define RE_STRAND_ELEMS 1 +#define RE_TANGENT_ELEMS 3 +#define RE_STRESS_ELEMS 1 + +/* render allocates totvert/256 of these nodes, for lookup and quick alloc */ typedef struct VertTableNode { - VertRen *vert; + struct VertRen *vert; float *rad; float *sticky; float *strand; @@ -86,55 +99,162 @@ typedef struct VertTableNode { float *stress; } VertTableNode; -#define RE_STICKY_ELEMS 3 float *RE_vertren_get_sticky(VertRen *ver, int verify) { float *sticky; - int a= ver->index>>8; + int nr= ver->index>>8; - sticky= R.blove[a].sticky; + sticky= R.vertnodes[nr].sticky; if(sticky==NULL) { if(verify) - sticky= R.blove[a].sticky= MEM_mallocN(RE_STICKY_ELEMS*sizeof(float), "sticky table"); + sticky= R.vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table"); + else + return NULL; + } + return sticky + (ver->index & 255)*RE_STICKY_ELEMS; +} + +float *RE_vertren_get_stress(VertRen *ver, int verify) +{ + float *stress; + int nr= ver->index>>8; + + stress= R.vertnodes[nr].stress; + if(stress==NULL) { + if(verify) + stress= R.vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table"); + else + return NULL; + } + return stress + (ver->index & 255)*RE_STRESS_ELEMS; +} + +/* this one callocs! */ +float *RE_vertren_get_rad(VertRen *ver, int verify) +{ + float *rad; + int nr= ver->index>>8; + + rad= R.vertnodes[nr].rad; + if(rad==NULL) { + if(verify) + rad= R.vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table"); + else + return NULL; + } + return rad + (ver->index & 255)*RE_RAD_ELEMS; +} + +float *RE_vertren_get_strand(VertRen *ver, int verify) +{ + float *strand; + int nr= ver->index>>8; + + strand= R.vertnodes[nr].strand; + if(strand==NULL) { + if(verify) + strand= R.vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table"); else return NULL; } - sticky+= (nr & 255)*RE_STICKY_ELEMS; + return strand + (ver->index & 255)*RE_STRAND_ELEMS; } -#endif + +float *RE_vertren_get_tangent(VertRen *ver, int verify) +{ + float *tangent; + int nr= ver->index>>8; + + tangent= R.vertnodes[nr].tangent; + if(tangent==NULL) { + if(verify) + tangent= R.vertnodes[nr].tangent= MEM_mallocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); + else + return NULL; + } + return tangent + (ver->index & 255)*RE_TANGENT_ELEMS; +} + VertRen *RE_findOrAddVert(int nr) { - VertRen *v, **temp; - static int rblovelen=TABLEINITSIZE; + VertTableNode *temp; + VertRen *v; + static int rvertnodeslen=TABLEINITSIZE; int a; if(nr<0) { printf("error in findOrAddVert: %d\n",nr); - return R.blove[0]; + return R.vertnodes[0].vert; } a= nr>>8; - if (a>=rblovelen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ - //printf("Allocating %i more vert groups. %i total.\n", - // TABLEINITSIZE, rblovelen+TABLEINITSIZE ); - temp=R.blove; - R.blove=(VertRen**)MEM_callocN(sizeof(void*)*(rblovelen+TABLEINITSIZE) , "Blove"); - memcpy(R.blove, temp, rblovelen*sizeof(void*)); - memset(&(R.blove[rblovelen]), 0, TABLEINITSIZE*sizeof(void*)); - rblovelen+=TABLEINITSIZE; + if (a>=rvertnodeslen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ + temp= R.vertnodes; + + R.vertnodes= MEM_mallocN(sizeof(VertTableNode)*(rvertnodeslen+TABLEINITSIZE) , "vertnodes"); + memcpy(R.vertnodes, temp, rvertnodeslen*sizeof(VertTableNode)); + memset(R.vertnodes+rvertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode)); + + rvertnodeslen+=TABLEINITSIZE; MEM_freeN(temp); } - v= R.blove[a]; - if(v==0) { + v= R.vertnodes[a].vert; + if(v==NULL) { + int i; + v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert"); - R.blove[a]= v; + R.vertnodes[a].vert= v; + + for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) { + v[a].index= i; + } } v+= (nr & 255); return v; } +void RE_free_vertex_tables(void) +{ + int a=0; + + while(R.vertnodes[a].vert) { + if(R.vertnodes[a].vert) { + MEM_freeN(R.vertnodes[a].vert); + R.vertnodes[a].vert= NULL; + + if(R.vertnodes[a].rad) { + MEM_freeN(R.vertnodes[a].rad); + R.vertnodes[a].rad= NULL; + } + if(R.vertnodes[a].sticky) { + MEM_freeN(R.vertnodes[a].sticky); + R.vertnodes[a].sticky= NULL; + } + if(R.vertnodes[a].strand) { + MEM_freeN(R.vertnodes[a].strand); + R.vertnodes[a].strand= NULL; + } + if(R.vertnodes[a].tangent) { + MEM_freeN(R.vertnodes[a].tangent); + R.vertnodes[a].tangent= NULL; + } + if(R.vertnodes[a].stress) { + MEM_freeN(R.vertnodes[a].stress); + R.vertnodes[a].stress= NULL; + } + } + a++; + } +} + +/* only once, on startup */ +void RE_init_vertex_tables(void) +{ + R.vertnodes= MEM_callocN(sizeof(VertTableNode)*TABLEINITSIZE , "vertnodes"); +} + /* ------------------------------------------------------------------------ */ int rblohalen=TABLEINITSIZE; HaloRen *RE_findOrAddHalo(int nr) diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 344957608fe..38936ec89fa 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1462,6 +1462,15 @@ void do_material_tex(ShadeInput *shi) dy[0]= shi->dystrand; dy[1]= dy[2]= 0.0f; } + else if(mtex->texco==TEXCO_STRESS) { + co= tempvec; dx= dxt; dy= dyt; + co[0]= shi->stress; + co[1]= co[2]= 0.0f; + dx[0]= 0.0f; + dx[1]= dx[2]= 0.0f; + dy[0]= 0.0f; + dy[1]= dy[2]= 0.0f; + } else continue; // can happen when texco defines disappear and it renders old files /* de pointer defines if bumping happens */ diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index f7480c4cb2f..368acfe1a41 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2559,9 +2559,7 @@ static void set_faces_raycountflag(void) maxy= (float)(2*Amaxy-R.recty+2)/(float)R.recty; for(v=0; v<R.totvert; v++) { - if((v & 255)==0) { - ver= R.blove[v>>8]; - } + if((v & 255)==0) ver= RE_findOrAddVert(v); else ver++; wco= ver->ho[3]; diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 776d656abaf..509e42637c0 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -314,6 +314,14 @@ void RE_make_stars(void (*initfunc)(void), /* ------------------------------------------------------------------------- */ +static VertRen *RE_duplicate_vertren(VertRen *ver) +{ + VertRen *v1= RE_findOrAddVert(R.totvert++); + int index= v1->index; + *v1= *ver; + v1->index= index; +} + static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv) { int vLen = vsize-1+(!!cyclv); @@ -322,10 +330,9 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi for (v=0; v<vLen; v++) { VlakRen *vlr = RE_findOrAddVlak(startvlak + vLen*uIndex + v); - VertRen *vert = RE_findOrAddVert(R.totvert++); + VertRen *vert = RE_duplicate_vertren(vlr->v2); if (cyclv) { - *vert = *vlr->v2; vlr->v2 = vert; if (v==vLen-1) { @@ -336,7 +343,6 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi vlr->v1 = vert; } } else { - *vert = *vlr->v2; vlr->v2 = vert; if (v<vLen-1) { @@ -345,60 +351,12 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi } if (v==0) { - vert = RE_findOrAddVert(R.totvert++); - *vert = *vlr->v1; - vlr->v1 = vert; + vlr->v1 = RE_duplicate_vertren(vlr->v1); } } } } -#if 0 -static void DBG_show_shared_render_faces(int firstvert, int firstface) -{ - int i; - - for (i=firstvert; i<R.totvert; i++) { - VertRen *ver = RE_findOrAddVert(i); - - ver->n[0] = ver->n[1] = ver->n[2] = 0.0; - ver->sticky = 0; - } - - for (i=firstface; i<R.totvlak; i++) { - VlakRen *vlr = RE_findOrAddVlak(i); - float cent[3]; - - if (vlr->v4) { - CalcCent4f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - VecAddf(vlr->v4->n, vlr->v4->n, cent); - vlr->v4->sticky = (float*) (((int) vlr->v4->sticky) + 1); - } else { - CalcCent3f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co); - } - - VecAddf(vlr->v1->n, vlr->v1->n, cent); - VecAddf(vlr->v2->n, vlr->v2->n, cent); - VecAddf(vlr->v3->n, vlr->v3->n, cent); - - vlr->v1->sticky = (float*) (((int) vlr->v1->sticky) + 1); - vlr->v2->sticky = (float*) (((int) vlr->v2->sticky) + 1); - vlr->v3->sticky = (float*) (((int) vlr->v3->sticky) + 1); - } - - for (i=firstvert; i<R.totvert; i++) { - VertRen *ver = RE_findOrAddVert(i); - - VecMulf(ver->n, 1.f/(int) ver->sticky); - - VecLerpf(ver->co, ver->co, ver->n, 0.3); - ver->sticky = 0; - } - - calc_vertexnormals(firstvert, firstface); -} -#endif - /* ------------------------------------------------------------------------- */ static int contrpuntnormr(float *n, float *puno) @@ -412,6 +370,78 @@ static int contrpuntnormr(float *n, float *puno) /* ------------------------------------------------------------------------- */ +static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2) +{ + float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco); + float *acc; + + acc= accum + 2*v1->index; + acc[0]+= len; + acc[1]+= 1.0f; + + acc= accum + 2*v2->index; + acc[0]+= len; + acc[1]+= 1.0f; +} + +static void calc_edge_stress(Mesh *me, int startvert, int startvlak) +{ + float loc[3], size[3], *accum, *acc, *accumoffs, *stress; + int a; + + if(startvert==R.totvert) return; + + mesh_get_texspace(me, loc, NULL, size); + + accum= MEM_callocN(2*sizeof(float)*(R.totvert-startvert), "temp accum for stress"); + + /* de-normalize orco */ + for(a=startvert; a<R.totvert; a++, acc+=2) { + VertRen *ver= RE_findOrAddVert(a); + if(ver->orco) { + ver->orco[0]= ver->orco[0]*size[0] +loc[0]; + ver->orco[1]= ver->orco[1]*size[1] +loc[1]; + ver->orco[2]= ver->orco[2]*size[2] +loc[2]; + } + } + + /* add stress values */ + accumoffs= accum - 2*startvert; /* so we can use vertex index */ + for(a=startvlak; a<R.totvlak; a++) { + VlakRen *vlr= RE_findOrAddVlak(a); + + if(vlr->v1->orco && vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3); + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1); + if(vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4); + calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4); + } + } + } + + for(a=startvert; a<R.totvert; a++) { + VertRen *ver= RE_findOrAddVert(a); + if(ver->orco) { + /* find stress value */ + acc= accumoffs + 2*ver->index; + if(acc[1]!=0.0f) + acc[0]/= acc[1]; + stress= RE_vertren_get_stress(ver, 1); + *stress= *acc; + + /* restore orcos */ + ver->orco[0] = (ver->orco[0]-loc[0])/size[0]; + ver->orco[1] = (ver->orco[1]-loc[1])/size[1]; + ver->orco[2] = (ver->orco[2]-loc[2])/size[2]; + } + } + + MEM_freeN(accum); +} + static void calc_vertexnormals(int startvert, int startvlak) { int a; @@ -543,30 +573,21 @@ typedef struct ASface { VertRen *nver[4]; } ASface; -/* prototypes: */ -static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh); -static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh); - - -static void as_addvert(VertRen *v1, VlakRen *vlr) +static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr) { - ASvert *asv; ASface *asf; int a; if(v1 == NULL) return; - if(v1->svert==0) { - v1->svert= MEM_callocN(sizeof(ASvert), "asvert"); - asv= v1->svert; + if(asv->faces.first==NULL) { asf= MEM_callocN(sizeof(ASface), "asface"); BLI_addtail(&asv->faces, asf); } - asv= v1->svert; asf= asv->faces.last; for(a=0; a<4; a++) { - if(asf->vlr[a]==0) { + if(asf->vlr[a]==NULL) { asf->vlr[a]= vlr; asv->totface++; break; @@ -582,16 +603,6 @@ static void as_addvert(VertRen *v1, VlakRen *vlr) } } -static void as_freevert(VertRen *ver) -{ - ASvert *asv; - - asv= ver->svert; - BLI_freelistN(&asv->faces); - MEM_freeN(asv); - ver->svert= NULL; -} - static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) { /* return 1: vertex needs a copy */ @@ -643,37 +654,35 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thr static void autosmooth(int startvert, int startvlak, int degr) { - ASvert *asv; + ASvert *asv, *asverts, *asvertoffs; ASface *asf; VertRen *ver, *v1; VlakRen *vlr; float thresh; int a, b, totvert; - thresh= cos( M_PI*((float)degr)/180.0 ); + if(startvert==R.totvert) return; + asverts= MEM_callocN(sizeof(ASvert)*(R.totvert-startvert), "all smooth verts"); + asvertoffs= asverts-startvert; /* se we can use indices */ - /* initialize */ - for(a=startvert; a<R.totvert; a++) { - ver= RE_findOrAddVert(a); - ver->svert= 0; - } + thresh= cos( M_PI*((float)degr)/180.0 ); /* step one: construct listbase of all vertices and pointers to faces */ for(a=startvlak; a<R.totvlak; a++) { vlr= RE_findOrAddVlak(a); - as_addvert(vlr->v1, vlr); - as_addvert(vlr->v2, vlr); - as_addvert(vlr->v3, vlr); - as_addvert(vlr->v4, vlr); + as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr); + as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr); + as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr); + if(vlr->v4) + as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr); } /* we now test all vertices, when faces have a normal too much different: they get a new vertex */ totvert= R.totvert; - for(a=startvert; a<totvert; a++) { - ver= RE_findOrAddVert(a); - asv= ver->svert; + for(a=startvert, asv=asverts; a<totvert; a++, asv++) { if(asv && asv->totface>1) { + ver= RE_findOrAddVert(a); asf= asv->faces.first; while(asf) { @@ -685,11 +694,9 @@ static void autosmooth(int startvert, int startvlak, int degr) /* already made a new vertex within threshold? */ v1= as_findvertex(vlr, ver, asv, thresh); - if(v1==0) { + if(v1==NULL) { /* make a new vertex */ - v1= RE_findOrAddVert(R.totvert++); - *v1= *ver; - v1->svert= 0; + v1= RE_duplicate_vertren(ver); } asf->nver[b]= v1; if(vlr->v1==ver) vlr->v1= v1; @@ -704,11 +711,10 @@ static void autosmooth(int startvert, int startvlak, int degr) } /* free */ - for(a=startvert; a<R.totvert; a++) { - ver= RE_findOrAddVert(a); - if(ver->svert) as_freevert(ver); + for(a=0; a<totvert-startvert; a++) { + BLI_freelistN(&asverts[a].faces); } - + MEM_freeN(asverts); } /* ------------------------------------------------------------------------- */ @@ -1387,7 +1393,7 @@ static void init_render_mesh(Object *ob) unsigned int *vertcol; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *orco=0; - int a, a1, ok, need_orco=0, totvlako, totverto, vertofs; + int a, a1, ok, need_orco=0, need_stress=0, totvlako, totverto, vertofs; int end, do_autosmooth=0, totvert = 0, dm_needsfree; me= ob->data; @@ -1415,10 +1421,10 @@ static void init_render_mesh(Object *ob) for(a=1; a<=ob->totcol; a++) { ma= give_render_material(ob, a); if(ma) { - if(ma->texco & TEXCO_ORCO) { + if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS)) need_orco= 1; - break; - } + if(ma->texco & TEXCO_STRESS) + need_stress= 1; } } @@ -1460,7 +1466,9 @@ static void init_render_mesh(Object *ob) orco+=3; } if(ms) { - ver->sticky= (float *)ms; + float *sticky= RE_vertren_get_sticky(ver, 1); + sticky[0]= ms->co[0]; + sticky[1]= ms->co[1]; ms++; } } @@ -1634,6 +1642,9 @@ static void init_render_mesh(Object *ob) calc_vertexnormals(totverto, totvlako); + if(need_stress) + calc_edge_stress(me, totverto, totvlako); + if(dlm) displistmesh_free(dlm); if(dm_needsfree) dm->release(dm); } @@ -2132,11 +2143,11 @@ static void init_render_curve(Object *ob) if(ver->co[2] < 0.0) { VECCOPY(ver->n, n); - ver->sticky = (float*) 1; + ver->flag = 1; } else { ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2]; - ver->sticky = (float*) 0; + ver->flag = 0; } if (orco) { @@ -2156,7 +2167,7 @@ static void init_render_curve(Object *ob) vlr->v3= RE_findOrAddVert(startvert+index[2]); vlr->v4= NULL; - if(vlr->v1->sticky) { + if(vlr->v1->flag) { VECCOPY(vlr->n, n); } else { @@ -2255,15 +2266,15 @@ static void init_render_curve(Object *ob) for(a=startvert; a<R.totvert; a++) { ver= RE_findOrAddVert(a); len= Normalise(ver->n); - if(len==0.0) ver->sticky= (float *)1; - else ver->sticky= 0; + if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */ + else ver->flag= 1; } for(a= startvlak; a<R.totvlak; a++) { vlr= RE_findOrAddVlak(a); - if(vlr->v1->sticky) VECCOPY(vlr->v1->n, vlr->n); - if(vlr->v2->sticky) VECCOPY(vlr->v2->n, vlr->n); - if(vlr->v3->sticky) VECCOPY(vlr->v3->n, vlr->n); - if(vlr->v4->sticky) VECCOPY(vlr->v4->n, vlr->n); + if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n); + if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n); + if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n); + if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n); } } @@ -2396,13 +2407,8 @@ void RE_freeRotateBlenderScene(void) BLI_freelistN(&R.lights); /* note; these pointer arrays were allocated, with last element NULL to stop loop */ - a=0; - while(R.blove[a]) { - MEM_freeN(R.blove[a]); - R.blove[a]= NULL; - a++; - } - + RE_free_vertex_tables(); + a=0; while(R.blovl[a]) { MEM_freeN(R.blovl[a]); @@ -2615,6 +2621,7 @@ void RE_rotateBlenderScene(void) R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); R.totvlak=R.totvert=R.totlamp=R.tothalo= 0; + R.lights.first= R.lights.last= NULL; slurph_opt= 0; @@ -2914,8 +2921,13 @@ static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale) if ((texco & TEXCO_ORCO) && (vr->orco)) { VECCOPY(shi->lo, vr->orco); } - if ((texco & TEXCO_STICKY) && (vr->sticky)) { - VECCOPY(shi->sticky, vr->sticky); + if (texco & TEXCO_STICKY) { + float *sticky= RE_vertren_get_sticky(vr, 0); + if(sticky) { + shi->sticky[0]= sticky[0]; + shi->sticky[1]= sticky[1]; + shi->sticky[2]= 0.0f; + } } if (texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index d8121fd458f..b697d4cab34 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2857,11 +2857,12 @@ static void material_panel_map_input(Object *ob, Material *ma) /* TEXCO */ uiBlockBeginAlign(block); uiDefButS(block, ROW, B_MATPRV, "UV", 630,166,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Object", 670,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",745,166,163,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "Glob", 670,166,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Object", 715,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",790,166,118,18, &(mtex->object), ""); - uiDefButS(block, ROW, B_MATPRV, "Glob", 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Orco", 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "Orco", 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object"); + uiDefButS(block, ROW, B_MATPRV, "Stress", 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh"); if( give_parteff(ob) ) uiDefButS(block, ROW, B_MATPRV, "Strand", 725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)"); else |