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:
authorNathan Letwory <nathan@letworyinteractive.com>2011-03-09 17:16:21 +0300
committerNathan Letwory <nathan@letworyinteractive.com>2011-03-09 17:16:21 +0300
commit3e8c838a99830012d447d218975653858d6c6ccf (patch)
tree161f21c80da4dd5172fae78a2b0e81badc167cfd /source/blender/collada
parenta23351fbb2beb8c4ffbbe6792d4114a118be6f7d (diff)
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.
Diffstat (limited to 'source/blender/collada')
-rw-r--r--source/blender/collada/AnimationImporter.cpp3
-rw-r--r--source/blender/collada/DocumentImporter.cpp33
2 files changed, 31 insertions, 5 deletions
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index cba39b04c3c..85fc6e3cbeb 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -405,6 +405,9 @@ bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* ani
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];
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 9669266d851..b4264f88b2f 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -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 @@ private:
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 @@ private:
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 @@ private:
}
}
- 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 @@ private:
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