diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c index ee52956bbd2..52e2b46d506 100644 --- a/source/blender/radiosity/intern/source/radrender.c +++ b/source/blender/radiosity/intern/source/radrender.c @@ -84,22 +84,23 @@ static float maxenergy; /* find the face with maximum energy to become shooter */ /* nb: _rr means rad-render version of existing radio call */ -static VlakRen *findshoot_rr(Render *re) +static void findshoot_rr(Render *re, VlakRen **shoot_p, RadFace **shootrf_p) { - RadFace *rf; + RadFace *rf, *shootrf, **radface; ObjectRen *obr; VlakRen *vlr=NULL, *shoot; float energy; int a; shoot= NULL; + shootrf= NULL; maxenergy= 0.0; for(obr=re->objecttable.first; obr; obr=obr->next) { for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; rf->flag &= ~RAD_SHOOT; energy= rf->unshot[0]*rf->area; @@ -108,26 +109,31 @@ static VlakRen *findshoot_rr(Render *re) if(energy>maxenergy) { shoot= vlr; + shootrf= rf; maxenergy= energy; } } } } - if(shoot) { + if(shootrf) { maxenergy/= RG.totenergy; - if(maxenergyradface->flag |= RAD_SHOOT; + if(maxenergyflag |= RAD_SHOOT; } - return shoot; + *shoot_p= shoot; + *shootrf_p= shootrf; } -static void backface_test_rr(Render *re, VlakRen *shoot) +static void backface_test_rr(Render *re, VlakRen *shoot, RadFace *shootrf) { ObjectRen *obr; VlakRen *vlr=NULL; - RadFace *rf; + RadFace *rf, **radface; float tvec[3]; int a; @@ -135,9 +141,9 @@ static void backface_test_rr(Render *re, VlakRen *shoot) for(obr=re->objecttable.first; obr; obr=obr->next) { for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface && vlr!=shoot) { - rf= vlr->radface; - VecSubf(tvec, shoot->radface->cent, rf->cent); + if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; + VecSubf(tvec, shootrf->cent, rf->cent); if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) rf->flag |= RAD_BACKFACE; @@ -150,7 +156,7 @@ static void clear_backface_test_rr(Render *re) { ObjectRen *obr; VlakRen *vlr=NULL; - RadFace *rf; + RadFace *rf, **radface; int a; /* backface flag clear */ @@ -158,8 +164,8 @@ static void clear_backface_test_rr(Render *re) for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; rf->flag &= ~RAD_BACKFACE; } } @@ -169,11 +175,11 @@ static void clear_backface_test_rr(Render *re) extern RadView hemitop, hemiside; // radfactors.c /* hemi-zbuffering, delivers formfactors array */ -static void makeformfactors_rr(Render *re, VlakRen *shoot) +static void makeformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) { ObjectRen *obr; VlakRen *vlr=NULL; - RadFace *rf; + RadFace *rf, **radface; float len, vec[3], up[3], side[3], tar[5][3], *fp; int a; @@ -182,25 +188,25 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot) /* set up hemiview */ /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */ - VecSubf(vec, shoot->v1->co, shoot->radface->cent); - Crossf(up, shoot->radface->norm, vec); + VecSubf(vec, shoot->v1->co, shootrf->cent); + Crossf(up, shootrf->norm, vec); len= Normalize(up); VECCOPY(hemitop.up, up); - VECCOPY(hemiside.up, shoot->radface->norm); + VECCOPY(hemiside.up, shootrf->norm); - Crossf(side, shoot->radface->norm, up); + Crossf(side, shootrf->norm, up); /* five targets */ - VecAddf(tar[0], shoot->radface->cent, shoot->radface->norm); - VecAddf(tar[1], shoot->radface->cent, up); - VecSubf(tar[2], shoot->radface->cent, up); - VecAddf(tar[3], shoot->radface->cent, side); - VecSubf(tar[4], shoot->radface->cent, side); + VecAddf(tar[0], shootrf->cent, shootrf->norm); + VecAddf(tar[1], shootrf->cent, up); + VecSubf(tar[2], shootrf->cent, up); + VecAddf(tar[3], shootrf->cent, side); + VecSubf(tar[4], shootrf->cent, side); /* camera */ - VECCOPY(hemiside.cam, shoot->radface->cent); - VECCOPY(hemitop.cam, shoot->radface->cent); + VECCOPY(hemiside.cam, shootrf->cent); + VECCOPY(hemitop.cam, shootrf->cent); /* do it! */ VECCOPY(hemitop.tar, tar[0]); @@ -218,10 +224,10 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot) for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; if(*fp!=0.0 && rf->area!=0.0) { - *fp *= shoot->radface->area/rf->area; + *fp *= shootrf->area/rf->area; if(*fp>1.0) *fp= 1.0001; } fp++; @@ -231,17 +237,17 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot) } /* based at RG.formfactors array, distribute shoot energy over other faces */ -static void applyformfactors_rr(Render *re, VlakRen *shoot) +static void applyformfactors_rr(Render *re, VlakRen *shoot, RadFace *shootrf) { ObjectRen *obr; VlakRen *vlr=NULL; - RadFace *rf; + RadFace *rf, **radface; float *fp, *ref, unr, ung, unb, r, g, b; int a; - unr= shoot->radface->unshot[0]; - ung= shoot->radface->unshot[1]; - unb= shoot->radface->unshot[2]; + unr= shootrf->unshot[0]; + ung= shootrf->unshot[1]; + unb= shootrf->unshot[2]; fp= RG.formfactors; @@ -249,8 +255,8 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot) for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; if(*fp!= 0.0) { ref= &(vlr->mat->r); @@ -274,7 +280,7 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot) } } /* shoot energy has been shot */ - shoot->radface->unshot[0]= shoot->radface->unshot[1]= shoot->radface->unshot[2]= 0.0; + shootrf->unshot[0]= shootrf->unshot[1]= shootrf->unshot[2]= 0.0; } @@ -282,29 +288,30 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot) static void progressiverad_rr(Render *re) { VlakRen *shoot; + RadFace *shootrf; float unshot[3]; int it= 0; - shoot= findshoot_rr(re); + findshoot_rr(re, &shoot, &shootrf); while( shoot ) { /* backfaces receive no energy, but are zbuffered... */ - backface_test_rr(re, shoot); + backface_test_rr(re, shoot, shootrf); /* ...unless it's two sided */ - if(shoot->radface->flag & RAD_TWOSIDED) { - VECCOPY(unshot, shoot->radface->unshot); - VecMulf(shoot->radface->norm, -1.0); - makeformfactors_rr(re, shoot); - applyformfactors_rr(re, shoot); - VecMulf(shoot->radface->norm, -1.0); - VECCOPY(shoot->radface->unshot, unshot); + if(shootrf->flag & RAD_TWOSIDED) { + VECCOPY(unshot, shootrf->unshot); + VecMulf(shootrf->norm, -1.0); + makeformfactors_rr(re, shoot, shootrf); + applyformfactors_rr(re, shoot, shootrf); + VecMulf(shootrf->norm, -1.0); + VECCOPY(shootrf->unshot, unshot); } /* hemi-zbuffers */ - makeformfactors_rr(re, shoot); + makeformfactors_rr(re, shoot, shootrf); /* based at RG.formfactors array, distribute shoot energy over other faces */ - applyformfactors_rr(re, shoot); + applyformfactors_rr(re, shoot, shootrf); it++; re->timecursor(it); @@ -314,7 +321,7 @@ static void progressiverad_rr(Render *re) if(re->test_break()) break; if(RG.maxiter && RG.maxiter<=it) break; - shoot= findshoot_rr(re); + findshoot_rr(re, &shoot, &shootrf); } printf(" Unshot energy:%f\n", 1000.0*maxenergy); @@ -327,7 +334,7 @@ static void initradfaces(Render *re) { ObjectRen *obr; VlakRen *vlr= NULL; - RadFace *rf; + RadFace *rf, **radface; int a, b; /* globals */ @@ -393,7 +400,8 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); // uncommented; this isnt satisfying, but i leave it in the code for now (ton) // if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED; - vlr->radface= rf++; + radface=RE_vlakren_get_radface(obr, vlr, 1); + *radface= rf++; } } } @@ -428,7 +436,7 @@ static void make_vertex_rad_values(Render *re) ObjectRen *obr; VertRen *v1=NULL; VlakRen *vlr=NULL; - RadFace *rf; + RadFace *rf, **radface; float *col; int a; @@ -440,8 +448,8 @@ static void make_vertex_rad_values(Render *re) for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; /* apply correction */ rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 05d8324dfc6..46b5face22a 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -244,7 +244,7 @@ typedef struct ObjectRen { struct ObjectRen *next, *prev; struct Object *ob, *par; struct Scene *sce; - int index, psysindex, flag; + int index, psysindex, flag, lay; int totvert, totvlak, totstrand, tothalo; int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen; @@ -309,12 +309,10 @@ typedef struct RadFace { typedef struct VlakRen { struct VertRen *v1, *v2, *v3, *v4; /* keep in order for ** addressing */ - unsigned int lay; float n[3]; struct Material *mat; char puno; char flag, ec; - RadFace *radface; int index; } VlakRen; diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index a74579acc4a..cfcbb4e7775 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -42,6 +42,7 @@ struct CustomData; struct StrandBuffer; struct StrandRen; struct ObjectInstanceRen; +struct RadFace; #define RE_QUAD_MASK 0x7FFFFFF #define RE_QUAD_OFFS 0x8000000 @@ -63,6 +64,7 @@ typedef struct VlakTableNode { struct MCol *mcol; int totmtface, totmcol; float *surfnor; + struct RadFace **radface; } VlakTableNode; typedef struct StrandTableNode { @@ -94,7 +96,7 @@ struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Mat struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma, float *vec, float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed); struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert); -struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex); +struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay); struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]); void RE_makeRenderInstances(struct Render *re); void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor); @@ -109,6 +111,7 @@ float *RE_vertren_get_winspeed(struct ObjectInstanceRen *obi, struct VertRen *ve struct MTFace *RE_vlakren_get_tface(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify); struct MCol *RE_vlakren_get_mcol(struct ObjectRen *obr, VlakRen *ren, int n, char **name, int verify); float *RE_vlakren_get_surfnor(struct ObjectRen *obr, VlakRen *ren, int verify); +RadFace **RE_vlakren_get_radface(struct ObjectRen *obr, VlakRen *ren, int verify); int RE_vlakren_get_normal(struct Render *re, struct ObjectInstanceRen *obi, struct VlakRen *vlr, float *nor); float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index de87d2c8cd9..69ae280dc4c 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -230,7 +230,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void), } if(re) /* add render object for stars */ - obr= RE_addRenderObject(re, NULL, NULL, 0, 0); + obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0); for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) { for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += stargrid) { @@ -1075,7 +1075,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - vlr->lay= obr->ob->lay; if(surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); @@ -1192,7 +1191,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - vlr->lay= obr->ob->lay; if(surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); @@ -1244,7 +1242,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float vlr->mat= ma; vlr->ec= ME_V1V2; - vlr->lay= obr->ob->lay; } else if(first) { @@ -1267,7 +1264,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float vlr->mat= ma; vlr->ec= ME_V1V2; - vlr->lay= obr->ob->lay; } } @@ -1366,7 +1362,6 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object vlr->mat= ma; vlr->ec= ME_V2V3; - vlr->lay= obr->ob->lay; if(uv_split>1){ uvdx=uvdy=1.0f/(float)uv_split; @@ -2304,7 +2299,6 @@ static void init_render_mball(Render *re, ObjectRen *obr) vlr->mat= ma; vlr->flag= ME_SMOOTH+R_NOPUNOFLIP; vlr->ec= 0; - vlr->lay= ob->lay; /* mball -too bad- always has triangles, because quads can be non-planar */ if(index[3] && index[3]!=index[2]) { @@ -2418,7 +2412,6 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar, flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1); VECCOPY(vlr->n, n1); - vlr->lay= ob->lay; vlr->mat= matar[ dl->col]; vlr->ec= ME_V1V2+ME_V2V3; vlr->flag= dl->rt; @@ -2652,7 +2645,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts) vlr->flag |= R_NOPUNOFLIP; } vlr->ec= 0; - vlr->lay= ob->lay; } } } @@ -2705,7 +2697,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts) if(a==0) vlr->ec+= ME_V1V2; vlr->flag= dl->rt; - vlr->lay= ob->lay; /* this is not really scientific: the vertices * 2, 3 en 4 seem to give better vertexnormals than 1 2 3: @@ -3105,7 +3096,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts) vlr->flag |= R_NOPUNOFLIP; } vlr->ec= 0; /* mesh edges rendered separately */ - vlr->lay= ob->lay; if(len==0) obr->totvlak--; else { @@ -3176,7 +3166,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts) vlr->mat= ma; vlr->flag= 0; vlr->ec= ME_V1V2; - vlr->lay= ob->lay; } } if(edgetable) @@ -4006,7 +3995,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in /* one render object for the data itself */ if(allow_render) { - obr= RE_addRenderObject(re, ob, par, index, 0); + obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay); if(instanceable) { obr->flag |= R_INSTANCEABLE; Mat4CpyMat4(obr->obmat, ob->obmat); @@ -4024,7 +4013,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in if(ob->particlesystem.first) { psysindex= 1; for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { - obr= RE_addRenderObject(re, ob, par, index, psysindex); + obr= RE_addRenderObject(re, ob, par, index, psysindex, ob->lay); if(instanceable) { obr->flag |= R_INSTANCEABLE; Mat4CpyMat4(obr->obmat, ob->obmat); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index b1b907aebb6..6d93d91ae97 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -313,12 +313,13 @@ static void env_layerflags(Render *re, unsigned int notlay) notlay= ~notlay; for(obr=re->objecttable.first; obr; obr=obr->next) { - for(a=0; atotvlak; a++) { - if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; - else vlr++; + if((obr->lay & notlay)==0) { + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; + else vlr++; - if((vlr->lay & notlay)==0) vlr->flag |= R_HIDDEN; + } } } } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index b7541bcbd74..218f5fe931e 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -79,13 +79,14 @@ static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, f static int vlr_check_intersect(Isect *is, int ob, RayFace *face) { + ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob); VlakRen *vlr = (VlakRen*)face; /* I know... cpu cycle waste, might do smarter once */ if(is->mode==RE_RAY_MIRROR) return !(vlr->mat->mode & MA_ONLYCAST); else - return (is->lay & vlr->lay); + return (is->lay & obi->obr->lay); } static float *vlr_get_transform(void *userdata, int i) diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 46f94c81c63..be96fe8f794 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1722,6 +1722,8 @@ void add_halo_flare(Render *re) void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr) { static VlakRen vlr; + static ObjectRen obr; + static ObjectInstanceRen obi; /* init */ if(re) { @@ -1729,11 +1731,16 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr) /* fake render face */ memset(&vlr, 0, sizeof(VlakRen)); - vlr.lay= -1; + memset(&obr, 0, sizeof(ObjectRen)); + memset(&obi, 0, sizeof(ObjectInstanceRen)); + obr.lay= -1; + obi.obr= &obr; return; } shi->vlr= &vlr; + shi->obr= &obr; + shi->obi= &obi; if(shi->mat->nodetree && shi->mat->use_nodes) ntreeShaderExecTree(shi->mat->nodetree, shi, shr); diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 8aaf29b65c4..27daad9dc26 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -104,6 +104,7 @@ #define RE_MCOL_ELEMS 4 #define RE_UV_ELEMS 2 #define RE_SURFNOR_ELEMS 3 +#define RE_RADFACE_ELEMS 1 #define RE_SIMPLIFY_ELEMS 2 #define RE_FACE_ELEMS 1 @@ -363,12 +364,28 @@ float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify) return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS; } +RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify) +{ + RadFace **radface; + int nr= vlak->index>>8; + + radface= obr->vlaknodes[nr].radface; + if(radface==NULL) { + if(verify) + radface= obr->vlaknodes[nr].radface= MEM_callocN(256*RE_RADFACE_ELEMS*sizeof(void*), "radface table"); + else + return NULL; + } + return radface + (vlak->index & 255)*RE_RADFACE_ELEMS; +} + VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) { VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++); MTFace *mtface, *mtface1; MCol *mcol, *mcol1; float *surfnor, *surfnor1; + RadFace **radface, **radface1; int i, index = vlr1->index; char *name; @@ -391,6 +408,12 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr) VECCOPY(surfnor1, surfnor); } + radface= RE_vlakren_get_radface(obr, vlr, 0); + if(radface) { + radface1= RE_vlakren_get_radface(obr, vlr1, 1); + *radface1= *radface; + } + return vlr1; } @@ -695,7 +718,7 @@ StrandBuffer *RE_addStrandBuffer(ObjectRen *obr, int totvert) /* ------------------------------------------------------------------------ */ -ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex) +ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, int psysindex, int lay) { ObjectRen *obr= MEM_callocN(sizeof(ObjectRen), "object render struct"); @@ -704,6 +727,7 @@ ObjectRen *RE_addRenderObject(Render *re, Object *ob, Object *par, int index, in obr->par= par; obr->index= index; obr->psysindex= psysindex; + obr->lay= lay; return obr; } @@ -749,6 +773,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes) MEM_freeN(vlaknodes[a].mcol); if(vlaknodes[a].surfnor) MEM_freeN(vlaknodes[a].surfnor); + if(vlaknodes[a].radface) + MEM_freeN(vlaknodes[a].radface); } MEM_freeN(vlaknodes); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 42086d078f6..fcd9220df0e 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -325,7 +325,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) if((ma->mode & MA_SHADBUF)==0) ok= 0; } - if(ok && (vlr->lay & lay)) { + if(ok && (obr->lay & lay)) { clipflag[vlr->v1->index]= 1; clipflag[vlr->v2->index]= 1; clipflag[vlr->v3->index]= 1; @@ -1558,7 +1558,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha; } - if(ok && (vlr->lay & lay)) { + if(ok && (obr->lay & lay)) { float hoco[4][4]; int c1, c2, c3, c4=0; int d1, d2, d3, d4=0; diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 1498683baab..8af98158981 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -355,7 +355,7 @@ void renderspothalo(ShadeInput *shi, float *col, float alpha) if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) { if(lar->mode & LA_LAYER) - if(shi->vlr && (lar->lay & shi->vlr->lay)==0) + if(shi->vlr && (lar->lay & shi->obr->lay)==0) continue; if((lar->lay & shi->lay)==0) continue; @@ -1460,7 +1460,7 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) /* yafray: ignore shading by photonlights, not used in Blender */ if (lar->type==LA_YF_PHOTON) continue; - if(lar->mode & LA_LAYER) if((lar->lay & shi->vlr->lay)==0) continue; + if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue; if((lar->lay & shi->lay)==0) continue; if(lar->shb || (lar->mode & LA_SHAD_RAY)) { @@ -1520,7 +1520,6 @@ static void wrld_exposure_correct(float *diff) void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) { Material *ma= shi->mat; - VlakRen *vlr= shi->vlr; int passflag= shi->passflag; memset(shr, 0, sizeof(ShadeResult)); @@ -1597,7 +1596,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if (lar->type==LA_YF_PHOTON) continue; /* test for lamp layer */ - if(lar->mode & LA_LAYER) if((lar->lay & vlr->lay)==0) continue; + if(lar->mode & LA_LAYER) if((lar->lay & shi->obr->lay)==0) continue; if((lar->lay & shi->lay)==0) continue; /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */ diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 3a4f44b11d3..7a3e4432872 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -686,7 +686,6 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss memset(&vlr, 0, sizeof(vlr)); vlr.flag= R_SMOOTH; - vlr.lay= sseg->strand->buffer->lay; if(sseg->buffer->ma->mode & MA_TANGENT_STR) vlr.flag |= R_TANGENT; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 2ad1f6bac53..3dcefbfdca0 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2003,7 +2003,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu else vlr++; /* three cases, visible for render, only z values and nothing */ - if(vlr->lay & lay) { + if(obr->lay & lay) { if(vlr->mat!=ma) { ma= vlr->mat; nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST); @@ -2191,7 +2191,7 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re else { /* radio render */ ObjectRen *obr; VlakRen *vlr=NULL; - RadFace *rf; + RadFace **radface, *rf; int totface=0; /* note: radio render doesn't support duplis */ @@ -2201,8 +2201,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re for(a=0; atotvlak; a++) { if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; - if(vlr->radface) { - rf= vlr->radface; + if((radface=RE_vlakren_get_radface(obr, vlr, 0))) { + rf= *radface; if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */ if( rf->flag & RAD_TWOSIDED) zvlnr= totface; @@ -2293,7 +2293,7 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int if((ma->mode & MA_SHADBUF)==0) ok= 0; } - if(ok && (vlr->lay & lay) && !(vlr->flag & R_HIDDEN)) { + if(ok && (obr->lay & lay) && !(vlr->flag & R_HIDDEN)) { c1= zbuf_shadow_project(cache, vlr->v1->index, obwinmat, vlr->v1->co, ho1); c2= zbuf_shadow_project(cache, vlr->v2->index, obwinmat, vlr->v2->co, ho2); c3= zbuf_shadow_project(cache, vlr->v3->index, obwinmat, vlr->v3->co, ho3); @@ -2508,7 +2508,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo if(material_in_material(vlr->mat, sss_ma)) { /* three cases, visible for render, only z values and nothing */ - if(vlr->lay & lay) { + if(obr->lay & lay) { if(vlr->mat!=ma) { ma= vlr->mat; nofill= ma->mode & MA_ONLYCAST; @@ -3214,7 +3214,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un } if(dofill) { - if(!(vlr->flag & R_HIDDEN) && (vlr->lay & lay)) { + if(!(vlr->flag & R_HIDDEN) && (obr->lay & lay)) { unsigned short partclip; v1= vlr->v1;