[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28014] branches/soc-2009-chingachgook/ source/blender/collada/DocumentImporter.cpp: COLLADA branch: import matrix animations.

Arystanbek Dyussenov arystan.d at gmail.com
Mon Apr 5 17:43:36 CEST 2010


Revision: 28014
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28014
Author:   kazanbas
Date:     2010-04-05 17:43:36 +0200 (Mon, 05 Apr 2010)

Log Message:
-----------
COLLADA branch: import matrix animations.
Discovered that importer sets object parents incorrectly - still got to figure out how to fix.

Modified Paths:
--------------
    branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp

Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2010-04-05 14:21:57 UTC (rev 28013)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp	2010-04-05 15:43:36 UTC (rev 28014)
@@ -174,6 +174,57 @@
 		return array.getDoubleValues()->getData()[index];
 }
 
+#if 0
+// copied from /editors/object/object_relations.c
+static int test_parent_loop(Object *par, Object *ob)
+{
+	/* test if 'ob' is a parent somewhere in par's parents */
+	
+	if(par == NULL) return 0;
+	if(ob == par) return 1;
+	
+	return test_parent_loop(par->parent, ob);
+}
+
+// a shortened version of parent_set_exec()
+static int set_parent(Object *ob, Object *par, bContext *C)
+{
+	if (!par || test_parent_loop(par, ob))
+		return false;
+
+	Object workob;
+	Scene *sce = CTX_data_scene(C);
+
+	ob->parent = par;
+	ob->partype = PAROBJECT;
+
+	ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
+	par->recalc |= OB_RECALC_OB;
+
+	ob->parsubstr[0] = 0;
+
+	where_is_object(sce, par);
+
+	// // move child obmat into world space
+	// float mat[4][4];
+	// copy_m4_m4(mat, ob->obmat);
+	// mul_m4_m4m4(ob->obmat, mat, par->obmat);
+	
+	// apply child obmat (i.e. decompose into rot/loc/size)
+	ED_object_apply_obmat(ob);
+
+	// compute parentinv
+	what_does_parent(sce, ob, &workob);
+	invert_m4_m4(ob->parentinv, workob.obmat);
+
+	DAG_scene_sort(sce);
+	DAG_ids_flush_update(0);
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+
+	return true;
+}
+#endif
+
 typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap;
 
 class TransformReader : public TransformBase
@@ -341,6 +392,7 @@
 	std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid;
 	std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
 	std::vector<COLLADAFW::Node*> root_joints;
+	std::map<COLLADAFW::UniqueId, Object*> joint_parent_map;
 
 	std::vector<Object*> armature_objects;
 
@@ -375,6 +427,7 @@
 
 		Object *ob_arm;
 		COLLADAFW::UniqueId controller_uid;
+		Object *parent;
 
 	public:
 
@@ -384,7 +437,8 @@
 										 joint_data(skin.joint_data),
 										 unit_converter(skin.unit_converter),
 										 ob_arm(skin.ob_arm),
-										 controller_uid(skin.controller_uid)
+										 controller_uid(skin.controller_uid),
+										 parent(skin.parent)
 		{
 			copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix);
 
@@ -393,7 +447,7 @@
 			transfer_int_array_data_const(skin.joint_indices, joint_indices);
 		}
 
-		SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL) {}
+		SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {}
 
 		// nobody owns the data after this, so it should be freed manually with releaseMemory
 		template <class T>
@@ -520,14 +574,17 @@
 		void link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
 						   TransformReader *tm)
 		{
-			Object workob;
 			Scene *scene = CTX_data_scene(C);
 
 			ModifierData *md = ED_object_modifier_add(NULL, scene, ob, NULL, eModifierType_Armature);
 			((ArmatureModifierData *)md)->object = ob_arm;
 
 			tm->decompose(bind_shape_matrix, ob->loc, ob->rot, NULL, ob->size);
-
+			
+#if 0
+			::set_parent(ob, ob_arm, C);
+#else
+			Object workob;
 			ob->parent = ob_arm;
 			ob->partype = PAROBJECT;
 
@@ -536,6 +593,11 @@
 
 			ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
 
+			DAG_scene_sort(scene);
+			DAG_ids_flush_update(0);
+			WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+#endif
+
 			((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP;
 
 			// create all vertex groups
@@ -577,16 +639,23 @@
 					}
 				}
 			}
-
-			DAG_scene_sort(scene);
-			DAG_ids_flush_update(0);
-			WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
 		}
 
 		bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node)
 		{
 			return get_pose_channel(ob_arm->pose, get_joint_name(node));
 		}
+
+		void set_parent(Object *_parent)
+		{
+			parent = _parent;
+		}
+
+		Object* get_parent()
+		{
+			return parent;
+		}
+
 	};
 
 	std::map<COLLADAFW::UniqueId, SkinInfo> skin_by_data_uid; // data UID = skin controller data UID
