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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to