diff options
Diffstat (limited to 'source/blender/render/intern/source/convertblender.c')
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 104 |
1 files changed, 84 insertions, 20 deletions
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; |