@@ -856,6 +925,9 @@
 			// since root_joints may contain joints for multiple controllers, we need to filter
 			if (skin.uses_joint(*it)) {
 				create_bone(skin, *it, NULL, (*it)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
+
+				if (joint_parent_map.find((*it)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
+					skin.set_parent(joint_parent_map[(*it)->getUniqueId()]);
 			}
 		}
 
@@ -889,10 +961,15 @@
 	// root - if this joint is the top joint in hierarchy, if a joint
 	// is a child of a node (not joint), root should be true since
 	// this is where we build armature bones from
-	void add_joint(COLLADAFW::Node *node, bool root)
+	void add_joint(COLLADAFW::Node *node, bool root, Object *parent)
 	{
 		joint_by_uid[node->getUniqueId()] = node;
-		if (root) root_joints.push_back(node);
+		if (root) {
+			root_joints.push_back(node);
+
+			if (parent)
+				joint_parent_map[node->getUniqueId()] = parent;
+		}
 	}
 
 #if 0
@@ -921,15 +998,20 @@
 
 			create_armature_bones(skin);
 
-			// link armature with an object
+			// link armature with a mesh object
 			Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
-			if (ob) {
+			if (ob)
 				skin.link_armature(C, ob, joint_by_uid, this);
-			}
-			else {
+			else
 				fprintf(stderr, "Cannot find object to link armature with.\n");
-			}
 
+#if 0
+			// set armature parent if any
+			Object *par = skin.get_parent();
+			if (par)
+				set_parent(skin.get_armature(), par, C);
+#endif
+
 			// free memory stolen from SkinControllerData
 			skin.free();
 		}
@@ -1901,77 +1983,50 @@
 
 		std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
 
-		if (dim == 1) {
-			FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
-
-			fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
-			// fcu->rna_path = BLI_strdupn(path, strlen(path));
-			fcu->array_index = 0;
-			//fcu->totvert = curve->getKeyCount();
-			
-			// create beztriple for each key
-			for (i = 0; i < curve->getKeyCount(); i++) {
-				BezTriple bez;
-				memset(&bez, 0, sizeof(BezTriple));
-
-				// intangent
-				// bez.vec[0][0] = get_float_value(intan, i + i) * fps;
-				// bez.vec[0][1] = get_float_value(intan, i + i + 1);
-
-				// input, output
-				bez.vec[1][0] = get_float_value(input, i) * fps;
-				bez.vec[1][1] = get_float_value(output, i);
-
-				// outtangent
-				// bez.vec[2][0] = get_float_value(outtan, i + i) * fps;
-				// bez.vec[2][1] = get_float_value(outtan, i + i + 1);
+		switch (dim) {
+		case 1: // X, Y, Z or angle
+		case 3: // XYZ
+		case 16: // matrix
+			{
+				for (i = 0; i < dim; i++ ) {
+					FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
 				
-				bez.ipo = U.ipo_new; /* use default interpolation mode here... */
-				bez.f1 = bez.f2 = bez.f3 = SELECT;
-				bez.h1 = bez.h2 = HD_AUTO;
-				insert_bezt_fcurve(fcu, &bez, 0);
-			}
+					fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
+					// fcu->rna_path = BLI_strdupn(path, strlen(path));
+					fcu->array_index = 0;
+					//fcu->totvert = curve->getKeyCount();
+				
+					// create beztriple for each key
+					for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
+						BezTriple bez;
+						memset(&bez, 0, sizeof(BezTriple));
 
-			calchandles_fcurve(fcu);
+						// intangent
+						// bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
+						// bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
 
-			fcurves.push_back(fcu);
-		}
-		else if(dim == 3) {
-			for (i = 0; i < dim; i++ ) {
-				FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
-				
-				fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
-				// fcu->rna_path = BLI_strdupn(path, strlen(path));
-				fcu->array_index = 0;
-				//fcu->totvert = curve->getKeyCount();
-				
-				// create beztriple for each key
-				for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
-					BezTriple bez;
-					memset(&bez, 0, sizeof(BezTriple));
+						// input, output
+						bez.vec[1][0] = get_float_value(input, j) * fps; 
+						bez.vec[1][1] = get_float_value(output, j * dim + i);
 
-					// intangent
-					// bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
-					// bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
+						// outtangent
+						// bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
+						// bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
 
-					// input, output
-					bez.vec[1][0] = get_float_value(input, j) * fps; 
-					bez.vec[1][1] = get_float_value(output, j * 3 + i);
+						bez.ipo = U.ipo_new; /* use default interpolation mode here... */
+						bez.f1 = bez.f2 = bez.f3 = SELECT;
+						bez.h1 = bez.h2 = HD_AUTO;
+						insert_bezt_fcurve(fcu, &bez, 0);
+					}
 
-					// outtangent
-					// bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
-					// bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
+					calchandles_fcurve(fcu);
 
-					bez.ipo = U.ipo_new; /* use default interpolation mode here... */
-					bez.f1 = bez.f2 = bez.f3 = SELECT;
-					bez.h1 = bez.h2 = HD_AUTO;
-					insert_bezt_fcurve(fcu, &bez, 0);
+					fcurves.push_back(fcu);
 				}
-
-				calchandles_fcurve(fcu);
-
-				fcurves.push_back(fcu);
 			}
+			break;
+		default:
+			fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", dim, curve->getOriginalId().c_str());
 		}
 
 		for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
@@ -2242,8 +2297,10 @@
 	{
 		float mat[4][4];
 		TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
-		if (ob)
-			TransformReader::decompose(mat, ob->loc, ob->rot, NULL, ob->size);
+		if (ob) {
+			copy_m4_m4(ob->obmat, mat);
+			ED_object_apply_obmat(ob);
+		}
 	}
 	
 #if 0
@@ -2349,7 +2406,9 @@
 								Object *par_job = NULL)
 	{
 		bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
+		bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
 		bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list