[原]osg模型动画|骨骼动画

参考源码:osg的官方例子:osganimationviewer

首先制作一个带骨骼动画的模型  demo.FBX

这里面我们做了两个骨骼动画:1.open   2.close  

下面开始在osg中使用这个动画。

我们用几种代码从简到繁来演示加载播放等过程:

1.最简单的示例代码

 1 #include <osgViewer/Viewer>
 2 #include <osgDB/ReadFile>
 3 #include <osgAnimation/BasicAnimationManager>
 4 
 5 int main(int argc, char* argv[])
 6 {
 7     osgViewer::Viewer viewer;
 8 
 9     //读取带动画的节点
10     osg::Node *animationNode = osgDB::readNodeFile("demo.FBX");
11     //获得节点的动画列表
12     osgAnimation::BasicAnimationManager* anim =
13         dynamic_cast<osgAnimation::BasicAnimationManager*>(animationNode->getUpdateCallback());
14     const osgAnimation::AnimationList& list = anim->getAnimationList();
15     //从动画列表中选择一个动画,播放
16     anim->playAnimation(list[0].get());
17 
18     viewer.setSceneData(animationNode);
19     return viewer.run();
20 }

2.通过自定义AnimationManagerFinder加载

 本段代码,我没有测试,但是大体是这样。

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgAnimation/BasicAnimationManager>

struct AnimationManagerFinder : public osg::NodeVisitor
{
    osg::ref_ptr<osgAnimation::BasicAnimationManager> _am;
    AnimationManagerFinder() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
    void apply(osg::Node& node) {
        if (_am.valid())
            return;
        if (node.getUpdateCallback()) {
            osgAnimation::AnimationManagerBase* b = dynamic_cast<osgAnimation::AnimationManagerBase*>(node.getUpdateCallback());
            if (b) {
                _am = new osgAnimation::BasicAnimationManager(*b);
                return;
            }
        }
        traverse(node);
    }
};


int main(int argc, char* argv[])
{
    osgViewer::Viewer viewer;

    //读取带动画的节点
    osg::Node *animationNode = osgDB::readNodeFile("demo.FBX");

    AnimationManagerFinder  m_cFinder;
    //获得节点的动画列表
    animationNode ->accept(*m_cFinder);
    if (m_cFinder->_am.valid())
    {
        animationNode ->setUpdateCallback(m_cFinder->_am.get());
    }

    for (osgAnimation::AnimationList::const_iterator it = m_cFinder->_am->getAnimationList().begin(); it != m_cFinder->_am->getAnimationList().end(); it++)
    {
        std::string animationName = (*it)->getName();
        osgAnimation::Animation::PlayMode playMode = osgAnimation::Animation::ONCE;
        (*it)->setPlayMode(playMode);//设置播放模式
        (*it)->setDuration(5.0);//设置播放时间
    }

    //从动画列表中选择一个动画,播放
    m_cFinder->_am->->playAnimation(*m_cFinder->_am->getAnimationList().begin());

    viewer.setSceneData(animationNode);
    return viewer.run();
}

原文地址:https://www.cnblogs.com/lyggqm/p/10518112.html