Revision: 27748
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27748
Author:   blendix
Date:     2010-03-25 17:02:00 +0100 (Thu, 25 Mar 2010)

Log Message:
-----------
Render Branch: Yet another fix for group transform, it was suffering from
numerical drift, now we backup matrices and restore if they were not modified.

Modified Paths:
--------------
    branches/render25/source/blender/blenkernel/intern/group.c
    branches/render25/source/blender/blenkernel/intern/object.c
    branches/render25/source/blender/makesdna/DNA_object_types.h

Modified: branches/render25/source/blender/blenkernel/intern/group.c
===================================================================
--- branches/render25/source/blender/blenkernel/intern/group.c  2010-03-25 
15:21:31 UTC (rev 27747)
+++ branches/render25/source/blender/blenkernel/intern/group.c  2010-03-25 
16:02:00 UTC (rev 27748)
@@ -331,16 +331,23 @@
 void group_handle_recalc_and_update(Scene *scene, Object *parent, Group *group)
 {
        GroupObject *go;
+       float (*parentinv)[4][4], (*obmat)[4][4];
        float parmat[4][4], iparmat[4][4];
-       int need_recalc= 0;
+       int need_recalc= 0, tot= 0, a;
 
        /* test if we need a recalculation */
-       for(go= group->gobject.first; go; go= go->next)
+       for(go= group->gobject.first; go; go= go->next) {
+               tot++;
+
                if(go->ob && (go->recalc || go->ob->recalc))
                        need_recalc= 1;
+       }
        
        if(!need_recalc)
                return;
+       
+       parentinv= MEM_callocN(sizeof(float)*4*4*tot, "group parentinv");
+       obmat= MEM_callocN(sizeof(float)*4*4*tot, "group obmat");
 
        if(group->id.lib) {
                /* in case of linked groups, we ensure all object matrices are
@@ -350,14 +357,18 @@
                copy_m4_m4(parmat, parent->obmat);
                invert_m4_m4(iparmat, parmat);
 
-               for(go= group->gobject.first; go; go= go->next) {
+               for(a=0, go= group->gobject.first; go; go= go->next, a++) {
                        if(go->ob) {
+                               copy_m4_m4(parentinv[a], go->ob->parentinv);
+                               copy_m4_m4(obmat[a], go->ob->obmat);
+
                                mul_m4_m4m4(go->ob->obmat, go->ob->obmat, 
parmat);
                                mul_m4_m4m4(go->ob->parentinv, 
go->ob->parentinv, iparmat);
 
                                /* this is applied in where_is_object_time in 
case the 
                                   matrix is recalculated */
                                go->ob->groupmat= (float*)parmat;
+                               go->ob->groupmodified= 0;
                        }
                }
        }
@@ -395,15 +406,25 @@
        }
 
        if(group->id.lib) {
-               for(go= group->gobject.first; go; go= go->next) {
+               for(a=0, go= group->gobject.first; go; go= go->next, a++) {
                        if(go->ob) {
-                               mul_m4_m4m4(go->ob->obmat, go->ob->obmat, 
iparmat);
-                               mul_m4_m4m4(go->ob->parentinv, 
go->ob->parentinv, parmat);
+                               /* we restore object matrices by copy to avoid 
numerical
+                                  drift, also matrices may not be exactly 
invertible */
+                               if(go->ob->groupmodified)
+                                       mul_m4_m4m4(go->ob->obmat, 
go->ob->obmat, iparmat);
+                               else
+                                       copy_m4_m4(go->ob->obmat, obmat[a]);
 
+                               copy_m4_m4(go->ob->parentinv, parentinv[a]);
+
                                go->ob->groupmat= NULL;
+                               go->ob->groupmodified= 0;
                        }
                }
        }
+
+       MEM_freeN(parentinv);
+       MEM_freeN(obmat);
 }
 
 Object *group_get_member_with_action(Group *group, bAction *act)

Modified: branches/render25/source/blender/blenkernel/intern/object.c
===================================================================
--- branches/render25/source/blender/blenkernel/intern/object.c 2010-03-25 
15:21:31 UTC (rev 27747)
+++ branches/render25/source/blender/blenkernel/intern/object.c 2010-03-25 
16:02:00 UTC (rev 27748)
@@ -2014,8 +2014,9 @@
                   so that e.g. physics systems are executed in the correct
                   space. this is enabled in group_handle_recalc_and_update */
                mul_m4_m4m4(ob->obmat, ob->obmat, (float(*)[4])ob->groupmat);
+               ob->groupmodified= 1;
        }
-       
+
        if(ob->parent) {
                Object *par= ob->parent;
                

Modified: branches/render25/source/blender/makesdna/DNA_object_types.h
===================================================================
--- branches/render25/source/blender/makesdna/DNA_object_types.h        
2010-03-25 15:21:31 UTC (rev 27747)
+++ branches/render25/source/blender/makesdna/DNA_object_types.h        
2010-03-25 16:02:00 UTC (rev 27748)
@@ -255,7 +255,10 @@
        ListBase gpulamp;               /* runtime, for lamps only */
        ListBase pc_ids;
        ListBase *duplilist;    /* for temporary dupli list storage, only for 
use by RNA API */
+
        float *groupmat;                /* runtime, temporarily set during 
group evaluation */
+       int groupmodified;              /* runtime, to indicate if we modified 
object matrix */
+       int pad3;
 } Object;
 
 /* Warning, this is not used anymore because hooks are now modifiers */


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to