diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-07-19 00:31:33 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-07-19 02:41:13 +0400 |
commit | e0d8e62f2bb97d75088f7f1fd9f0fab578a02410 (patch) | |
tree | 27d3aa656684d2bd34f49a9d5169cbb7ce8bc936 /source/blender/blenkernel | |
parent | a474125893bc5db227b1b5f90233bc51c89b5c68 (diff) |
Fix T41010: MetaBall Duplivert Unwanted Movement Bug.
BKE_scene_base_iter_next() was completely messing poor dupli objects' matrices...
Note this func should be reworked, but as stated in comments, it should not exist at all,
DAG should be used here, so until we have new shinny one we can live with this.
Also, mballs do not behave correctly when used as duplis (org object remains visible/rendered,
unlike any other object type). This will be fixed in a separate patch/commit,
since it proved to be rather tricky to handle.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_scene.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 37 |
2 files changed, 25 insertions, 13 deletions
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index a10a3f3f59f..452e23bdcb8 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -84,6 +84,7 @@ typedef struct SceneBaseIter { struct ListBase *duplilist; struct DupliObject *dupob; float omat[4][4]; + struct Object *dupli_refob; int phase; } SceneBaseIter; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f8ce31f1b8a..66b2e3c6e97 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -804,9 +804,7 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) BKE_libblock_free(bmain, sce); } -/* used by metaballs - * doesn't return the original duplicated object, only dupli's - */ +/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter, Scene **scene, int val, Base **base, Object **ob) { @@ -817,11 +815,12 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter, iter->phase = F_START; iter->dupob = NULL; iter->duplilist = NULL; + iter->dupli_refob = NULL; } else { /* run_again is set when a duplilist has been ended */ while (run_again) { - run_again = 0; + run_again = false; /* the first base */ if (iter->phase == F_START) { @@ -879,34 +878,46 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter, iter->dupob = iter->duplilist->first; - if (!iter->dupob) + if (!iter->dupob) { free_object_duplilist(iter->duplilist); + iter->duplilist = NULL; + } + iter->dupli_refob = NULL; } } } /* 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->phase = F_DUPLI; - + + if (iter->dupli_refob != *ob) { + if (iter->dupli_refob) { + /* Restore previous object's real matrix. */ + copy_m4_m4(iter->dupli_refob->obmat, iter->omat); + } + /* Backup new object's real matrix. */ + iter->dupli_refob = *ob; + copy_m4_m4(iter->omat, iter->dupli_refob->obmat); + } + copy_m4_m4((*ob)->obmat, iter->dupob->mat); + iter->dupob = iter->dupob->next; } 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->omat); + if (iter->dupli_refob) { + /* Restore last object's real matrix. */ + copy_m4_m4(iter->dupli_refob->obmat, iter->omat); + iter->dupli_refob = NULL; } free_object_duplilist(iter->duplilist); iter->duplilist = NULL; - run_again = 1; + run_again = true; } } } |