[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