Minor render memory usage optimization, removed layer and

radface from VlakRen, saves about 100mb for 10 million faces.
This commit is contained in:
Brecht Van Lommel 2008-01-23 13:35:51 +00:00
parent d4ae72c7c9
commit 52404cd114
12 changed files with 127 additions and 96 deletions

@ -84,22 +84,23 @@ static float maxenergy;
/* find the face with maximum energy to become shooter */ /* find the face with maximum energy to become shooter */
/* nb: _rr means rad-render version of existing radio call */ /* 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; ObjectRen *obr;
VlakRen *vlr=NULL, *shoot; VlakRen *vlr=NULL, *shoot;
float energy; float energy;
int a; int a;
shoot= NULL; shoot= NULL;
shootrf= NULL;
maxenergy= 0.0; maxenergy= 0.0;
for(obr=re->objecttable.first; obr; obr=obr->next) { for(obr=re->objecttable.first; obr; obr=obr->next) {
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
rf->flag &= ~RAD_SHOOT; rf->flag &= ~RAD_SHOOT;
energy= rf->unshot[0]*rf->area; energy= rf->unshot[0]*rf->area;
@ -108,26 +109,31 @@ static VlakRen *findshoot_rr(Render *re)
if(energy>maxenergy) { if(energy>maxenergy) {
shoot= vlr; shoot= vlr;
shootrf= rf;
maxenergy= energy; maxenergy= energy;
} }
} }
} }
} }
if(shoot) { if(shootrf) {
maxenergy/= RG.totenergy; maxenergy/= RG.totenergy;
if(maxenergy<RG.convergence) return NULL; if(maxenergy<RG.convergence) {
shoot->radface->flag |= RAD_SHOOT; *shoot_p= NULL;
*shootrf_p= NULL;
}
shootrf->flag |= 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; ObjectRen *obr;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace *rf, **radface;
float tvec[3]; float tvec[3];
int a; 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(obr=re->objecttable.first; obr; obr=obr->next) {
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface && vlr!=shoot) { if(vlr != shoot && (radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
VecSubf(tvec, shoot->radface->cent, rf->cent); VecSubf(tvec, shootrf->cent, rf->cent);
if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0) if(tvec[0]*rf->norm[0]+ tvec[1]*rf->norm[1]+ tvec[2]*rf->norm[2] < 0.0)
rf->flag |= RAD_BACKFACE; rf->flag |= RAD_BACKFACE;
@ -150,7 +156,7 @@ static void clear_backface_test_rr(Render *re)
{ {
ObjectRen *obr; ObjectRen *obr;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace *rf, **radface;
int a; int a;
/* backface flag clear */ /* backface flag clear */
@ -158,8 +164,8 @@ static void clear_backface_test_rr(Render *re)
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
rf->flag &= ~RAD_BACKFACE; rf->flag &= ~RAD_BACKFACE;
} }
} }
@ -169,11 +175,11 @@ static void clear_backface_test_rr(Render *re)
extern RadView hemitop, hemiside; // radfactors.c extern RadView hemitop, hemiside; // radfactors.c
/* hemi-zbuffering, delivers formfactors array */ /* 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; ObjectRen *obr;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace *rf, **radface;
float len, vec[3], up[3], side[3], tar[5][3], *fp; float len, vec[3], up[3], side[3], tar[5][3], *fp;
int a; int a;
@ -182,25 +188,25 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
/* set up hemiview */ /* set up hemiview */
/* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */ /* first: upvector for hemitop, we use diagonal hemicubes to prevent aliasing */
VecSubf(vec, shoot->v1->co, shoot->radface->cent); VecSubf(vec, shoot->v1->co, shootrf->cent);
Crossf(up, shoot->radface->norm, vec); Crossf(up, shootrf->norm, vec);
len= Normalize(up); len= Normalize(up);
VECCOPY(hemitop.up, 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 */ /* five targets */
VecAddf(tar[0], shoot->radface->cent, shoot->radface->norm); VecAddf(tar[0], shootrf->cent, shootrf->norm);
VecAddf(tar[1], shoot->radface->cent, up); VecAddf(tar[1], shootrf->cent, up);
VecSubf(tar[2], shoot->radface->cent, up); VecSubf(tar[2], shootrf->cent, up);
VecAddf(tar[3], shoot->radface->cent, side); VecAddf(tar[3], shootrf->cent, side);
VecSubf(tar[4], shoot->radface->cent, side); VecSubf(tar[4], shootrf->cent, side);
/* camera */ /* camera */
VECCOPY(hemiside.cam, shoot->radface->cent); VECCOPY(hemiside.cam, shootrf->cent);
VECCOPY(hemitop.cam, shoot->radface->cent); VECCOPY(hemitop.cam, shootrf->cent);
/* do it! */ /* do it! */
VECCOPY(hemitop.tar, tar[0]); VECCOPY(hemitop.tar, tar[0]);
@ -218,10 +224,10 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
if(*fp!=0.0 && rf->area!=0.0) { 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; if(*fp>1.0) *fp= 1.0001;
} }
fp++; fp++;
@ -231,17 +237,17 @@ static void makeformfactors_rr(Render *re, VlakRen *shoot)
} }
/* based at RG.formfactors array, distribute shoot energy over other faces */ /* 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; ObjectRen *obr;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace *rf, **radface;
float *fp, *ref, unr, ung, unb, r, g, b; float *fp, *ref, unr, ung, unb, r, g, b;
int a; int a;
unr= shoot->radface->unshot[0]; unr= shootrf->unshot[0];
ung= shoot->radface->unshot[1]; ung= shootrf->unshot[1];
unb= shoot->radface->unshot[2]; unb= shootrf->unshot[2];
fp= RG.formfactors; fp= RG.formfactors;
@ -249,8 +255,8 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
if(*fp!= 0.0) { if(*fp!= 0.0) {
ref= &(vlr->mat->r); ref= &(vlr->mat->r);
@ -274,7 +280,7 @@ static void applyformfactors_rr(Render *re, VlakRen *shoot)
} }
} }
/* shoot energy has been shot */ /* 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) static void progressiverad_rr(Render *re)
{ {
VlakRen *shoot; VlakRen *shoot;
RadFace *shootrf;
float unshot[3]; float unshot[3];
int it= 0; int it= 0;
shoot= findshoot_rr(re); findshoot_rr(re, &shoot, &shootrf);
while( shoot ) { while( shoot ) {
/* backfaces receive no energy, but are zbuffered... */ /* backfaces receive no energy, but are zbuffered... */
backface_test_rr(re, shoot); backface_test_rr(re, shoot, shootrf);
/* ...unless it's two sided */ /* ...unless it's two sided */
if(shoot->radface->flag & RAD_TWOSIDED) { if(shootrf->flag & RAD_TWOSIDED) {
VECCOPY(unshot, shoot->radface->unshot); VECCOPY(unshot, shootrf->unshot);
VecMulf(shoot->radface->norm, -1.0); VecMulf(shootrf->norm, -1.0);
makeformfactors_rr(re, shoot); makeformfactors_rr(re, shoot, shootrf);
applyformfactors_rr(re, shoot); applyformfactors_rr(re, shoot, shootrf);
VecMulf(shoot->radface->norm, -1.0); VecMulf(shootrf->norm, -1.0);
VECCOPY(shoot->radface->unshot, unshot); VECCOPY(shootrf->unshot, unshot);
} }
/* hemi-zbuffers */ /* hemi-zbuffers */
makeformfactors_rr(re, shoot); makeformfactors_rr(re, shoot, shootrf);
/* based at RG.formfactors array, distribute shoot energy over other faces */ /* based at RG.formfactors array, distribute shoot energy over other faces */
applyformfactors_rr(re, shoot); applyformfactors_rr(re, shoot, shootrf);
it++; it++;
re->timecursor(it); re->timecursor(it);
@ -314,7 +321,7 @@ static void progressiverad_rr(Render *re)
if(re->test_break()) break; if(re->test_break()) break;
if(RG.maxiter && RG.maxiter<=it) 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); printf(" Unshot energy:%f\n", 1000.0*maxenergy);
@ -327,7 +334,7 @@ static void initradfaces(Render *re)
{ {
ObjectRen *obr; ObjectRen *obr;
VlakRen *vlr= NULL; VlakRen *vlr= NULL;
RadFace *rf; RadFace *rf, **radface;
int a, b; int a, b;
/* globals */ /* 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) // uncommented; this isnt satisfying, but i leave it in the code for now (ton)
// if(vlr->mat->translucency!=0.0) rf->flag |= RAD_TWOSIDED; // 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; ObjectRen *obr;
VertRen *v1=NULL; VertRen *v1=NULL;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace *rf, **radface;
float *col; float *col;
int a; int a;
@ -440,8 +448,8 @@ static void make_vertex_rad_values(Render *re)
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
/* apply correction */ /* apply correction */
rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma); rf->totrad[0]= RG.radfactor*pow( rf->totrad[0], RG.igamma);

@ -244,7 +244,7 @@ typedef struct ObjectRen {
struct ObjectRen *next, *prev; struct ObjectRen *next, *prev;
struct Object *ob, *par; struct Object *ob, *par;
struct Scene *sce; struct Scene *sce;
int index, psysindex, flag; int index, psysindex, flag, lay;
int totvert, totvlak, totstrand, tothalo; int totvert, totvlak, totstrand, tothalo;
int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen; int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen;
@ -309,12 +309,10 @@ typedef struct RadFace {
typedef struct VlakRen { typedef struct VlakRen {
struct VertRen *v1, *v2, *v3, *v4; /* keep in order for ** addressing */ struct VertRen *v1, *v2, *v3, *v4; /* keep in order for ** addressing */
unsigned int lay;
float n[3]; float n[3];
struct Material *mat; struct Material *mat;
char puno; char puno;
char flag, ec; char flag, ec;
RadFace *radface;
int index; int index;
} VlakRen; } VlakRen;

@ -42,6 +42,7 @@ struct CustomData;
struct StrandBuffer; struct StrandBuffer;
struct StrandRen; struct StrandRen;
struct ObjectInstanceRen; struct ObjectInstanceRen;
struct RadFace;
#define RE_QUAD_MASK 0x7FFFFFF #define RE_QUAD_MASK 0x7FFFFFF
#define RE_QUAD_OFFS 0x8000000 #define RE_QUAD_OFFS 0x8000000
@ -63,6 +64,7 @@ typedef struct VlakTableNode {
struct MCol *mcol; struct MCol *mcol;
int totmtface, totmcol; int totmtface, totmcol;
float *surfnor; float *surfnor;
struct RadFace **radface;
} VlakTableNode; } VlakTableNode;
typedef struct StrandTableNode { 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 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 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]); 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_makeRenderInstances(struct Render *re);
void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor); 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 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); 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); 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); 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); float *RE_strandren_get_surfnor(struct ObjectRen *obr, struct StrandRen *strand, int verify);

