路径漫游
按照指定的路径进行漫游对一个演示是非常重要的。在osgViewer中,当第一次按下小写字母“z”时,开始记录动画路径;待动画录制完毕,按下大写字母“Z”,保存动画路径文件;使用osgViewer读取该动画路径文件时,会回放此动画路径的内容。按照指定的路径漫游称为路径漫游。同样,也可以指定物体按照指定的路径进行运动,此时就称为路径动画,其实它们本质是一样的,只是对路径的使用方法不同而已,但按照指定的路径比较简单。osgGA::MatrixManipulator有一个派生类一osgGA:AnimationPathManipulator 类,其继承关系图如图8-19所示。
图8-19 osgGA::AnimationPathManipulator 的继承关系图
osgGA:: AnimationPathManipulator 继承自osgGA::MatrixManipulator类在使用时没有必要考虑它内部是否实现矩阵变换,使用这个类的主要目的是但它在内部已经实现了矩阵变换等一系列的操作。实现路径漫游。
在osgGA::AnimationPathManipulator的类成员中已经包含了很多与路径关联的函数,此时读者的选择非常多,关联函数如下:
// 构造函数本身就关联
AnimationPathManipulator(osg::AnimationPath*animationPath = 0);
AnimationPathManipulator(const std::string &fileName);
// 得到或者设置路径
void setAnimationPath(osg::AnimationPath *animationPath);
const osg::AnimationPath *getAnimationPath()const;
了解了这些以后,路径漫游就变得非常简单了,其主要步骤如下:
<1> 创建一个osgGA::AnimationPathManipulator动画路径操作器实例
<2> 关联需要的路径。
<3> 设置当前视图场景操作器,关联该动画路径操作器。
viewer->setCameraMainpulator(camera);
对于如何创建路径,方法有很多,读者可以使用插值的方式来得到一些关键点插值,或者从3d max导出路径,这些方法都比较简单,具体因不同的项目需要,路径录制的方式也不一样。
路径漫游示例
路径漫游示例的代码如程序清单8-9所示
/* 路径漫游奇 */
void animationManipulator_8_9(const string &strDataFolder)
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 50;
traits->y = 50;
traits->width = 1000;
traits->height = 800;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setDrawBuffer(buffer);
camera->setReadBuffer(buffer);
viewer->addSlave(camera.get());
osg::ref_ptr<osg::Group> root = new osg::Group;
// 读取cow模型
string strDataPath = strDataFolder + "cow.osg";
osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile(strDataPath);
// 申请一个操作器
string strPath = strDataFolder + "animation.path";
osg::ref_ptr<osgGA::AnimationPathManipulator> apm = new osgGA::AnimationPathManipulator(strPath);
// 启用操作器
viewer->setCameraManipulator(apm.get());
root->addChild(cow.get());
// 优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
}
运行序,截图如图8-20所示
图8-20路径漫游示例截图