Fix for error in approximate AO in last commit, made it really slow.

Also, duplis are now taking into account, the proper way to exclude
them is to set the material to be not traceable.

Removed an unnecessary pointer from the VlakRen struct to save some
memory, not really that significant, but still, saves 70 mb for 10
million faces.
This commit is contained in:
Brecht Van Lommel 2008-01-21 23:17:19 +00:00
parent 9f3f546a6f
commit ec04c09365
17 changed files with 100 additions and 80 deletions

@ -2058,6 +2058,47 @@ static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
/************************************************/ /************************************************/
/* Effectors */ /* Effectors */
/************************************************/ /************************************************/
static float particle_falloff(PartDeflect *pd, float fac)
{
float mindist= (pd->flag & PFIELD_USEMIN)? pd->mindist: 0.0f;
#if 0
if(distance<=mindist) fallof= 1.0f;
else if(pd->flag & PFIELD_USEMAX) {
if(distance>pd->maxdist || mindist>=pd->maxdist) fallof= 0.0f;
else {
fallof= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
if(ffall_val!=0.0f)
fallof = (float)pow(fallof, ffall_val+1.0);
}
}
else {
fallof= 1.0f/(1.0f + distance-mindist);
if(ffall_val!=0.0f)
fallof = (float)pow(fallof, ffall_val+1.0);
}
fac=VecLength(vec_to_part);
#endif
if(fac < mindist) {
return 1.0f;
}
else if(pd->flag & PFIELD_USEMAX) {
if(fac>pd->maxdist || (pd->maxdist-mindist)<=0.0f)
return 0.0f;
fac= 1.0f - (fac-mindist)/(pd->maxdist-mindist);
printf("fac %f^%f\n", fac, pd->f_power);
return (float)pow((double)fac, (double)pd->f_power);
}
else {
fac+=1.0f-pd->mindist;
return (float)pow((double)fac,(double)-pd->f_power);
}
}
static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part) static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
{ {
float eff_dir[3], temp[3]; float eff_dir[3], temp[3];
@ -2071,6 +2112,8 @@ static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_t
else switch(pd->falloff){ else switch(pd->falloff){
case PFIELD_FALL_SPHERE: case PFIELD_FALL_SPHERE:
fac=VecLength(vec_to_part); fac=VecLength(vec_to_part);
falloff= particle_falloff(pd, fac);
#if 0
if(pd->flag&PFIELD_USEMAX && fac>pd->maxdist){ if(pd->flag&PFIELD_USEMAX && fac>pd->maxdist){
falloff=0.0f; falloff=0.0f;
break; break;
@ -2086,6 +2129,7 @@ static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_t
fac=0.001f; fac=0.001f;
falloff=1.0f/(float)pow((double)fac,(double)pd->f_power); falloff=1.0f/(float)pow((double)fac,(double)pd->f_power);
#endif
break; break;
case PFIELD_FALL_TUBE: case PFIELD_FALL_TUBE:

@ -89,7 +89,7 @@ typedef struct Isect {
/* function callbacks for face type abstraction */ /* function callbacks for face type abstraction */
typedef void (*RayCoordsFunc)(RayFace *face, typedef void (*RayCoordsFunc)(RayFace *face,
float **v1, float **v2, float **v3, float **v4); float **v1, float **v2, float **v3, float **v4);
typedef int (*RayCheckFunc)(Isect *is, RayFace *face); typedef int (*RayCheckFunc)(Isect *is, int ob, RayFace *face);
typedef float *(*RayObjectTransformFunc)(void *userdata, int ob); typedef float *(*RayObjectTransformFunc)(void *userdata, int ob);
/* tree building and freeing */ /* tree building and freeing */

@ -315,7 +315,6 @@ typedef struct VlakRen {
char puno; char puno;
char flag, ec; char flag, ec;
RadFace *radface; RadFace *radface;
ObjectRen *obr;
int index; int index;
} VlakRen; } VlakRen;
@ -496,7 +495,6 @@ typedef struct LampRen {
#define R_DUPLI_TRANSFORMED 1 #define R_DUPLI_TRANSFORMED 1
#define R_ENV_TRANSFORMED 2 #define R_ENV_TRANSFORMED 2
#define R_TRANSFORMED (1|2) #define R_TRANSFORMED (1|2)
#define R_DUPLI_ELEM 4
#endif /* RENDER_TYPES_H */ #endif /* RENDER_TYPES_H */

@ -1042,7 +1042,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
if(line) { if(line) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->flag= flag; vlr->flag= flag;
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, obr->totvert++); vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
vlr->v2= RE_findOrAddVert(obr, obr->totvert++); vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
@ -1132,7 +1131,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
if(adapt==0 || second){ if(adapt==0 || second){
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->flag= flag; vlr->flag= flag;
vlr->obr= obr;
vlr->v1= v1; vlr->v1= v1;
vlr->v2= v2; vlr->v2= v2;
vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
@ -1162,7 +1160,6 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo
if(Inpf(anor,nor)<adapt_angle && w>adapt_pix){ if(Inpf(anor,nor)<adapt_angle && w>adapt_pix){
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->flag= flag; vlr->flag= flag;
vlr->obr= obr;
vlr->v1= v1; vlr->v1= v1;
vlr->v2= v2; vlr->v2= v2;
vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
@ -1232,7 +1229,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
if(line) { if(line) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, obr->totvert++); vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
vlr->v2= RE_findOrAddVert(obr, obr->totvert++); vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
vlr->v3= vlr->v2; vlr->v3= vlr->v2;
@ -1257,7 +1253,6 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
} }
else { else {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= v1; vlr->v1= v1;
vlr->v2= RE_findOrAddVert(obr, obr->totvert++); vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
vlr->v3= vlr->v2; vlr->v3= vlr->v2;
@ -1289,7 +1284,6 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object
onevec[align]=1.0f; onevec[align]=1.0f;
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, obr->totvert++); vlr->v1= RE_findOrAddVert(obr, obr->totvert++);
vlr->v2= RE_findOrAddVert(obr, obr->totvert++); vlr->v2= RE_findOrAddVert(obr, obr->totvert++);
vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v3= RE_findOrAddVert(obr, obr->totvert++);
@ -2159,7 +2153,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve
return; return;
} }
static void displace_render_face(Render *re, VlakRen *vlr, float *scale) static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale)
{ {
ShadeInput shi; ShadeInput shi;
@ -2178,17 +2172,17 @@ static void displace_render_face(Render *re, VlakRen *vlr, float *scale)
/* Displace the verts, flag is set when done */ /* Displace the verts, flag is set when done */
if (!vlr->v1->flag) if (!vlr->v1->flag)
displace_render_vert(re, vlr->obr, &shi, vlr->v1,0, scale); displace_render_vert(re, obr, &shi, vlr->v1,0, scale);
if (!vlr->v2->flag) if (!vlr->v2->flag)
displace_render_vert(re, vlr->obr, &shi, vlr->v2, 1, scale); displace_render_vert(re, obr, &shi, vlr->v2, 1, scale);
if (!vlr->v3->flag) if (!vlr->v3->flag)
displace_render_vert(re, vlr->obr, &shi, vlr->v3, 2, scale); displace_render_vert(re, obr, &shi, vlr->v3, 2, scale);
if (vlr->v4) { if (vlr->v4) {
if (!vlr->v4->flag) if (!vlr->v4->flag)
displace_render_vert(re, vlr->obr, &shi, vlr->v4, 3, scale); displace_render_vert(re, obr, &shi, vlr->v4, 3, scale);
/* closest in displace value. This will help smooth edges. */ /* closest in displace value. This will help smooth edges. */
if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum)) if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum))
@ -2230,7 +2224,7 @@ static void do_displacement(Render *re, ObjectRen *obr)
for(i=0; i<obr->totvlak; i++){ for(i=0; i<obr->totvlak; i++){
vlr=RE_findOrAddVlak(obr, i); vlr=RE_findOrAddVlak(obr, i);
displace_render_face(re, vlr, scale); displace_render_face(re, obr, vlr, scale);
} }
/* Recalc vertex normals */ /* Recalc vertex normals */
@ -2297,7 +2291,6 @@ static void init_render_mball(Render *re, ObjectRen *obr)
for(a=0; a<dl->parts; a++, index+=4) { for(a=0; a<dl->parts; a++, index+=4) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, index[0]); vlr->v1= RE_findOrAddVert(obr, index[0]);
vlr->v2= RE_findOrAddVert(obr, index[1]); vlr->v2= RE_findOrAddVert(obr, index[1]);
vlr->v3= RE_findOrAddVert(obr, index[2]); vlr->v3= RE_findOrAddVert(obr, index[2]);
@ -2420,7 +2413,6 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
v4= RE_findOrAddVert(obr, p4); v4= RE_findOrAddVert(obr, p4);
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4; vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
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);
@ -2642,7 +2634,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
for(a=0; a<dl->parts; a++, index+=3) { for(a=0; a<dl->parts; a++, index+=3) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr = obr;
vlr->v1= RE_findOrAddVert(obr, startvert+index[0]); vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
vlr->v2= RE_findOrAddVert(obr, startvert+index[1]); vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
vlr->v3= RE_findOrAddVert(obr, startvert+index[2]); vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
@ -2706,7 +2697,6 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
for(; b<dl->nr; b++) { for(; b<dl->nr; b++) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, p2); vlr->v1= RE_findOrAddVert(obr, p2);
vlr->v2= RE_findOrAddVert(obr, p1); vlr->v2= RE_findOrAddVert(obr, p1);
vlr->v3= RE_findOrAddVert(obr, p3); vlr->v3= RE_findOrAddVert(obr, p3);
@ -3086,7 +3076,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
flag= mface->flag & ME_SMOOTH; flag= mface->flag & ME_SMOOTH;
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, vertofs+v1); vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
vlr->v2= RE_findOrAddVert(obr, vertofs+v2); vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
vlr->v3= RE_findOrAddVert(obr, vertofs+v3); vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
@ -3167,7 +3156,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
MVert *v1 = &mvert[medge->v2]; MVert *v1 = &mvert[medge->v2];
vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->obr= obr;
vlr->v1= RE_findOrAddVert(obr, vertofs+medge->v1); vlr->v1= RE_findOrAddVert(obr, vertofs+medge->v1);
vlr->v2= RE_findOrAddVert(obr, vertofs+medge->v2); vlr->v2= RE_findOrAddVert(obr, vertofs+medge->v2);
vlr->v3= vlr->v2; vlr->v3= vlr->v2;
@ -4309,7 +4297,6 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
VECCOPY(obi->dupliorco, dob->orco); VECCOPY(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0]; obi->dupliuv[0]= dob->uv[0];
obi->dupliuv[1]= dob->uv[1]; obi->dupliuv[1]= dob->uv[1];
obi->flag |= R_DUPLI_ELEM;
} }
else else
assign_dupligroup_dupli(re, obi, obr); assign_dupligroup_dupli(re, obi, obr);
@ -4325,7 +4312,6 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
VECCOPY(obi->dupliorco, dob->orco); VECCOPY(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0]; obi->dupliuv[0]= dob->uv[0];
obi->dupliuv[1]= dob->uv[1]; obi->dupliuv[1]= dob->uv[1];
obi->flag |= R_DUPLI_ELEM;
} }
else else
assign_dupligroup_dupli(re, obi, obr); assign_dupligroup_dupli(re, obi, obr);

@ -332,7 +332,7 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area)
if(area) { if(area) {
VECCOPY(v1, vlr->v1->co); VECCOPY(v1, vlr->v1->co);
VECCOPY(v3, vlr->v2->co); VECCOPY(v2, vlr->v2->co);
VECCOPY(v3, vlr->v3->co); VECCOPY(v3, vlr->v3->co);
if(vlr->v4) VECCOPY(v4, vlr->v4->co); if(vlr->v4) VECCOPY(v4, vlr->v4->co);
@ -589,9 +589,6 @@ static OcclusionTree *occ_tree_build(Render *re)
/* count */ /* count */
totface= 0; totface= 0;
for(obi=re->instancetable.first; obi; obi=obi->next) { for(obi=re->instancetable.first; obi; obi=obi->next) {
if(obi->flag & R_DUPLI_ELEM)
continue;
obr= obi->obr; obr= obi->obr;
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;
@ -625,9 +622,6 @@ static OcclusionTree *occ_tree_build(Render *re)
/* make array of face pointers */ /* make array of face pointers */
for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) { for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) {
if(obi->flag & R_DUPLI_ELEM)
continue; /* temporary to avoid slow renders with loads of duplis */
obr= obi->obr; obr= obi->obr;
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;

@ -77,7 +77,7 @@ static void vlr_face_coords(RayFace *face, float **v1, float **v2, float **v3, f
*v4 = (vlr->v4)? vlr->v4->co: NULL; *v4 = (vlr->v4)? vlr->v4->co: NULL;
} }
static int vlr_check_intersect(Isect *is, RayFace *face) static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
{ {
VlakRen *vlr = (VlakRen*)face; VlakRen *vlr = (VlakRen*)face;

@ -983,7 +983,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
if(!(is->faceorig == face && is->oborig == ob)) { if(!(is->faceorig == face && is->oborig == ob)) {
if(checkfunc(is, face)) { if(checkfunc(is, ob, face)) {
ov= no->ov+nr; ov= no->ov+nr;
if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
@ -1023,7 +1023,7 @@ static int testnode(Octree *oc, Isect *is, Node *no, OcVal ocval, RayCheckFunc c
while(face) { while(face) {
if(!(is->faceorig == face && is->oborig == ob)) { if(!(is->faceorig == face && is->oborig == ob)) {
if(checkfunc(is, face)) { if(checkfunc(is, ob, face)) {
ov= no->ov+nr; ov= no->ov+nr;
if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) { if( (ov->ocx & ocval.ocx) && (ov->ocy & ocval.ocy) && (ov->ocz & ocval.ocz) ) {
//accepted++; //accepted++;
@ -1205,7 +1205,7 @@ int RE_ray_tree_intersect_check(RayTree *tree, Isect *is, RayCheckFunc checkfunc
/* check with last intersected shadow face */ /* check with last intersected shadow face */
if(is->face_last!=NULL && !(is->face_last==is->faceorig && is->ob_last==is->oborig)) { if(is->face_last!=NULL && !(is->face_last==is->faceorig && is->ob_last==is->oborig)) {
if(checkfunc(is, is->face_last)) { if(checkfunc(is, is->ob_last, is->face_last)) {
is->ob= is->ob_last; is->ob= is->ob_last;
is->face= is->face_last; is->face= is->face_last;
VECSUB(is->vec, is->end, is->start); VECSUB(is->vec, is->end, is->start);

@ -1911,15 +1911,14 @@ static void bake_displacement(void *handle, ShadeInput *shi, Isect *isec, int di
} }
} }
static int bake_check_intersect(Isect *is, RayFace *face) static int bake_check_intersect(Isect *is, int ob, RayFace *face)
{ {
VlakRen *vlr = (VlakRen*)face;
BakeShade *bs = (BakeShade*)is->userdata; BakeShade *bs = (BakeShade*)is->userdata;
/* no direction checking for now, doesn't always improve the result /* no direction checking for now, doesn't always improve the result
* (INPR(shi->facenor, bs->dir) > 0.0f); */ * (INPR(shi->facenor, bs->dir) > 0.0f); */
return (vlr->obr->ob != bs->actob); return (R.objectinstance[ob].obr->ob != bs->actob);
} }
static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco) static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *dir, float sign, float *hitco)

@ -687,7 +687,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; vlr.lay= sseg->strand->buffer->lay;
vlr.obr= sseg->strand->buffer->obr;
if(sseg->buffer->ma->mode & MA_TANGENT_STR) if(sseg->buffer->ma->mode & MA_TANGENT_STR)
vlr.flag |= R_TANGENT; vlr.flag |= R_TANGENT;

@ -1796,8 +1796,8 @@ void do_material_tex(ShadeInput *shi)
Mat4Mul3Vecfl(R.viewmat, nor); Mat4Mul3Vecfl(R.viewmat, nor);
} }
else if(mtex->normapspace == MTEX_NSPACE_OBJECT) { else if(mtex->normapspace == MTEX_NSPACE_OBJECT) {
if(shi->vlr && shi->vlr->obr->ob) if(shi->obr && shi->obr->ob)
Mat4Mul3Vecfl(shi->vlr->obr->ob->obmat, nor); Mat4Mul3Vecfl(shi->obr->ob->obmat, nor);
Mat4Mul3Vecfl(R.viewmat, nor); Mat4Mul3Vecfl(R.viewmat, nor);
} }

@ -398,7 +398,7 @@ static void heat_ray_coords_func(RayFace *face, float **v1, float **v2, float **
*v4= (mface->v4)? verts[mface->v4]: NULL; *v4= (mface->v4)? verts[mface->v4]: NULL;
} }
static int heat_ray_check_func(Isect *is, RayFace *face) static int heat_ray_check_func(Isect *is, int ob, RayFace *face)
{ {
float *v1, *v2, *v3, *v4, nor[3]; float *v1, *v2, *v3, *v4, nor[3];

@ -1188,7 +1188,7 @@ void yafrayFileRender_t::writeMaterialsAndModulators()
} }
void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_list, const float obmat[4][4]) void yafrayFileRender_t::writeObject(Object* obj, ObjectRen *obr, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
{ {
ostr.str(""); ostr.str("");
// transform first (not necessarily actual obj->obmat, can be duplivert see below) // transform first (not necessarily actual obj->obmat, can be duplivert see below)
@ -1230,7 +1230,6 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
string matname(face0mat->id.name); string matname(face0mat->id.name);
// use name in imgtex_shader list if 'TexFace' enabled for this material // use name in imgtex_shader list if 'TexFace' enabled for this material
if (face0mat->mode & MA_FACETEXTURE) { if (face0mat->mode & MA_FACETEXTURE) {
ObjectRen *obr = face0->obr;
MTFace* tface = RE_vlakren_get_tface(obr, face0, obr->actmtface, NULL, 0); MTFace* tface = RE_vlakren_get_tface(obr, face0, obr->actmtface, NULL, 0);
if (tface) { if (tface) {
Image* fimg = (Image*)tface->tpage; Image* fimg = (Image*)tface->tpage;
@ -1408,7 +1407,6 @@ void yafrayFileRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_li
fci2!=VLR_list.end();++fci2) fci2!=VLR_list.end();++fci2)
{ {
VlakRen* vlr = *fci2; VlakRen* vlr = *fci2;
ObjectRen *obr = vlr->obr;
Material* fmat = vlr->mat; Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0); bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
string fmatname(fmat->id.name); string fmatname(fmat->id.name);
@ -1510,13 +1508,13 @@ void yafrayFileRender_t::writeAllObjects()
{ {
// first all objects except dupliverts (and main instance object for dups) // first all objects except dupliverts (and main instance object for dups)
for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin(); for (map<Object*, yafrayObjectRen >::const_iterator obi=all_objects.begin();
obi!=all_objects.end(); ++obi) obi!=all_objects.end(); ++obi)
{ {
// skip main duplivert object if in dupliMtx_list, written later // skip main duplivert object if in dupliMtx_list, written later
Object* obj = obi->first; Object* obj = obi->first;
if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue; if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
writeObject(obj, obi->second, obj->obmat); writeObject(obj, obi->second.obr, obi->second.faces, obj->obmat);
} }
// Now all duplivert objects (if any) as instances of main object // Now all duplivert objects (if any) as instances of main object
@ -1536,7 +1534,7 @@ void yafrayFileRender_t::writeAllObjects()
// first object written as normal (but with transform of first duplivert) // first object written as normal (but with transform of first duplivert)
Object* obj = dup_srcob[dupMtx->first]; Object* obj = dup_srcob[dupMtx->first];
writeObject(obj, all_objects[obj], obmat); writeObject(obj, all_objects[obj].obr, all_objects[obj].faces, obmat);
// all others instances of first // all others instances of first
for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16) { // number of 4x4 matrices for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16) { // number of 4x4 matrices

@ -18,7 +18,7 @@ class yafrayFileRender_t : public yafrayRender_t
virtual void writeTextures(); virtual void writeTextures();
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname=""); virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators(); virtual void writeMaterialsAndModulators();
virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]); virtual void writeObject(Object* obj, ObjectRen *obr, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects(); virtual void writeAllObjects();
virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]); virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
virtual void writeLamps(); virtual void writeLamps();

@ -1079,7 +1079,7 @@ void yafrayPluginRender_t::writeMaterialsAndModulators()
} }
void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen *vlr, MTFace* uvc, bool comple) void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, ObjectRen *obr, VlakRen *vlr, MTFace* uvc, bool comple)
{ {
if (uvc) if (uvc)
{ {
@ -1107,9 +1107,8 @@ void yafrayPluginRender_t::genUVcoords(vector<yafray::GFLOAT> &uvcoords, VlakRen
} }
} }
void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple) void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, ObjectRen *obr, VlakRen *vlr, bool comple)
{ {
ObjectRen *obr= vlr->obr;
MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0); MCol *mcol= RE_vlakren_get_mcol(obr, vlr, obr->actmcol, NULL, 0);
if (mcol) if (mcol)
@ -1143,10 +1142,9 @@ void yafrayPluginRender_t::genVcol(vector<yafray::CFLOAT> &vcol, VlakRen *vlr, b
void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,vector<int> &faceshader, void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol, vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
map<VertRen*, int> &vert_idx,VlakRen *vlr, map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv) int has_orco,bool has_uv)
{ {
ObjectRen *obr= vlr->obr;
Material* fmat = vlr->mat; Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0); bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
string fmatname(fmat->id.name); string fmatname(fmat->id.name);
@ -1185,16 +1183,15 @@ void yafrayPluginRender_t::genFace(vector<int> &faces,vector<string> &shaders,ve
faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3); faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
if(has_uv) genUVcoords(uvcoords, vlr, uvc); if(has_uv) genUVcoords(uvcoords, obr, vlr, uvc);
if (EXPORT_VCOL) genVcol(vcol, vlr); if (EXPORT_VCOL) genVcol(vcol, obr, vlr);
} }
void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &shaders,*/vector<int> &faceshader, void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &shaders,*/vector<int> &faceshader,
vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol, vector<yafray::GFLOAT> &uvcoords,vector<yafray::CFLOAT> &vcol,
map<VertRen*, int> &vert_idx,VlakRen *vlr, map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv) int has_orco,bool has_uv)
{ {
ObjectRen *obr= vlr->obr;
Material* fmat = vlr->mat; Material* fmat = vlr->mat;
bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0); bool EXPORT_VCOL = ((fmat->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))!=0);
@ -1210,12 +1207,12 @@ void yafrayPluginRender_t::genCompleFace(vector<int> &faces,/*vector<string> &sh
faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3); faces.push_back(idx1); faces.push_back(idx2); faces.push_back(idx3);
if (has_uv) genUVcoords(uvcoords, vlr, uvc, true); if (has_uv) genUVcoords(uvcoords, obr, vlr, uvc, true);
if (EXPORT_VCOL) genVcol(vcol, vlr, true); if (EXPORT_VCOL) genVcol(vcol, obr, vlr, true);
} }
void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx, void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vidx,
map<VertRen*, int> &vert_idx, VlakRen* vlr, int has_orco, Object* obj) map<VertRen*, int> &vert_idx, ObjectRen *obr, VlakRen* vlr, int has_orco, Object* obj)
{ {
VertRen* ver; VertRen* ver;
float tvec[3]; // for back2world transform float tvec[3]; // for back2world transform
@ -1280,7 +1277,7 @@ void yafrayPluginRender_t::genVertices(vector<yafray::point3d_t> &verts, int &vi
} }
} }
void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_list, const float obmat[4][4]) void yafrayPluginRender_t::writeObject(Object* obj, ObjectRen *obr, const vector<VlakRen*> &VLR_list, const float obmat[4][4])
{ {
float mtr[4*4]; float mtr[4*4];
mtr[0*4+0]=obmat[0][0]; mtr[0*4+1]=obmat[1][0]; mtr[0*4+2]=obmat[2][0]; mtr[0*4+3]=obmat[3][0]; mtr[0*4+0]=obmat[0][0]; mtr[0*4+1]=obmat[1][0]; mtr[0*4+2]=obmat[2][0]; mtr[0*4+3]=obmat[3][0];
@ -1341,8 +1338,7 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
fci!=VLR_list.end();++fci) fci!=VLR_list.end();++fci)
{ {
VlakRen* vlr = *fci; VlakRen* vlr = *fci;
ObjectRen *obr = vlr->obr; genVertices(verts, vidx, vert_idx, obr, vlr, has_orco, obj);
genVertices(verts, vidx, vert_idx, vlr, has_orco, obj);
if(RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0)) has_uv=true; if(RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0)) has_uv=true;
} }
// all faces using the index list created above // all faces using the index list created above
@ -1354,9 +1350,9 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
fci2!=VLR_list.end();++fci2) fci2!=VLR_list.end();++fci2)
{ {
VlakRen* vlr = *fci2; VlakRen* vlr = *fci2;
genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv); genFace(faces, shaders, faceshader, uvcoords, vcol, vert_idx, obr, vlr, has_orco, has_uv);
if (vlr->v4) if (vlr->v4)
genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, vlr, has_orco, has_uv); genCompleFace(faces, faceshader, uvcoords, vcol, vert_idx, obr, vlr, has_orco, has_uv);
} }
// using the ObjectRen database, contruct a new name if object has a parent. // using the ObjectRen database, contruct a new name if object has a parent.
@ -1387,13 +1383,13 @@ void yafrayPluginRender_t::writeObject(Object* obj, const vector<VlakRen*> &VLR_
void yafrayPluginRender_t::writeAllObjects() void yafrayPluginRender_t::writeAllObjects()
{ {
// first all objects except dupliverts (and main instance object for dups) // first all objects except dupliverts (and main instance object for dups)
for (map<Object*, vector<VlakRen*> >::const_iterator obi=all_objects.begin(); for (map<Object*, yafrayObjectRen >::const_iterator obi=all_objects.begin();
obi!=all_objects.end(); ++obi) obi!=all_objects.end(); ++obi)
{ {
// skip main duplivert object if in dupliMtx_list, written later // skip main duplivert object if in dupliMtx_list, written later
Object* obj = obi->first; Object* obj = obi->first;
if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue; if (dupliMtx_list.find(string(obj->id.name))!=dupliMtx_list.end()) continue;
writeObject(obj, obi->second, obj->obmat); writeObject(obj, obi->second.obr, obi->second.faces, obj->obmat);
} }
// Now all duplivert objects (if any) as instances of main object // Now all duplivert objects (if any) as instances of main object
@ -1411,7 +1407,7 @@ void yafrayPluginRender_t::writeAllObjects()
// first object written as normal (but with transform of first duplivert) // first object written as normal (but with transform of first duplivert)
Object* obj = dup_srcob[dupMtx->first]; Object* obj = dup_srcob[dupMtx->first];
writeObject(obj, all_objects[obj], obmat); writeObject(obj, all_objects[obj].obr, all_objects[obj].faces, obmat);
// all others instances of first // all others instances of first
for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16) for (unsigned int curmtx=16;curmtx<dupMtx->second.size();curmtx+=16)

@ -35,7 +35,7 @@ class yafrayPluginRender_t : public yafrayRender_t
virtual void writeTextures(); virtual void writeTextures();
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname=""); virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname="");
virtual void writeMaterialsAndModulators(); virtual void writeMaterialsAndModulators();
virtual void writeObject(Object* obj, virtual void writeObject(Object* obj, ObjectRen *obr,
const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]); const std::vector<VlakRen*> &VLR_list, const float obmat[4][4]);
virtual void writeAllObjects(); virtual void writeAllObjects();
virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]); virtual void writeAreaLamp(LampRen* lamp, int num, float iview[4][4]);
@ -48,18 +48,18 @@ class yafrayPluginRender_t : public yafrayRender_t
virtual bool initExport(); virtual bool initExport();
virtual bool finishExport(); virtual bool finishExport();
void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,VlakRen *vlr,MTFace* uvc, bool comple=false); void genUVcoords(std::vector<yafray::GFLOAT> &uvcoords,ObjectRen *obr,VlakRen *vlr,MTFace* uvc, bool comple=false);
void genVcol(std::vector<yafray::CFLOAT> &vcol, VlakRen *vlr, bool comple=false); void genVcol(std::vector<yafray::CFLOAT> &vcol, ObjectRen *obr, VlakRen *vlr, bool comple=false);
void genFace(std::vector<int> &faces,std::vector<std::string> &shaders,std::vector<int> &faceshader, void genFace(std::vector<int> &faces,std::vector<std::string> &shaders,std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol, std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
std::map<VertRen*, int> &vert_idx,VlakRen *vlr, std::map<VertRen*, int> &vert_idx,ObjectRen *obr,VlakRen *vlr,
int has_orco,bool has_uv); int has_orco,bool has_uv);
void genCompleFace(std::vector<int> &faces,/*std::vector<std::string> &shaders,*/std::vector<int> &faceshader, void genCompleFace(std::vector<int> &faces,/*std::vector<std::string> &shaders,*/std::vector<int> &faceshader,
std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol, std::vector<yafray::GFLOAT> &uvcoords,std::vector<yafray::CFLOAT> &vcol,
std::map<VertRen*, int> &vert_idx,VlakRen *vlr, std::map<VertRen*, int> &vert_idx,ObjectRen *obr, VlakRen *vlr,
int has_orco,bool has_uv); int has_orco,bool has_uv);
void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx, void genVertices(std::vector<yafray::point3d_t> &verts, int &vidx,
std::map<VertRen*, int> &vert_idx, VlakRen* vlr, int has_orco, Object* obj); std::map<VertRen*, int> &vert_idx, ObjectRen *obr, VlakRen* vlr, int has_orco, Object* obj);
}; };
class blenderYafrayOutput_t : public yafray::colorOutput_t class blenderYafrayOutput_t : public yafray::colorOutput_t

@ -141,15 +141,15 @@ bool yafrayRender_t::getAllMatTexObs()
// Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later. // Make list of faces per object, ignore <3 vert faces, duplicate vertex sorting done later.
// ignore null object pointers. // ignore null object pointers.
// Also make list of facetexture images (material 'TexFace'). // Also make list of facetexture images (material 'TexFace').
if (vlr->obr->ob) { if (obr->ob) {
int nv = 0; // number of vertices int nv = 0; // number of vertices
MTFace *tface; MTFace *tface;
if (vlr->v4) nv=4; else if (vlr->v3) nv=3; if (vlr->v4) nv=4; else if (vlr->v3) nv=3;
if (nv) { if (nv) {
ObjectRen *obr= vlr->obr;
renderobs[obr->ob->id.name] = obr->ob; renderobs[obr->ob->id.name] = obr->ob;
all_objects[obr->ob].push_back(vlr); all_objects[obr->ob].obr= obr;
all_objects[obr->ob].faces.push_back(vlr);
tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0); tface= RE_vlakren_get_tface(obr, vlr, obr->actmtface, NULL, 0);
if (tface && tface->tpage) { if (tface && tface->tpage) {
@ -184,7 +184,7 @@ bool yafrayRender_t::getAllMatTexObs()
// in all_objects with the name given in dupliMtx_list // in all_objects with the name given in dupliMtx_list
if (!dupliMtx_list.empty()) { if (!dupliMtx_list.empty()) {
for (map<Object*, vector<VlakRen*> >::const_iterator obn=all_objects.begin(); for (map<Object*, yafrayObjectRen>::const_iterator obn=all_objects.begin();
obn!=all_objects.end();++obn) obn!=all_objects.end();++obn)
{ {
Object* obj = obn->first; Object* obj = obn->first;

@ -52,6 +52,12 @@ extern void error (char *fmt, ...);
#include <vector> #include <vector>
#include <set> #include <set>
class yafrayObjectRen {
public:
std::vector<VlakRen*> faces;
ObjectRen *obr;
};
class yafrayRender_t class yafrayRender_t
{ {
public: public:
@ -72,7 +78,7 @@ class yafrayRender_t
bool hasworld; bool hasworld;
std::map<Object*, std::vector<VlakRen*> > all_objects; std::map<Object*, yafrayObjectRen> all_objects;
std::map<std::string, Material*> used_materials; std::map<std::string, Material*> used_materials;
std::map<std::string, MTex*> used_textures; std::map<std::string, MTex*> used_textures;
std::map<std::string, std::vector<float> > dupliMtx_list; std::map<std::string, std::vector<float> > dupliMtx_list;
@ -86,7 +92,7 @@ class yafrayRender_t
virtual void writeTextures()=0; virtual void writeTextures()=0;
virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname)=0; virtual void writeShader(const std::string &shader_name, Material* matr, const std::string &facetexname)=0;
virtual void writeMaterialsAndModulators()=0; virtual void writeMaterialsAndModulators()=0;
virtual void writeObject(Object* obj, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0; virtual void writeObject(Object* obj, ObjectRen *obr, const std::vector<VlakRen*> &VLR_list, const float obmat[4][4])=0;
virtual void writeAllObjects()=0; virtual void writeAllObjects()=0;
virtual void writeLamps()=0; virtual void writeLamps()=0;
virtual void writeCamera()=0; virtual void writeCamera()=0;