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:
authorBastien Montagne <montagne29@wanadoo.fr>2014-07-19 00:31:33 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-07-19 02:41:13 +0400
commite0d8e62f2bb97d75088f7f1fd9f0fab578a02410 (patch)
tree27d3aa656684d2bd34f49a9d5169cbb7ce8bc936
parenta474125893bc5db227b1b5f90233bc51c89b5c68 (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.
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/intern/scene.c37
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;
}
}
}