diff options
-rw-r--r-- | source/blender/blenkernel/BKE_anim.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_group.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 57 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/group.c | 15 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 104 | ||||
-rw-r--r-- | source/blender/render/intern/source/occlusion.c | 21 |
7 files changed, 154 insertions, 54 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index a82faa56e40..54fcb19d5dc 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -46,7 +46,7 @@ typedef struct DupliObject { struct DupliObject *next, *prev; struct Object *ob; unsigned int origlay; - int index, no_draw, type; + int index, no_draw, type, animated; float mat[4][4], omat[4][4]; float orco[3], uv[2]; } DupliObject; diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 1c301bb255c..bdc56b2cbd1 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -47,6 +47,7 @@ void add_to_group(struct Group *group, struct Object *ob); void rem_from_group(struct Group *group, struct Object *ob); struct Group *find_group(struct Object *ob, struct Group *group); int object_in_group(struct Object *ob, struct Group *group); +int group_is_animated(struct Object *parent, struct Group *group); void group_tag_recalc(struct Group *group); void group_handle_recalc_and_update(struct Object *parent, struct Group *group); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index a776f2eab80..58d0e84acd8 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -76,7 +76,7 @@ #include <config.h> #endif -static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level); +static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated); void free_path(Path *path) { @@ -284,7 +284,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK /* ****************** DUPLICATOR ************** */ -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type) +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated) { DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -295,12 +295,13 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i dob->origlay= ob->lay; dob->index= index; dob->type= type; + dob->animated= (type == OB_DUPLIGROUP) && animated; ob->lay= lay; return dob; } -static void group_duplilist(ListBase *lb, Object *ob, int level) +static void group_duplilist(ListBase *lb, Object *ob, int level, int animated) { DupliObject *dob; Group *group; @@ -316,25 +317,26 @@ static void group_duplilist(ListBase *lb, Object *ob, int level) /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ group_handle_recalc_and_update(ob, group); + animated= animated || group_is_animated(ob, group); for(go= group->gobject.first; go; go= go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ if(go->ob!=ob) { Mat4MulMat4(mat, go->ob->obmat, ob->obmat); - dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP); + dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated); dob->no_draw= (dob->origlay & group->layer)==0; if(go->ob->transflag & OB_DUPLI) { Mat4CpyMat4(dob->ob->obmat, dob->mat); - object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1); + object_duplilist_recursive((ID *)group, go->ob, lb, ob->obmat, level+1, animated); Mat4CpyMat4(dob->ob->obmat, dob->omat); } } } } -static void frames_duplilist(ListBase *lb, Object *ob, int level) +static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated) { extern int enable_cu_speed; /* object.c */ Object copyob; @@ -361,7 +363,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level) if(ok) { do_ob_ipo(ob); where_is_object_time(ob, (float)G.scene->r.cfra); - new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES); + new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated); } } @@ -373,6 +375,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level) struct vertexDupliData { ID *id; /* scene or group, for recursive loops */ int level; + int animated; ListBase *lb; float pmat[4][4]; float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */ @@ -408,7 +411,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n Mat4CpyMat4(tmat, obmat); Mat4MulMat43(obmat, tmat, mat); } - dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS); + dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated); if(vdd->orco) VECCOPY(dob->orco, vdd->orco[index]); @@ -416,12 +419,12 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n float tmpmat[4][4]; Mat4CpyMat4(tmpmat, vdd->ob->obmat); Mat4CpyMat4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1); + object_duplilist_recursive((ID *)vdd->id, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated); Mat4CpyMat4(vdd->ob->obmat, tmpmat); } } -static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level) +static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated) { Object *ob, *ob_iter; Mesh *me; @@ -493,6 +496,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ vdd.id= id; vdd.level= level; + vdd.animated= animated; vdd.lb= lb; vdd.ob= ob; vdd.par= par; @@ -527,7 +531,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level) +static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], int level, int animated) { Object *ob, *ob_iter; Base *base = NULL; @@ -663,7 +667,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma Mat4CpyMat4(tmat, obmat); Mat4MulMat43(obmat, tmat, mat); - dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES); + dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated); if(G.rendering) { w= (mv4)? 0.25f: 1.0f/3.0f; @@ -694,7 +698,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma float tmpmat[4][4]; Mat4CpyMat4(tmpmat, ob->obmat); Mat4CpyMat4(ob->obmat, obmat); /* pretend we are really this mat */ - object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1); + object_duplilist_recursive((ID *)id, ob, lb, ob->obmat, level+1, animated); Mat4CpyMat4(ob->obmat, tmpmat); } } @@ -719,7 +723,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level) +static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) { GroupObject *go; Object *ob=0, **oblist=0; @@ -868,7 +872,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_ else Mat4CpyMat4(mat, tmat); - dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS); + dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); if(G.rendering) psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); } @@ -894,7 +898,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_ else Mat4CpyMat4(mat, tmat); - dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS); + dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); if(G.rendering) psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); } @@ -935,7 +939,7 @@ static Object *find_family_object(Object **obar, char *family, char ch) } -static void font_duplilist(ListBase *lb, Object *par, int level) +static void font_duplilist(ListBase *lb, Object *par, int level, int animated) { Object *ob, *obar[256]; Curve *cu; @@ -976,16 +980,15 @@ static void font_duplilist(ListBase *lb, Object *par, int level) Mat4CpyMat4(obmat, par->obmat); VECCOPY(obmat[3], vec); - new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS); + new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated); } - } MEM_freeN(chartransdata); } /* ***************************** */ -static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level) +static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated) { if((ob->transflag & OB_DUPLI)==0) return; @@ -1004,30 +1007,30 @@ static void object_duplilist_recursive(ID *id, Object *ob, ListBase *duplilist, if(ob->transflag & OB_DUPLIPARTS) { ParticleSystem *psys = ob->particlesystem.first; for(; psys; psys=psys->next) - new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1); + new_particle_duplilist(duplilist, id, ob, par_space_mat, psys, level+1, animated); } else if(ob->transflag & OB_DUPLIVERTS) { if(ob->type==OB_MESH) { - vertex_duplilist(duplilist, id, ob, par_space_mat, level+1); + vertex_duplilist(duplilist, id, ob, par_space_mat, level+1, animated); } else if(ob->type==OB_FONT) { if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ - font_duplilist(duplilist, ob, level+1); + font_duplilist(duplilist, ob, level+1, animated); } } } else if(ob->transflag & OB_DUPLIFACES) { if(ob->type==OB_MESH) - face_duplilist(duplilist, id, ob, par_space_mat, level+1); + face_duplilist(duplilist, id, ob, par_space_mat, level+1, animated); } else if(ob->transflag & OB_DUPLIFRAMES) { if (GS(id->name)==ID_SCE) { /* TODO - support dupligroups */ - frames_duplilist(duplilist, ob, level+1); + frames_duplilist(duplilist, ob, level+1, animated); } } else if(ob->transflag & OB_DUPLIGROUP) { DupliObject *dob; - group_duplilist(duplilist, ob, level+1); /* now recursive */ + group_duplilist(duplilist, ob, level+1, animated); /* now recursive */ if (level==0) { for(dob= duplilist->first; dob; dob= dob->next) @@ -1042,7 +1045,7 @@ ListBase *object_duplilist(Scene *sce, Object *ob) { ListBase *duplilist= MEM_mallocN(sizeof(ListBase), "duplilist"); duplilist->first= duplilist->last= NULL; - object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0); + object_duplilist_recursive((ID *)sce, ob, duplilist, NULL, 0, 0); return duplilist; } diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index b29cf63ab0b..a85f0f52ad2 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -191,6 +191,20 @@ void group_tag_recalc(Group *group) } } +int group_is_animated(Object *parent, Group *group) +{ + GroupObject *go; + + if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first) + return 1; + + for(go= group->gobject.first; go; go= go->next) + if(go->ob && go->ob->proxy) + return 1; + + return 0; +} + /* only replaces object strips or action when parent nla instructs it */ /* keep checking nla.c though, in case internal structure of strip changes */ static void group_replaces_nla(Object *parent, Object *target, char mode) @@ -231,7 +245,6 @@ static void group_replaces_nla(Object *parent, Object *target, char mode) } } - /* puts all group members in local timing system, after this call you can draw everything, leaves tags in objects to signal it needs further updating */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 6124870d63e..b400014d1bf 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; + int index, psysindex, flag; int totvert, totvlak, totstrand, tothalo; int vertnodeslen, vlaknodeslen, strandnodeslen, blohalen; @@ -257,6 +257,8 @@ typedef struct ObjectRen { char (*mtface)[32]; char (*mcol)[32]; int actmtface, actmcol; + + float obmat[4][4]; /* only used in convertblender.c, for instancing */ } ObjectRen; typedef struct ObjectInstanceRen { @@ -487,10 +489,14 @@ typedef struct LampRen { #define R_STRAND_BSPLINE 1 #define R_STRAND_B_UNITS 2 +/* objectren->flag */ +#define R_INSTANCEABLE 1 + /* objectinstance->flag */ #define R_DUPLI_TRANSFORMED 1 #define R_ENV_TRANSFORMED 2 #define R_TRANSFORMED (1|2) +#define R_DUPLI_ELEM 4 #endif /* RENDER_TYPES_H */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index ff227b1c670..845fda22816 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3896,7 +3896,7 @@ static void find_dupli_instances(Render *re, ObjectRen *obr) float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; int first = 1; - Mat4MulMat4(obmat, obr->ob->obmat, re->viewmat); + Mat4MulMat4(obmat, obr->obmat, re->viewmat); Mat4Invert(imat, obmat); for(obi=re->instancetable.last; obi; obi=obi->prev) { @@ -3923,6 +3923,40 @@ static void find_dupli_instances(Render *re, ObjectRen *obr) } } +static void assign_dupligroup_dupli(Render *re, ObjectInstanceRen *obi, ObjectRen *obr) +{ + float imat[4][4], obmat[4][4], obimat[4][4], nmat[3][3]; + + Mat4MulMat4(obmat, obr->obmat, re->viewmat); + Mat4Invert(imat, obmat); + + obi->obr= obr; + + /* compute difference between object matrix and + * object matrix with dupli transform, in viewspace */ + Mat4CpyMat4(obimat, obi->mat); + Mat4MulMat4(obi->mat, imat, obimat); + + Mat3CpyMat4(nmat, obi->mat); + Mat3Inv(obi->imat, nmat); + + re->totvert += obr->totvert; + re->totvlak += obr->totvlak; + re->tothalo += obr->tothalo; + re->totstrand += obr->totstrand; +} + +static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex) +{ + ObjectRen *obr; + + for(obr=re->objecttable.first; obr; obr=obr->next) + if(obr->ob == ob && obr->psysindex == psysindex && (obr->flag & R_INSTANCEABLE)) + return obr; + + return NULL; +} + static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts) { Object *ob= obr->ob; @@ -3962,7 +3996,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts) re->totstrand += obr->totstrand; } -static void add_render_object(Render *re, Object *ob, Object *par, int index, int only_verts) +static void add_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable) { ObjectRen *obr; ParticleSystem *psys; @@ -3985,6 +4019,10 @@ 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); + if(instanceable) { + obr->flag |= R_INSTANCEABLE; + Mat4CpyMat4(obr->obmat, ob->obmat); + } init_render_object_data(re, obr, only_verts); /* only add instance for objects that have not been used for dupli */ @@ -3999,6 +4037,10 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in psysindex= 1; for(psys=ob->particlesystem.first; psys; psys=psys->next, psysindex++) { obr= RE_addRenderObject(re, ob, par, index, psysindex); + if(instanceable) { + obr->flag |= R_INSTANCEABLE; + Mat4CpyMat4(obr->obmat, ob->obmat); + } init_render_object_data(re, obr, only_verts); psys_render_restore(ob, psys); @@ -4013,7 +4055,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in /* par = pointer to duplicator parent, needed for object lookup table */ /* index = when duplicater copies same object (particle), the counter */ -static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts) +static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable) { static double lasttime= 0.0; double time; @@ -4022,7 +4064,7 @@ static void init_render_object(Render *re, Object *ob, Object *par, int index, i if(ob->type==OB_LAMP) add_render_lamp(re, ob); else if(render_object_type(ob->type)) - add_render_object(re, ob, par, index, only_verts); + add_render_object(re, ob, par, index, only_verts, instanceable); else { MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); MTC_Mat4Invert(ob->imat, mat); @@ -4151,7 +4193,7 @@ static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd) { return (render_object_type(obd->type) && - (!(dob->type == OB_DUPLIGROUP)) && + (!(dob->type == OB_DUPLIGROUP) || !dob->animated) && !(re->r.mode & R_RADIO)); } @@ -4224,7 +4266,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int if(ob->flag & OB_DONE) { if(ob->transflag & OB_RENDER_DUPLI) if(allow_render_object(ob, nolamps, onlyselected, actob)) - init_render_object(re, ob, NULL, 0, only_verts); + init_render_object(re, ob, NULL, 0, only_verts, 1); } else if((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) { if((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) { @@ -4255,38 +4297,60 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int if(allow_render_dupli_instance(re, dob, obd)) { ParticleSystem *psys; + ObjectRen *obr = NULL; int psysindex; float mat[4][4]; - Mat4MulMat4(mat, dob->mat, re->viewmat); - obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat); - VECCOPY(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; + if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, obd, 0))) { + Mat4MulMat4(mat, dob->mat, re->viewmat); + obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat); + + if(dob->type != OB_DUPLIGROUP) { + VECCOPY(obi->dupliorco, dob->orco); + obi->dupliuv[0]= dob->uv[0]; + obi->dupliuv[1]= dob->uv[1]; + obi->flag |= R_DUPLI_ELEM; + } + else + assign_dupligroup_dupli(re, obi, obr); + } + else + init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated); psysindex= 1; for(psys=obd->particlesystem.first; psys; psys=psys->next) { - RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat); - VECCOPY(obi->dupliorco, dob->orco); - obi->dupliuv[0]= dob->uv[0]; - obi->dupliuv[1]= dob->uv[1]; + if(dob->type != OB_DUPLIGROUP || (obr=find_dupligroup_dupli(re, ob, psysindex))) { + obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat); + if(dob->type != OB_DUPLIGROUP) { + VECCOPY(obi->dupliorco, dob->orco); + obi->dupliuv[0]= dob->uv[0]; + obi->dupliuv[1]= dob->uv[1]; + obi->flag |= R_DUPLI_ELEM; + } + else + assign_dupligroup_dupli(re, obi, obr); + } + else + init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated); } - obd->flag |= OB_DONE; - obd->transflag |= OB_RENDER_DUPLI; + if(dob->type != OB_DUPLIGROUP) { + obd->flag |= OB_DONE; + obd->transflag |= OB_RENDER_DUPLI; + } } else - init_render_object(re, obd, ob, dob->index, only_verts); + init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated); if(re->test_break()) break; } free_object_duplilist(lb); if(allow_render_object(ob, nolamps, onlyselected, actob)) - init_render_object(re, ob, NULL, 0, only_verts); + init_render_object(re, ob, NULL, 0, only_verts, 0); } else if(allow_render_object(ob, nolamps, onlyselected, actob)) - init_render_object(re, ob, NULL, 0, only_verts); + init_render_object(re, ob, NULL, 0, only_verts, 0); } if(re->test_break()) break; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index bcd6ed3aa0d..0744aa95c45 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -297,6 +297,7 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area) { ObjectInstanceRen *obi; VlakRen *vlr; + float v1[3], v2[3], v3[3], v4[3]; obi= &R.objectinstance[face->obi]; vlr= RE_findOrAddVlak(obi->obr, face->facenr); @@ -330,11 +331,23 @@ static void occ_face(const OccFace *face, float *co, float *normal, float *area) } if(area) { + VECCOPY(v1, vlr->v1->co); + VECCOPY(v3, vlr->v2->co); + VECCOPY(v3, vlr->v3->co); + if(vlr->v4) VECCOPY(v4, vlr->v4->co); + + if(obi->flag & R_TRANSFORMED) { + Mat4MulVecfl(obi->mat, v1); + Mat4MulVecfl(obi->mat, v2); + Mat4MulVecfl(obi->mat, v3); + if(vlr->v4) Mat4MulVecfl(obi->mat, v4); + } + /* todo: correct area for instances */ if(vlr->v4) - *area= AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); + *area= AreaQ3Dfl(v1, v2, v3, v4); else - *area= AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co); + *area= AreaT3Dfl(v1, v2, v3); } } @@ -576,7 +589,7 @@ static OcclusionTree *occ_tree_build(Render *re) /* count */ totface= 0; for(obi=re->instancetable.first; obi; obi=obi->next) { - if(obi->flag & R_TRANSFORMED) + if(obi->flag & R_DUPLI_ELEM) continue; obr= obi->obr; @@ -612,7 +625,7 @@ static OcclusionTree *occ_tree_build(Render *re) /* make array of face pointers */ for(b=0, c=0, obi=re->instancetable.first; obi; obi=obi->next, c++) { - if(obi->flag & R_TRANSFORMED) + if(obi->flag & R_DUPLI_ELEM) continue; /* temporary to avoid slow renders with loads of duplis */ obr= obi->obr; |