Removed the omat matrix from DupliObject.
authorLukas Tönne <lukas.toenne@gmail.com>
Thu, 23 Jan 2014 09:20:42 +0000 (10:20 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Thu, 23 Jan 2014 09:20:42 +0000 (10:20 +0100)
This was storing the original object matrix, which builds on the
assumption that obmat is modified during dupli construction, which is a
bad hack.

Now the obmats are still modified, but this only happens outside of the
dupli system itself and the original ("omat") is stored as local
variables in the same place where the obmat manipulation takes place.
This is easier to follow and avoids hidden hacks as much as possible.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D254

source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/intern/object_dupli.c
source/blender/blenkernel/intern/scene.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/gpu/intern/gpu_material.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/render/intern/source/convertblender.c

index 4ff1c8ba3a480ca4ca69bf175faa5bdda0a05f68..d19c281afb8ec6333e62f317fe114300533b86f6 100644 (file)
@@ -83,7 +83,8 @@ void         BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
 typedef struct SceneBaseIter {
        struct ListBase *duplilist;
        struct DupliObject *dupob;
-       int fase;
+       float omat[4][4];
+       int phase;
 } SceneBaseIter;
 
 int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
index 41d411b9b1cb68b5ae087aff760c464eb1744422..0671c8ea1714d788aeb395cc89520a31155ed7ea 100644 (file)
@@ -159,7 +159,6 @@ static DupliObject *make_dupli(const DupliContext *ctx,
 
        dob->ob = ob;
        mul_m4_m4m4(dob->mat, (float (*)[4])ctx->space_mat, mat);
-       copy_m4_m4(dob->omat, ob->obmat);
        dob->type = ctx->gen->type;
        dob->animated = animated || ctx->animated; /* object itself or some parent is animated */
 
@@ -378,7 +377,6 @@ static void make_duplis_frames(const DupliContext *ctx)
                        BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra);
 
                        dob = make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false);
-                       copy_m4_m4(dob->omat, copyob.obmat);
                }
        }
 
@@ -839,7 +837,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
        ParticleCacheKey *cache;
        float ctime, pa_time, scale = 1.0f;
        float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
-       float (*obmat)[4], (*oldobmat)[4];
+       float (*obmat)[4];
        int a, b, hair = 0;
        int totpart, totchild, totgroup = 0 /*, pa_num */;
        int dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene);
@@ -993,11 +991,9 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
 
                                ob = oblist[b];
                                obmat = oblist[b]->obmat;
-                               oldobmat = obcopylist[b].obmat;
                        }
                        else {
                                obmat = ob->obmat;
-                               oldobmat = obcopy.obmat;
                        }
 
                        if (hair) {
@@ -1045,7 +1041,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
 
                                        dob = make_dupli(ctx, go->ob, mat, a, false, false);
                                        dob->particle_system = psys;
-                                       copy_m4_m4(dob->omat, obcopylist[b].obmat);
                                        if (for_render)
                                                psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
                                }
@@ -1095,7 +1090,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
 
                                dob = make_dupli(ctx, ob, mat, a, false, false);
                                dob->particle_system = psys;
-                               copy_m4_m4(dob->omat, oldobmat);
                                if (for_render)
                                        psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
                                /* XXX blender internal needs this to be set to dupligroup to render
@@ -1218,7 +1212,6 @@ void free_object_duplilist(ListBase *lb)
         * solution is more complicated */
        for (dob = lb->last; dob; dob = dob->prev) {
                dob->ob->lay = dob->origlay;
-               copy_m4_m4(dob->ob->obmat, dob->omat);
        }
 
        BLI_freelistN(lb);
index ca6ff4dc1e5f1c0b304ae9eed834a032e66b6178..584aab9f84a32b05152f40e7468c633433001f08 100644 (file)
@@ -747,7 +747,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
        
        /* init */
        if (val == 0) {
-               iter->fase = F_START;
+               iter->phase = F_START;
                iter->dupob = NULL;
                iter->duplilist = NULL;
        }
@@ -757,11 +757,11 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                        run_again = 0;
 
                        /* the first base */
