[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48022] branches/soc-2012-bratwurst/source /blender/assimp: - bf_assimp: further work on animation importer.

Alexander Gessler alexander.gessler at gmx.net
Mon Jun 18 04:42:52 CEST 2012


Revision: 48022
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48022
Author:   aramis_acg
Date:     2012-06-18 02:42:44 +0000 (Mon, 18 Jun 2012)
Log Message:
-----------
- bf_assimp: further work on animation importer. Bones and nodes now have separate handling. 
- bf_assimp: re-design object import. Assimp nodes with multiple meshes, lights or cameras attached should now get attached to dummy nodes to avoid name conflicts.

Modified Paths:
--------------
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h
    branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp
    branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.h

Modified: branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp	2012-06-18 02:13:11 UTC (rev 48021)
+++ branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp	2012-06-18 02:42:44 UTC (rev 48022)
@@ -57,16 +57,18 @@
 	const aiScene& in_scene, 
 	Scene& out_scene, 
 	unsigned int in_anim_index, 
-	const Object& ob_armature)
-: armature(*static_cast<bArmature*>(ob_armature.data)) 
-, ob_armature(ob_armature)
+	const Object* ob_armature)
+
+: ob_armature(ob_armature)
+, armature(ob_armature ? static_cast<bArmature*>(ob_armature->data) : NULL) 
 , out_scene(out_scene)
 , in_anim(in_anim)
 , in_anim_index(in_anim_index)
 , in_scene(in_scene)
 , scene_imp(scene_imp)
 {
-	assert(ob_armature.type == OB_ARMATURE);
+	assert(!ob_armature || ob_armature->type == OB_ARMATURE);
+	assert(!!ob_armature == !!armature);
 
 	std::stringstream ss;
 	ss << "animation-" << in_anim_index;
@@ -106,18 +108,100 @@
 }
 
 
+const aiNode* AnimationImporter::node_for_node_anim(const aiNodeAnim& anim)
+{
+	return scene_imp.get_node_by_name(anim.mNodeName.C_Str());
+}
+
+
 void AnimationImporter::convert_node_anim(const aiNodeAnim& anim)
 {
-	verbose(("convert node animation: " + std::string(anim.mNodeName.C_Str())).c_str());
+	// first find out if this node is a Bone (i.e. part of armature) or a node or both
+	const aiNode* nd = node_for_node_anim(anim);
+	assert(nd);
 
+	if(scene_imp.has_mesh_descendants(*nd)) {
+		Object* const obj = scene_imp.get_bobject_for_node(*nd);
+		assert(obj);
+
+		convert_node_anim_for_bobject(anim, *nd, *obj);
+	}
+
+	if(armature) {
+		// XXX why does BKE_armature_find_bone_name not take const bArmature*?
+		Bone* const bone = BKE_armature_find_bone_name(const_cast<bArmature*>(armature), anim.mNodeName.C_Str());
+		if(bone) {
+			convert_node_anim_for_bone(anim,*bone);
+		}
+	}
+}
+
+
+void AnimationImporter::convert_node_anim_for_bobject(const aiNodeAnim& anim, const aiNode& nd, Object& ob)
+{
+	verbose(("convert node animation (target is object): " + std::string(anim.mNodeName.C_Str())).c_str());
+
 	// 10 curves: rotation_quaternion, location and scale
 	FCurve *newcu[10] = {0};
 
 	setup_empty_fcurves(newcu,anim);
 	populate_fcurves(newcu,anim);
+
+	// setup correct rotation mode
+	ob.rotmode = ROT_MODE_QUAT;
+
+	ListBase* curves = NULL;
+
+	// add curves to object
+	for (int i = 0; i < 10; i++) {
+		if (!newcu[i]){
+			continue;
+		}
+
+		// only add adt if needed - in many cases all fcurves will be NULL
+		// since assimp always writes node anim channels, even if no
+		// animation exists (i.e. it writes constant values taken from
+		// the corr. node trafo).
+		if(!curves) {
+			verify_adt_action(&ob.id, 1);
+			curves = &ob.adt->action->curves;
+		}
+
+		BLI_addtail(curves, newcu[i]);
+	}
 }
 
 
