Revision: 35429
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35429
Author:   jesterking
Date:     2011-03-09 14:16:21 +0000 (Wed, 09 Mar 2011)
Log Message:
-----------
Fix [#26012] Import Collada: instance_node incorrectly handled
Reported by David Roy

When <instance_node>s where read, their transformation matrix got overwritten 
with the transform matrix
of their own node, not taking into account the parent node transformation. 
Instead of doing
that we now get the parent node transformation matrix and apply it to its own, 
and prevent
caller from overwriting this new transformation matrix.

Modified Paths:
--------------
    trunk/blender/source/blender/collada/AnimationImporter.cpp
    trunk/blender/source/blender/collada/DocumentImporter.cpp

Modified: trunk/blender/source/blender/collada/AnimationImporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/AnimationImporter.cpp  2011-03-09 
13:47:54 UTC (rev 35428)
+++ trunk/blender/source/blender/collada/AnimationImporter.cpp  2011-03-09 
14:16:21 UTC (rev 35429)
@@ -405,6 +405,9 @@
        return true;
 }
 
+// \todo refactor read_node_transform to not automatically apply anything,
+// but rather return the transform matrix, so caller can do with it what is
+// necessary. Same for \ref get_node_mat
 void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob)
 {
        float mat[4][4];

Modified: trunk/blender/source/blender/collada/DocumentImporter.cpp
===================================================================
--- trunk/blender/source/blender/collada/DocumentImporter.cpp   2011-03-09 
13:47:54 UTC (rev 35428)
+++ trunk/blender/source/blender/collada/DocumentImporter.cpp   2011-03-09 
14:16:21 UTC (rev 35429)
@@ -75,6 +75,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DocumentImporter.h"
+#include "TransformReader.h"
 #include "collada_internal.h"
 
 #include "collada_utils.h"
@@ -336,10 +337,29 @@
                obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
                scene_add_base(sce, obn);
 
-               if (instance_node)
+               if (instance_node) {
                        anim_importer.read_node_transform(instance_node, obn);
-               else
+                       // if we also have a source_node (always ;), take its
+                       // transformation matrix and apply it to the newly 
instantiated
+                       // object to account for node hierarchy transforms in
+                       // .dae
+                       if(source_node) {
+                               COLLADABU::Math::Matrix4 mat4 = 
source_node->getTransformationMatrix();
+                               COLLADABU::Math::Matrix4 bmat4 = 
mat4.transpose(); // transpose to get blender row-major order
+                               float mat[4][4];
+                               for (int i = 0; i < 4; i++) {
+                                       for (int j = 0; j < 4; j++) {
+                                               mat[i][j] = bmat4[i][j];
+                                       }
+                               }
+                               // calc new matrix and apply
+                               mul_m4_m4m4(obn->obmat, mat, obn->obmat);
+                               object_apply_mat4(obn, obn->obmat, 0, 0);
+                       }
+               }
+               else {
                        anim_importer.read_node_transform(source_node, obn);
+               }
 
                DAG_scene_sort(CTX_data_main(mContext), sce);
                DAG_ids_flush_update(CTX_data_main(mContext), 0);
@@ -353,7 +373,7 @@
                                        continue;
                                COLLADAFW::InstanceNodePointerArray &inodes = 
child_node->getInstanceNodes();
                                Object *new_child = NULL;
-                               if (inodes.getCount()) {
+                               if (inodes.getCount()) { // \todo loop through 
instance nodes
                                        const COLLADAFW::UniqueId& id = 
inodes[0]->getInstanciatedObjectId();
                                        new_child = 
create_instance_node(object_map[id], node_map[id], child_node, sce, 
is_library_node);
                                }
@@ -367,7 +387,10 @@
                        }
                }
 
-               return obn;
+               // when we have an instance_node, don't return the object, 
because otherwise
+               // its correct location gets overwritten in write_node(). Fixes 
bug #26012.
+               if(instance_node) return NULL;
+               else return obn;
        }
        
        void DocumentImporter::write_node (COLLADAFW::Node *node, 
COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
@@ -444,7 +467,7 @@
                                libnode_ob.push_back(ob);
                }
 
-               anim_importer.read_node_transform(node, ob);
+               anim_importer.read_node_transform(node, ob); // overwrites 
location set earlier
 
                if (!is_joint) {
                        // if par was given make this object child of the 
previous 

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

Reply via email to