-                       if (iter->fase == F_START) {
+                       if (iter->phase == F_START) {
                                *base = (*scene)->base.first;
                                if (*base) {
                                        *ob = (*base)->object;
-                                       iter->fase = F_SCENE;
+                                       iter->phase = F_SCENE;
                                }
                                else {
                                        /* exception: empty scene */
@@ -770,20 +770,20 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                                                if ((*scene)->base.first) {
                                                        *base = (*scene)->base.first;
                                                        *ob = (*base)->object;
-                                                       iter->fase = F_SCENE;
+                                                       iter->phase = F_SCENE;
                                                        break;
                                                }
                                        }
                                }
                        }
                        else {
-                               if (*base && iter->fase != F_DUPLI) {
+                               if (*base && iter->phase != F_DUPLI) {
                                        *base = (*base)->next;
                                        if (*base) {
                                                *ob = (*base)->object;
                                        }
                                        else {
-                                               if (iter->fase == F_SCENE) {
+                                               if (iter->phase == F_SCENE) {
                                                        /* (*scene) is finished, now do the set */
                                                        while ((*scene)->set) {
                                                                (*scene) = (*scene)->set;
@@ -799,10 +799,10 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                        }
                        
                        if (*base == NULL) {
-                               iter->fase = F_START;
+                               iter->phase = F_START;
                        }
                        else {
-                               if (iter->fase != F_DUPLI) {
+                               if (iter->phase != F_DUPLI) {
                                        if ( (*base)->object->transflag & OB_DUPLI) {
                                                /* groups cannot be duplicated for mballs yet, 
                                                 * this enters eternal loop because of 
@@ -820,20 +820,21 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                                /* handle dupli's */
                                if (iter->dupob) {
                                        
+                                       copy_m4_m4(iter->omat, iter->dupob->ob->obmat);
                                        copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
                                        
                                        (*base)->flag |= OB_FROMDUPLI;
                                        *ob = iter->dupob->ob;
-                                       iter->fase = F_DUPLI;
+                                       iter->phase = F_DUPLI;
                                        
                                        iter->dupob = iter->dupob->next;
                                }
-                               else if (iter->fase == F_DUPLI) {
-                                       iter->fase = F_SCENE;
+                               else if (iter->phase == F_DUPLI) {
+                                       iter->phase = F_SCENE;
                                        (*base)->flag &= ~OB_FROMDUPLI;
                                        
                                        for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
-                                               copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat);
+                                               copy_m4_m4(iter->dupob->ob->obmat, iter->omat);
                                        }
                                        
                                        free_object_duplilist(iter->duplilist);
@@ -850,7 +851,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
        }
 #endif
 
-       return iter->fase;
+       return iter->phase;
 }
 
 Object *BKE_scene_camera_find(Scene *sc)
index 23252804b367dd788b86ac1f08b2ed03f1fe3339..ad5f393f9565d0463867cd22403ab4879e615a1d 100644 (file)
@@ -1960,6 +1960,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
        RegionView3D *rv3d = ar->regiondata;
        ListBase *lb;
        LodLevel *savedlod;
+       float savedobmat[4][4];
        DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
        Base tbase = {NULL};
        BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
@@ -1982,6 +1983,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
 
                /* Make sure lod is updated from dupli's position */
 
+               copy_m4_m4(savedobmat, dob->ob->obmat);
                copy_m4_m4(dob->ob->obmat, dob->mat);
                savedlod = dob->ob->currentlod;
                BKE_object_lod_update(dob->ob, rv3d->viewinv[3]);
@@ -2069,11 +2071,12 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
                tbase.object->dtx = dtx;
                tbase.object->transflag = transflag;
                tbase.object->currentlod = savedlod;
+               copy_m4_m4(tbase.object->obmat, savedobmat);
        }
        
        /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */
        
-       free_object_duplilist(lb);  /* does restore */
+       free_object_duplilist(lb);
        
        if (use_displist)
                glDeleteLists(displist, 1);
index dcbcb127f5c83a05449bbc191724905c3bf728c8..595e6dd98f2c7dc46c202dcac074518f76c8d9c1 100644 (file)
@@ -987,7 +987,10 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
                                                lb = object_duplilist(G.main->eval_ctx, scene, base->object);
                                                
                                                for (dob = lb->first; dob; dob = dob->next) {
+                                                       float omat[4][4];
+                                                       
                                                        tbase.object = dob->ob;
+                                                       copy_m4_m4(omat, dob->ob->obmat);
                                                        copy_m4_m4(dob->ob->obmat, dob->mat);
                                                        
                                                        /* extra service: draw the duplicator in drawtype of parent */
@@ -1000,7 +1003,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
                                                        tbase.object->dt = dt;
                                                        tbase.object->dtx = dtx;
 
-                                                       copy_m4_m4(dob->ob->obmat, dob->omat);
+                                                       copy_m4_m4(dob->ob->obmat, omat);
                                                }
                                                free_object_duplilist(lb);
                                        }
index a425153f4034d886f281489c69b1191b60335d61..7c67e6152178f465f5b2d404d3b19d07b976d71e 100644 (file)
@@ -859,11 +859,15 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
                                Object *ob_iter = dob->ob;
 
                                if (ob_iter->type==OB_LAMP) {
+                                       float omat[4][4];
+                                       copy_m4_m4(omat, ob_iter->obmat);
                                        copy_m4_m4(ob_iter->obmat, dob->mat);
 
                                        lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob_iter, ob);
                                        if (lamp)
                                                shade_one_light(shi, shr, lamp);
+
+                                       copy_m4_m4(ob_iter->obmat, omat);
                                }
                        }
                        
index 782d00fd2c946a45d859ac4438a4cee62eb81b83..1f18b054d0ed7082aad70f03083e83e9a453fb36 100644 (file)
@@ -317,7 +317,7 @@ typedef struct DupliObject {
        struct DupliObject *next, *prev;
        struct Object *ob;
        unsigned int origlay, pad;
-       float mat[4][4], omat[4][4];
+       float mat[4][4];
        float orco[3], uv[2];
 
        short type; /* from Object.transflag */
index d82fe46ea54fa541f69269ce6be5fcb487a4a2aa..41f34f0f40e3fd656871a360695b90cd542f4171 100644 (file)
@@ -2771,12 +2771,6 @@ static void rna_def_dupli_object(BlenderRNA *brna)
        /* RNA_def_property_pointer_funcs(prop, "rna_DupliObject_object_get", NULL, NULL, NULL); */
        RNA_def_property_ui_text(prop, "Object", "Object being duplicated");
 
-       prop = RNA_def_property(srna, "matrix_original", PROP_FLOAT, PROP_MATRIX);
-       RNA_def_property_float_sdna(prop, NULL, "omat");
-       RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
-       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Object Matrix", "The original matrix of this object before it was duplicated");
-
        prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
        RNA_def_property_float_sdna(prop, NULL, "mat");
        RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
index ca80757122025a15c2e69cc3e5f480fd8484248d..ae87aedf175700b29d5bf19f45f9d94134f512b6 100644 (file)
@@ -4519,7 +4519,7 @@ static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex)
        return NULL;
 }
 
-static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob)
+static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *dob, float omat[4][4])
 {
        /* For duplis we need to have a matrix that transform the coordinate back
         * to it's original position, without the dupli transforms. We also check
@@ -4557,7 +4557,7 @@ static void set_dupli_tex_mat(Render *re, ObjectInstanceRen *obi, DupliObject *d
 
                obi->duplitexmat= BLI_memarena_alloc(re->memArena, sizeof(float)*4*4);
                invert_m4_m4(imat, dob->mat);
-               mul_serie_m4(obi->duplitexmat, re->viewmat, dob->omat, imat, re->viewinv,
+               mul_serie_m4(obi->duplitexmat, re->viewmat, omat, imat, re->viewinv,
                             NULL, NULL, NULL, NULL);
        }
 
@@ -4607,7 +4607,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
        re->totstrand += obr->totstrand;
 }
 
-static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, int timeoffset)
+static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, float omat[4][4], int timeoffset)
 {
        ObjectRen *obr;
        ObjectInstanceRen *obi;
@@ -4643,7 +4643,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
                /* only add instance for objects that have not been used for dupli */
                if (!(ob->transflag & OB_RENDER_DUPLI)) {
                        obi= RE_addRenderInstance(re, obr, ob, par, index, 0, NULL, ob->lay);
-                       if (dob) set_dupli_tex_mat(re, obi, dob);
+                       if (dob) set_dupli_tex_mat(re, obi, dob, omat);
                }
                else
                        find_dupli_instances(re, obr, dob);
@@ -4677,7 +4677,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
                        /* only add instance for objects that have not been used for dupli */
                        if (!(ob->transflag & OB_RENDER_DUPLI)) {
                                obi= RE_addRenderInstance(re, obr, ob, par, index, psysindex, NULL, ob->lay);
-                               if (dob) set_dupli_tex_mat(re, obi, dob);
+                               if (dob) set_dupli_tex_mat(re, obi, dob, omat);
                        }
                        else
                                find_dupli_instances(re, obr, dob);
@@ -4687,7 +4687,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
 
 /* 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, DupliObject *dob, int timeoffset)
+static void init_render_object(Render *re, Object *ob, Object *par, DupliObject *dob, float omat[4][4], int timeoffset)
 {
        static double lasttime= 0.0;
        double time;
@@ -4696,7 +4696,7 @@ static void init_render_object(Render *re, Object *ob, Object *par, DupliObject
        if (ob->type==OB_LAMP)
                add_render_lamp(re, ob);
        else if (render_object_type(ob->type))
-               add_render_object(re, ob, par, dob, timeoffset);
+               add_render_object(re, ob, par, dob, omat, timeoffset);
        else {
                mul_m4_m4m4(mat, re->viewmat, ob->obmat);
                invert_m4_m4(ob->imat, mat);
@@ -4920,7 +4920,7 @@ static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, in
                if (ob->flag & OB_DONE) {
                        if (ob->transflag & OB_RENDER_DUPLI) {
                                if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
-                                       init_render_object(re, ob, NULL, NULL, timeoffset);
+                                       init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
                                        ob->transflag &= ~OB_RENDER_DUPLI;
 
                                        if (ob->dup_group)
@@ -4938,13 +4938,12 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
        Group *group;
        ObjectInstanceRen *obi;
        Scene *sce_iter;
-       float mat[4][4];
        int lay, vectorlay;
 
        /* for duplis we need the Object texture mapping to work as if
         * untransformed, set_dupli_tex_mat sets the matrix to allow that
         * NULL is just for init */
-       set_dupli_tex_mat(NULL, NULL, NULL);
+       set_dupli_tex_mat(NULL, NULL, NULL, NULL);
 
        /* loop over all objects rather then using SETLOOPER because we may
         * reference an mtex-mapped object which isn't rendered or is an
@@ -4953,6 +4952,8 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
         * 'imat' / 'imat_ren' on all and unlikely to be a performance hit
         * See bug: [#28744] - campbell */
        for (ob= re->main->object.first; ob; ob= ob->id.next) {
+               float mat[4][4];
+               
                /* imat objects has to be done here, since displace can have texture using Object map-input */
                mul_m4_m4m4(mat, re->viewmat, ob->obmat);
                invert_m4_m4(ob->imat_ren, mat);
@@ -4980,7 +4981,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                         * it still needs to create the ObjectRen containing the data */
                        if (ob->transflag & OB_RENDER_DUPLI) {
                                if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
-                                       init_render_object(re, ob, NULL, NULL, timeoffset);
+                                       init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
                                        ob->transflag &= ~OB_RENDER_DUPLI;
                                }
                        }
@@ -4998,7 +4999,9 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
 
                                for (dob= lb->first; dob; dob= dob->next) {
                                        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 */
@@ -5031,7 +5034,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);
+                                                       set_dupli_tex_mat(re, obi, dob, omat);
                                                        if (dob->type != OB_DUPLIGROUP) {
                                                                copy_v3_v3(obi->dupliorco, dob->orco);
                                                                obi->dupliuv[0]= dob->uv[0];
@@ -5057,7 +5060,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);
+                                                               set_dupli_tex_mat(re, obi, dob, omat);
                                                                if (dob->type != OB_DUPLIGROUP) {
                                                                        copy_v3_v3(obi->dupliorco, dob->orco);
                                                                        obi->dupliuv[0]= dob->uv[0];
@@ -5073,7 +5076,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, timeoffset);
+                                                       init_render_object(re, obd, ob, dob, omat, timeoffset);
                                                
                                                if (dob->type != OB_DUPLIGROUP) {
                                                        obd->flag |= OB_DONE;
@@ -5081,17 +5084,19 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                                }
                                        }
                                        else
-                                               init_render_object(re, obd, ob, dob, timeoffset);
+                                               init_render_object(re, obd, ob, dob, omat, timeoffset);
+                                       
+                                       copy_m4_m4(obd->obmat, omat);
                                        
                                        if (re->test_break(re->tbh)) break;
                                }
                                free_object_duplilist(lb);
 
                                if (allow_render_object(re, ob, nolamps, onlyselected, actob))
-                                       init_render_object(re, ob, NULL, NULL, timeoffset);
+                                       init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
                        }
                        else if (allow_render_object(re, ob, nolamps, onlyselected, actob))
-                               init_render_object(re, ob, NULL, NULL, timeoffset);
+                               init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
                }
 
                if (re->test_break(re->tbh)) break;