+void AnimationImporter::convert_node_anim_for_bone(const aiNodeAnim& anim, Bone& bone)
+{
+	assert(ob_armature);
+	assert(armature);
+
+	verbose(("convert node animation (target is bone)" + std::string(anim.mNodeName.C_Str())).c_str());
+
+	// 10 curves: rotation_quaternion, location and scale
+	FCurve *newcu[10] = {0};
+
+	setup_empty_fcurves(newcu,anim);
+	populate_fcurves(newcu,anim);
+
+	// setup correct rotation mode for pose
+	bPoseChannel* const chan = BKE_pose_channel_find_name(ob_armature->pose, anim.mNodeName.C_Str());
+	chan->rotmode = ROT_MODE_QUAT;
+
+	verify_adt_action((ID *)&ob_armature->id, 1);
+
+	// add curves to bone
+	for (int i = 0; i < 10; i++) {
+		if (!newcu[i]){
+			continue;
+		}
+
+		add_bone_fcurve(anim.mNodeName.C_Str(), newcu[i]);
+	}
+}
+
+
 void AnimationImporter::setup_empty_fcurves(FCurve* curves_out[10], const aiNodeAnim& anim)
 {
 	char joint_path[200];
@@ -211,38 +295,13 @@
 			add_bezt(curves_out[9], time, v.mValue.z);
 		}
 	}
-
-	verify_adt_action((ID *)&ob_armature.id, 1);
-	ListBase *curves = &ob_armature.adt->action->curves;
-
-	// add curves
-	for (int i = 0; i < 10; i++) {
-		if (!curves_out[i]){
-			continue;
-		}
-		add_bone_fcurve(anim.mNodeName.C_Str(), curves_out[i]);
-	}
-
-	bPoseChannel* const chan = BKE_pose_channel_find_name(ob_armature.pose, anim.mNodeName.C_Str());
-	chan->rotmode = ROT_MODE_QUAT;
-
-	/*
-	if (is_joint) {
-		bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name);
-		chan->rotmode = ROT_MODE_QUAT;
-	}
-	else {
-		ob->rotmode = ROT_MODE_QUAT;
-	}*/
-	
-
-	return;
 }
 
 
 void AnimationImporter::add_bone_fcurve(const char* bone_name, FCurve *fcu)
 {
-	bAction *act = ob_armature.adt->action;
+	assert(ob_armature);
+	bAction *act = ob_armature->adt->action;
 
 	/* try to find group */
 	bActionGroup *grp = BKE_action_group_find_name(act, bone_name);

Modified: branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h	2012-06-18 02:13:11 UTC (rev 48021)
+++ branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h	2012-06-18 02:42:44 UTC (rev 48022)
@@ -38,8 +38,9 @@
 {
 private:
 
-	const bArmature& armature;
-	const Object& ob_armature;
+	// armature is optional, anims need not be coupled with skinning info
+	const Object* ob_armature;
+	const bArmature* armature;
 
 	Scene& out_scene;
 	const aiAnimation& in_anim;
@@ -59,8 +60,12 @@
 	void add_bone_fcurve(const char* bone_name, FCurve *fcu);
 	FCurve* create_fcurve(int array_index, const char *rna_path);
 	void add_bezt(FCurve *fcu, float fra, float value);
+	const aiNode* node_for_node_anim(const aiNodeAnim& anim);
 
 	void convert_node_anim(const aiNodeAnim& anim);
+	void convert_node_anim_for_bobject(const aiNodeAnim& anim, const aiNode& nd, Object& ob);
+	void convert_node_anim_for_bone(const aiNodeAnim& anim, Bone& bone);
+
 	void setup_empty_fcurves(FCurve* curves_out[10], const aiNodeAnim& anim);
 	void populate_fcurves(FCurve* const curves_out[10], const aiNodeAnim& anim);
 
@@ -70,7 +75,7 @@
 		const aiScene& in_scene, 
 		Scene& out_scene, 
 		unsigned int in_anim_index, 
-		const Object& ob_armature);
+		const Object* ob_armature);
 
 	~AnimationImporter();
 

Modified: branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp	2012-06-18 02:13:11 UTC (rev 48021)
+++ branches/soc-2012-bratwurst/source/blender/assimp/SceneImporter.cpp	2012-06-18 02:42:44 UTC (rev 48022)
@@ -62,6 +62,7 @@
 , C(C)
 , scene()
 , out_scene(CTX_data_scene(C))
+, armature()
 {
 }
 
@@ -127,6 +128,8 @@
 		return false;
 	}
 
+	populate_node_name_map(scene->mRootNode);
+
 	// generate the subgraph of all mesh-carrier nodes
 	populate_mesh_node_graph(scene->mRootNode);
 
