OSG动画与声音-路径动画之导出与导入(2)

路径的导出示例

        路径的导出示例的代码如程序清单10-2所示。

1.	// 创建路径  
2.	osg::ref_ptr<osg::AnimationPath> createAnimationPath(osg::Vec3 ¢er,  
3.	    float radius, float looptime)  
4.	{  
5.	    // 创建一个Path对象  
6.	    osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();  
7.	  
8.	    // 设置动画模式为循环(LOOP),LOOP,循环,SWING;单摆,NO_LOOPING,不循环  
9.	    animationPath->setLoopMode(osg::AnimationPath::LOOP);  
10.	      
11.	    // 关键点数  
12.	    int numPoint = 60;  
13.	  
14.	    // 每次偏移角度  
15.	    float yaw = 0.0;  
16.	    float yaw_delta = 2.0f * osg::PI / (numPoint - 1.0);  
17.	  
18.	    // 倾斜角度  
19.	    float roll = osg::inDegrees(45.0);  
20.	  
21.	    // 时间偏移  
22.	    float time = 0.0;  
23.	    float time_delta = looptime/(float(numPoint));  
24.	  
25.	    for (int i = 0; i < numPoint; ++i)  
26.	    {  
27.	        // 关键点位置  
28.	        osg::Vec3 position(center + osg::Vec3(sinf(yaw) * radius, cosf(yaw) * radius, 0.0f));  
29.	  
30.	        // 关键点角度  
31.	        osg::Quat rotation(osg::Quat(roll, osg::Vec3(0.0, 1.0, 0.0)) * osg::Quat(-(yaw + osg::inDegrees(90.0)),osg::Vec3(0.0,0.0,1.0)));  
32.	  
33.	        // 插入Path,把关键点与时间压入星辰Path  
34.	        animationPath->insert(time, osg::AnimationPath::ControlPoint(position, rotation));  
35.	  
36.	        yaw += yaw_delta;  
37.	        time += time_delta;  
38.	    }  
39.	  
40.	    // 返回Path  
41.	    return animationPath.get();  
42.	}  
43.	// 导出动画路径  
44.	void outAnimationPath_10_2(const string &strDataFolder)  
45.	{  
46.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
47.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
48.	    traits->x = 40;  
49.	    traits->y = 40;  
50.	    traits->width = 600;  
51.	    traits->height = 480;  
52.	    traits->windowDecoration = true;  
53.	    traits->doubleBuffer = true;  
54.	    traits->sharedContext = 0;  
55.	  
56.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
57.	  
58.	    osg::ref_ptr<osg::Camera> camera = viewer->getCamera();  
59.	    camera->setGraphicsContext(gc.get());  
60.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
61.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
62.	    camera->setDrawBuffer(buffer);  
63.	    camera->setReadBuffer(buffer);  
64.	  
65.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
66.	  
67.	    // 读取飞机模型  
68.	    string strDataPath = strDataFolder + "cessna.osg";  
69.	    osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile(strDataPath);  
70.	  
71.	    strDataPath = strDataFolder + "lz.osg";  
72.	    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);  
73.	  
74.	    // 得到包围盒,来确定动画旋转中心  
75.	    const osg::BoundingSphere &bs = cessna->getBound();  
76.	    osg::Vec3 position = bs.center() + osg::Vec3(0.0, 0.0, 200.0);  
77.	  
78.	    // 缩放比例,如果比例不当,模型会看不见  
79.	    float size = 100.0 / bs.radius() * 0.3;  
80.	  
81.	    // 创建路径  
82.	    osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();  
83.	    animationPath = createAnimationPath(position, 200.0, 10.0);  
84.	  
85.	    string fileName = strDataFolder + "animation_10_2.path";  
86.	    ofstream out(fileName.c_str());  
87.	    animationPath->write(out);  
88.	  
89.	    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();  
90.	  
91.	    // OSG确保只有STATIC数据可以进行图形渲染  
92.	    mt->setDataVariance(osg::Object::STATIC);  
93.	  
94.	    // 进行适当的变换(平移、缩放以及旋转)  
95.	    mt->setMatrix(osg::Matrix::translate(-bs.center()) * osg::Matrix::scale(size, size, size) *  
96.	        osg::Matrix::rotate(osg::inDegrees(-180.0), 0.0, 0.0, 1.0));  
97.	    mt->addChild(cessna.get());  
98.	  
99.	    osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();  
100.	  
101.	    // 设置更新回调  
102.	    pat->setUpdateCallback(new osg::AnimationPathCallback(animationPath.get(), 0.0, 1.0));  
103.	    pat->addChild(mt.get());  
104.	  
105.	    root->addChild(pat.get());  
106.	    root->addChild(node.get());  
107.	  
108.	    // 优化场景数据  
109.	    osgUtil::Optimizer optimizer;  
110.	    optimizer.optimize(root.get());  
111.	  
112.	    viewer->setSceneData(root.get());  
113.	    viewer->addEventHandler(new AnimationEventHander(*(viewer.get())));  
114.	    viewer->realize();  
115.	    viewer->run();  
116.	}  

        运行程序,截图如图10-4所示。