@ -230,7 +230,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
} }
if(re) /* add render object for stars */ 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 (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) {
for (y = sy, fy = sy * stargrid; y <= ey ; y++, fy += 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->mat= ma;
vlr->ec= ME_V2V3; vlr->ec= ME_V2V3;
vlr->lay= obr->ob->lay;
if(surfnor) { if(surfnor) {
float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); 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->mat= ma;
vlr->ec= ME_V2V3; vlr->ec= ME_V2V3;
vlr->lay= obr->ob->lay;
if(surfnor) { if(surfnor) {
float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); 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->mat= ma;
vlr->ec= ME_V1V2; vlr->ec= ME_V1V2;
vlr->lay= obr->ob->lay;
} }
else if(first) { else if(first) {
@ -1267,7 +1264,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
vlr->mat= ma; vlr->mat= ma;
vlr->ec= ME_V1V2; 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->mat= ma;
vlr->ec= ME_V2V3; vlr->ec= ME_V2V3;
vlr->lay= obr->ob->lay;
if(uv_split>1){ if(uv_split>1){
uvdx=uvdy=1.0f/(float)uv_split; uvdx=uvdy=1.0f/(float)uv_split;
@ -2304,7 +2299,6 @@ static void init_render_mball(Render *re, ObjectRen *obr)
vlr->mat= ma; vlr->mat= ma;
vlr->flag= ME_SMOOTH+R_NOPUNOFLIP; vlr->flag= ME_SMOOTH+R_NOPUNOFLIP;
vlr->ec= 0; vlr->ec= 0;
vlr->lay= ob->lay;
/* mball -too bad- always has triangles, because quads can be non-planar */ /* mball -too bad- always has triangles, because quads can be non-planar */
if(index[3] && index[3]!=index[2]) { 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); flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
VECCOPY(vlr->n, n1); VECCOPY(vlr->n, n1);
vlr->lay= ob->lay;
vlr->mat= matar[ dl->col]; vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3; vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt; 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->flag |= R_NOPUNOFLIP;
} }
vlr->ec= 0; 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; if(a==0) vlr->ec+= ME_V1V2;
vlr->flag= dl->rt; vlr->flag= dl->rt;
vlr->lay= ob->lay;
/* this is not really scientific: the vertices /* this is not really scientific: the vertices
* 2, 3 en 4 seem to give better vertexnormals than 1 2 3: * 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->flag |= R_NOPUNOFLIP;
} }
vlr->ec= 0; /* mesh edges rendered separately */ vlr->ec= 0; /* mesh edges rendered separately */
vlr->lay= ob->lay;
if(len==0) obr->totvlak--; if(len==0) obr->totvlak--;
else { else {
@ -3176,7 +3166,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
vlr->mat= ma; vlr->mat= ma;
vlr->flag= 0; vlr->flag= 0;
vlr->ec= ME_V1V2; vlr->ec= ME_V1V2;
vlr->lay= ob->lay;
} }
} }
if(edgetable) 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 */ /* one render object for the data itself */
if(allow_render) { if(allow_render) {
obr= RE_addRenderObject(re, ob, par, index, 0); obr= RE_addRenderObject(re, ob, par, index, 0, ob->lay);
if(instanceable) { if(instanceable) {
obr->flag |= R_INSTANCEABLE; obr->flag |= R_INSTANCEABLE;
Mat4CpyMat4(obr->obmat, ob->obmat); 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) { if(ob->particlesystem.first) {
psysindex= 1; psysindex= 1;
for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { 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) { if(instanceable) {
obr->flag |= R_INSTANCEABLE; obr->flag |= R_INSTANCEABLE;
Mat4CpyMat4(obr->obmat, ob->obmat); Mat4CpyMat4(obr->obmat, ob->obmat);

@ -313,14 +313,15 @@ static void env_layerflags(Render *re, unsigned int notlay)
notlay= ~notlay; notlay= ~notlay;
for(obr=re->objecttable.first; obr; obr=obr->next) { for(obr=re->objecttable.first; obr; obr=obr->next) {
if((obr->lay & notlay)==0) {
for(a=0; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak;
else vlr++; else vlr++;
if((vlr->lay & notlay)==0)
vlr->flag |= R_HIDDEN; vlr->flag |= R_HIDDEN;
} }
} }
}
} }
static void env_hideobject(Render *re, Object *ob) static void env_hideobject(Render *re, Object *ob)

@ -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) static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
{ {
ObjectInstanceRen *obi= RAY_OBJECT_GET((Render*)is->userdata, ob);
VlakRen *vlr = (VlakRen*)face; VlakRen *vlr = (VlakRen*)face;
/* I know... cpu cycle waste, might do smarter once */ /* I know... cpu cycle waste, might do smarter once */
if(is->mode==RE_RAY_MIRROR) if(is->mode==RE_RAY_MIRROR)
return !(vlr->mat->mode & MA_ONLYCAST); return !(vlr->mat->mode & MA_ONLYCAST);
else else
return (is->lay & vlr->lay); return (is->lay & obi->obr->lay);
} }
static float *vlr_get_transform(void *userdata, int i) static float *vlr_get_transform(void *userdata, int i)

@ -1722,6 +1722,8 @@ void add_halo_flare(Render *re)
void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr) void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
{ {
static VlakRen vlr; static VlakRen vlr;
static ObjectRen obr;
static ObjectInstanceRen obi;
/* init */ /* init */
if(re) { if(re) {
@ -1729,11 +1731,16 @@ void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
/* fake render face */ /* fake render face */
memset(&vlr, 0, sizeof(VlakRen)); 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; return;
} }
shi->vlr= &vlr; shi->vlr= &vlr;
shi->obr= &obr;
shi->obi= &obi;
if(shi->mat->nodetree && shi->mat->use_nodes) if(shi->mat->nodetree && shi->mat->use_nodes)
ntreeShaderExecTree(shi->mat->nodetree, shi, shr); ntreeShaderExecTree(shi->mat->nodetree, shi, shr);

@ -104,6 +104,7 @@
#define RE_MCOL_ELEMS 4 #define RE_MCOL_ELEMS 4
#define RE_UV_ELEMS 2 #define RE_UV_ELEMS 2
#define RE_SURFNOR_ELEMS 3 #define RE_SURFNOR_ELEMS 3
#define RE_RADFACE_ELEMS 1
#define RE_SIMPLIFY_ELEMS 2 #define RE_SIMPLIFY_ELEMS 2
#define RE_FACE_ELEMS 1 #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; 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 *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
{ {
VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++); VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
MTFace *mtface, *mtface1; MTFace *mtface, *mtface1;
MCol *mcol, *mcol1; MCol *mcol, *mcol1;
float *surfnor, *surfnor1; float *surfnor, *surfnor1;
RadFace **radface, **radface1;
int i, index = vlr1->index; int i, index = vlr1->index;
char *name; char *name;
@ -391,6 +408,12 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
VECCOPY(surfnor1, surfnor); 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; 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"); 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->par= par;
obr->index= index; obr->index= index;
obr->psysindex= psysindex; obr->psysindex= psysindex;
obr->lay= lay;
return obr; return obr;
} }
@ -749,6 +773,8 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
MEM_freeN(vlaknodes[a].mcol); MEM_freeN(vlaknodes[a].mcol);
if(vlaknodes[a].surfnor) if(vlaknodes[a].surfnor)
MEM_freeN(vlaknodes[a].surfnor); MEM_freeN(vlaknodes[a].surfnor);
if(vlaknodes[a].radface)
MEM_freeN(vlaknodes[a].radface);
} }
MEM_freeN(vlaknodes); MEM_freeN(vlaknodes);

@ -325,7 +325,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar)
if((ma->mode & MA_SHADBUF)==0) ok= 0; 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->v1->index]= 1;
clipflag[vlr->v2->index]= 1; clipflag[vlr->v2->index]= 1;
clipflag[vlr->v3->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; zspanstrand.shad_alpha= zspan.shad_alpha= ma->shad_alpha;
} }
if(ok && (vlr->lay & lay)) { if(ok && (obr->lay & lay)) {
float hoco[4][4]; float hoco[4][4];
int c1, c2, c3, c4=0; int c1, c2, c3, c4=0;
int d1, d2, d3, d4=0; int d1, d2, d3, d4=0;

@ -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->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) {
if(lar->mode & LA_LAYER) if(lar->mode & LA_LAYER)
if(shi->vlr && (lar->lay & shi->vlr->lay)==0) if(shi->vlr && (lar->lay & shi->obr->lay)==0)
continue; continue;
if((lar->lay & shi->lay)==0) if((lar->lay & shi->lay)==0)
continue; 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 */ /* yafray: ignore shading by photonlights, not used in Blender */
if (lar->type==LA_YF_PHOTON) continue; 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->lay & shi->lay)==0) continue;
if(lar->shb || (lar->mode & LA_SHAD_RAY)) { 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) void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
{ {
Material *ma= shi->mat; Material *ma= shi->mat;
VlakRen *vlr= shi->vlr;
int passflag= shi->passflag; int passflag= shi->passflag;
memset(shr, 0, sizeof(ShadeResult)); memset(shr, 0, sizeof(ShadeResult));
@ -1597,7 +1596,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if (lar->type==LA_YF_PHOTON) continue; if (lar->type==LA_YF_PHOTON) continue;
/* test for lamp layer */ /* 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; if((lar->lay & shi->lay)==0) continue;
/* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */ /* accumulates in shr->diff and shr->spec and shr->shad (diffuse with shadow!) */

@ -686,7 +686,6 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
memset(&vlr, 0, sizeof(vlr)); memset(&vlr, 0, sizeof(vlr));
vlr.flag= R_SMOOTH; vlr.flag= R_SMOOTH;
vlr.lay= sseg->strand->buffer->lay;
if(sseg->buffer->ma->mode & MA_TANGENT_STR) if(sseg->buffer->ma->mode & MA_TANGENT_STR)
vlr.flag |= R_TANGENT; vlr.flag |= R_TANGENT;

@ -2003,7 +2003,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu
else vlr++; else vlr++;
/* three cases, visible for render, only z values and nothing */ /* three cases, visible for render, only z values and nothing */
if(vlr->lay & lay) { if(obr->lay & lay) {
if(vlr->mat!=ma) { if(vlr->mat!=ma) {
ma= vlr->mat; ma= vlr->mat;
nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST); 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 */ else { /* radio render */
ObjectRen *obr; ObjectRen *obr;
VlakRen *vlr=NULL; VlakRen *vlr=NULL;
RadFace *rf; RadFace **radface, *rf;
int totface=0; int totface=0;
/* note: radio render doesn't support duplis */ /* 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; a<obr->totvlak; a++) { for(a=0; a<obr->totvlak; a++) {
if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++; if((a & 255)==0) vlr= obr->vlaknodes[a>>8].vlak; else vlr++;
if(vlr->radface) { if((radface=RE_vlakren_get_radface(obr, vlr, 0))) {
rf= vlr->radface; rf= *radface;
if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */ if( (rf->flag & RAD_SHOOT)==0 ) { /* no shootelement */
if( rf->flag & RAD_TWOSIDED) zvlnr= totface; 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((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); 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); 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); 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)) { if(material_in_material(vlr->mat, sss_ma)) {
/* three cases, visible for render, only z values and nothing */ /* three cases, visible for render, only z values and nothing */
if(vlr->lay & lay) { if(obr->lay & lay) {
if(vlr->mat!=ma) { if(vlr->mat!=ma) {
ma= vlr->mat; ma= vlr->mat;
nofill= ma->mode & MA_ONLYCAST; nofill= ma->mode & MA_ONLYCAST;
@ -3214,7 +3214,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
} }
if(dofill) { if(dofill) {
if(!(vlr->flag & R_HIDDEN) && (vlr->lay & lay)) { if(!(vlr->flag & R_HIDDEN) && (obr->lay & lay)) {
unsigned short partclip; unsigned short partclip;
v1= vlr->v1; v1= vlr->v1;