• [原]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();
    }

  • 相关阅读:
    程序写法
    2011年C++再次给力
    WIN7+LINUX双系统
    随机洗牌算法
    Eclipse快捷键大全
    Android 编程规范
    android Context 上下文的几点解析
    消息模式Toast.makeText的几种常见用法
    Eclipse的优化
    用PULL解析器解析XML文件
  • 原文地址:https://www.cnblogs.com/lyggqm/p/10518112.html
Copyright © 2020-2023  润新知