@@ -146,6 +149,7 @@
 	}
 
 	convert_node(*scene->mRootNode,NULL);
+	convert_armature();
 	convert_animations();
 
 	verbose("conversion to blender Scene ok");
@@ -173,31 +177,29 @@
 	rot.rotate_90deg_xpositive();
 }
 
-
-void SceneImporter::convert_animations() 
+void SceneImporter::convert_armature() 
 {
 	if (!has_bones)	{
 		return;
 	}
 
-	verbose("found bones, trying to import them");
+	verbose("found bones, trying to import them as armature");
 
 	ArmatureImporter imp(*this,scene,out_scene);
 	imp.convert();
 
-	const Object* const arm = imp.get_armature();
+	armature = imp.get_armature();
 
 	// preserve the armature
 	imp.disown_armature();
+}
 
-	// now convert animation channels
-	if (!scene->mNumAnimations) {
-		return;
-	}
 
+void SceneImporter::convert_animations() 
+{
 	for (int i = 0; i < scene->mNumAnimations; ++i)
 	{
-		AnimationImporter animp(*this,*scene->mAnimations[i],*scene,*out_scene,i,*arm);
+		AnimationImporter animp(*this,*scene->mAnimations[i],*scene,*out_scene,i,armature);
 		animp.convert();
 	}
 }
@@ -235,6 +237,29 @@
 }
 
 
+void SceneImporter::populate_node_name_map(const aiNode* node)
+{
+	nodes_by_name[node->mName.C_Str()] = node;
+	for (unsigned int i = 0; i < node->mNumChildren; ++i) {
+		populate_node_name_map(node->mChildren[i]);
+	}
+}
+
+
+const aiNode* SceneImporter::get_node_by_name(const std::string& node) const
+{
+	const NodeNameMap::const_iterator it = nodes_by_name.find(node);
+	return it == nodes_by_name.end() ? NULL : (*it).second;
+}
+
+
+Object* SceneImporter::get_bobject_for_node(const aiNode& nd) const
+{
+	const NodeToObjectMap::const_iterator it = objects_by_node.find(&nd);
+	return it == objects_by_node.end() ? NULL : (*it).second;
+}
+
+
 bool SceneImporter::has_mesh_descendants(const aiNode& in_node) const
 {
 	return nodes_with_mesh_descendants.find(&in_node) != nodes_with_mesh_descendants.end();
@@ -274,13 +299,14 @@
 }
 
 
-void SceneImporter::convert_node(const aiNode& in_node, Object* out_parent) const
+void SceneImporter::convert_node(const aiNode& in_node, Object* out_parent) 
 {
-	std::vector<Object*> objects_done;
+	typedef std::vector<Object *> ObjectVector;
+	ObjectVector objects_done;
 
 	unsigned int meshes = 0, cameras = 0, lights = 0;
 	verbose(("convert node: " + std::string(in_node.mName.C_Str())).c_str());
-	
+
 	// attach meshes
 	if (in_node.mNumMeshes) {
 		// XXX join meshes on their name -- for each list of meshes we create a blender mesh
@@ -288,7 +314,7 @@
 		for (unsigned int i = 0, c = in_node.mNumMeshes; i < c; ++i) {
 			in_meshes.clear();
 			in_meshes.push_back(scene->mMeshes[in_node.mMeshes[i]]);
-			Object* const obj = convert_mesh(in_meshes,(in_node.mName.C_Str() + std::string("-mesh")).c_str());
+			Object* const obj = convert_mesh(in_meshes,in_node.mName.C_Str());
 
 			if(obj != NULL) {
 				objects_done.push_back(obj);
@@ -329,32 +355,82 @@
 		}
 	}
 
+	// note:
+	// empty nodes are usually bones and should thus not be represented by OB_EMPTY
+	// objects - these would just spoil Blender's scene outline :-) An exception
+	// are nodes that carry meshes in the subtree rooted at them. These must
+	// be preserved to avoid loosing the trafo info.
+
 	if (meshes + cameras + lights  == 0 &&  (!has_bones || has_mesh_descendants(in_node))) {
 		Object* const obj = util_add_object(out_scene, OB_EMPTY, NULL);
 		objects_done.push_back(obj);
 	}
 
-	for (std::vector<Object *>::iterator it = objects_done.begin(), end = objects_done.end(); it != end; ++it) {
-		Object* const obj = *it;
-		
-		convert_node_transform(in_node, *obj); 
+	// note:
+	// for animation purposes, we need a single anchor node to attach animation channels to.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list