Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-02-24 21:53:35 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-02-24 22:00:44 +0400
commit188f8d093504aa3dcf28efc404c395ad43fc633f (patch)
tree3aa201070829aac12757a13ef9d3f50124632072 /source/blender/render
parent036d35dd2471bc490c266cf4f7d4aba10080cb10 (diff)
Fix T38801: Dupli objects with modifiers exhibit bad transform artifacts
in Blender Internal renderer. The BI renderer applies modifiers //after// changing the obmat of the respective object (for the first instance it encounters). Before rB6940bf0 the original obmat (omat) was stored inside dupli object data, which was removed in favor of local omat variables due to hackishness and redundancy. Problem with BI is that all the obmats have to be overridden in relation to each other to produce the correct modifier results (here: offset object for the array modifier). The patch restores the old (messy) behavior for BI by first overriding **all** the obmats at once from duplis, then creating render instances, then cleaning up. A better solution would be to avoid these modifier hacks in BI altogether and properly evaluate them in the original object space, but that requires far greater changes to the old code base, and is out of scope for bugfixing.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/source/convertblender.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 57fb42cf20a..3e9e1b1c5e5 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4930,6 +4930,13 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in
}
}
+/* additional data for dupli objects outside
+ * of the main dupli list
+ */
+typedef struct DupliObjectExtra {
+ float omat[4][4];
+} DupliObjectExtra;
+
static void database_init_objects(Render *re, unsigned int renderlay, int nolamps, int onlyselected, Object *actob, int timeoffset)
{
Base *base;
@@ -4988,20 +4995,28 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
else if ((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->lay)) ) {
if ((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
DupliObject *dob;
- ListBase *lb;
+ ListBase *duplilist;
+ DupliObjectExtra *duplilist_extra = NULL;
+ int totdob, i;
/* create list of duplis generated by this object, particle
* system need to have render settings set for dupli particles */
dupli_render_particle_set(re, ob, timeoffset, 0, 1);
- lb= object_duplilist(re->eval_ctx, re->scene, ob);
+ duplilist = object_duplilist(re->eval_ctx, re->scene, ob);
+ totdob = BLI_countlist(duplilist);
+ if (totdob > 0)
+ duplilist_extra = MEM_mallocN(sizeof(DupliObjectExtra) * totdob, "DupliObject extra data");
dupli_render_particle_set(re, ob, timeoffset, 0, 0);
- for (dob= lb->first; dob; dob= dob->next) {
+ /* set dupli obmats */
+ for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
+ copy_m4_m4(duplilist_extra[i].omat, dob->ob->obmat);
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ }
+
+ for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
+ DupliObjectExtra *dob_extra = &duplilist_extra[i];
Object *obd= dob->ob;
- float omat[4][4];
-
- copy_m4_m4(omat, obd->obmat);
- copy_m4_m4(obd->obmat, dob->mat);
/* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
if (!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw)
@@ -5033,7 +5048,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], 0, mat, ob->lay);
/* fill in instance variables for texturing */
- set_dupli_tex_mat(re, obi, dob, omat);
+ set_dupli_tex_mat(re, obi, dob, dob_extra->omat);
if (dob->type != OB_DUPLIGROUP) {
copy_v3_v3(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0];
@@ -5059,7 +5074,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
mul_m4_m4m4(mat, re->viewmat, dob->mat);
obi= RE_addRenderInstance(re, NULL, obd, ob, dob->persistent_id[0], psysindex++, mat, obd->lay);
- set_dupli_tex_mat(re, obi, dob, omat);
+ set_dupli_tex_mat(re, obi, dob, dob_extra->omat);
if (dob->type != OB_DUPLIGROUP) {
copy_v3_v3(obi->dupliorco, dob->orco);
obi->dupliuv[0]= dob->uv[0];
@@ -5075,7 +5090,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
if (obi==NULL)
/* can't instance, just create the object */
- init_render_object(re, obd, ob, dob, omat, timeoffset);
+ init_render_object(re, obd, ob, dob, dob_extra->omat, timeoffset);
if (dob->type != OB_DUPLIGROUP) {
obd->flag |= OB_DONE;
@@ -5083,13 +5098,19 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
}
}
else
- init_render_object(re, obd, ob, dob, omat, timeoffset);
-
- copy_m4_m4(obd->obmat, omat);
+ init_render_object(re, obd, ob, dob, dob_extra->omat, timeoffset);
if (re->test_break(re->tbh)) break;
}
- free_object_duplilist(lb);
+
+ /* restore obmats */
+ for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {
+ copy_m4_m4(dob->ob->obmat, duplilist_extra[i].omat);
+ }
+
+ free_object_duplilist(duplilist);
+ if (duplilist_extra)
+ MEM_freeN(duplilist_extra);
if (allow_render_object(re, ob, nolamps, onlyselected, actob))
init_render_object(re, ob, NULL, NULL, NULL, timeoffset);