图10-4路径的导出示例截图

​​​​​​​路径的导入示例

        路径的导入示例的代码如程序清单10-3所示

 

1.	// 创建路径  
2.	osg::ref_ptr<osg::AnimationPath> createAnimationPath(osg::Vec3 ¢er,  
3.	    float radius, float looptime)  
4.	{  
5.	    // 创建一个Path对象  
6.	    osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();  
7.	  
8.	    // 设置动画模式为循环(LOOP),LOOP,循环,SWING;单摆,NO_LOOPING,不循环  
9.	    animationPath->setLoopMode(osg::AnimationPath::LOOP);  
10.	      
11.	    // 关键点数  
12.	    int numPoint = 60;  
13.	  
14.	    // 每次偏移角度  
15.	    float yaw = 0.0;  
16.	    float yaw_delta = 2.0f * osg::PI / (numPoint - 1.0);  
17.	  
18.	    // 倾斜角度  
19.	    float roll = osg::inDegrees(45.0);  
20.	  
21.	    // 时间偏移  
22.	    float time = 0.0;  
23.	    float time_delta = looptime/(float(numPoint));  
24.	  
25.	    for (int i = 0; i < numPoint; ++i)  
26.	    {  
27.	        // 关键点位置  
28.	        osg::Vec3 position(center + osg::Vec3(sinf(yaw) * radius, cosf(yaw) * radius, 0.0f));  
29.	  
30.	        // 关键点角度  
31.	        osg::Quat rotation(osg::Quat(roll, osg::Vec3(0.0, 1.0, 0.0)) * osg::Quat(-(yaw + osg::inDegrees(90.0)),osg::Vec3(0.0,0.0,1.0)));  
32.	  
33.	        // 插入Path,把关键点与时间压入星辰Path  
34.	        animationPath->insert(time, osg::AnimationPath::ControlPoint(position, rotation));  
35.	  
36.	        yaw += yaw_delta;  
37.	        time += time_delta;  
38.	    }  
39.	  
40.	    // 返回Path  
41.	    return animationPath.get();  
42.	}  
43.	// 导入动画路径  
44.	void inputAnimationPath_10_3(const string &strDataFolder)  
45.	{  
46.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
47.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
48.	    traits->x = 40;  
49.	    traits->y = 40;  
50.	    traits->width = 600;  
51.	    traits->height = 480;  
52.	    traits->windowDecoration = true;  
53.	    traits->doubleBuffer = true;  
54.	    traits->sharedContext = 0;  
55.	  
56.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
57.	  
58.	    osg::ref_ptr<osg::Camera> camera = viewer->getCamera();  
59.	    camera->setGraphicsContext(gc.get());  
60.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
61.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
62.	    camera->setDrawBuffer(buffer);  
63.	    camera->setReadBuffer(buffer);  
64.	  
65.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
66.	  
67.	    // 读取飞机模型  
68.	    string strDataPath = strDataFolder + "cessna.osg";  
69.	    osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile(strDataPath);  
70.	  
71.	    strDataPath = strDataFolder + "lz.osg";  
72.	    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);  
73.	  
74.	    // 得到包围盒,来确定动画旋转中心  
75.	    const osg::BoundingSphere &bs = cessna->getBound();  
76.	    osg::Vec3 position = bs.center() + osg::Vec3(0.0, 0.0, 200.0);  
77.	  
78.	    // 缩放比例,如果比例不当,模型会看不见  
79.	    float size = 100.0 / bs.radius() * 0.3;  
80.	  
81.	    // 创建路径  
82.	    string fileName = strDataFolder + "animation_10_2.path";  
83.	    ifstream fin(fileName.c_str());  
84.	  
85.	    osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();  
86.	    animationPath->read(fin);  
87.	    fin.close();  
88.	  
89.	    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();  
90.	  
91.	    // OSG确保只有STATIC数据可以进行图形渲染  
92.	    mt->setDataVariance(osg::Object::STATIC);  
93.	  
94.	    // 进行适当的变换(平移、缩放以及旋转)  
95.	    mt->setMatrix(osg::Matrix::translate(-bs.center()) * osg::Matrix::scale(size, size, size) *  
96.	        osg::Matrix::rotate(osg::inDegrees(-180.0), 0.0, 0.0, 1.0));  
97.	    mt->addChild(cessna.get());  
98.	  
99.	    osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();  
100.	  
101.	    // 设置更新回调  
102.	    pat->setUpdateCallback(new osg::AnimationPathCallback(animationPath.get(), 0.0, 1.0));  
103.	    pat->addChild(mt.get());  
104.	  
105.	    root->addChild(pat.get());  
106.	    root->addChild(node.get());  
107.	  
108.	    // 优化场景数据  
109.	    osgUtil::Optimizer optimizer;  
110.	    optimizer.optimize(root.get());  
111.	  
112.	    viewer->setSceneData(root.get());  
113.	    viewer->addEventHandler(new AnimationEventHander(*(viewer.get())));  
114.	    viewer->realize();  
115.	    viewer->run();  
116.	}  

        运行程序,截图如图10-5所示

图10-5路的导入示例截图

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风者868

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值