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