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路的导入示例截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/211328.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AndroidNDK开发之交叉编译

在Android studio2.2以及以上&#xff0c;构建原生库的默认工具是cmake。 CMake是一个跨平台的构建工具&#xff0c;可以使用简单的语句来描述所有平台的安装(编译过程)。 能够输出各种各样的makefile或者project文件。cmake并不直接构建出最终的软件&#xff0c;而是产生其他工…

《微信小程序开发从入门到实战》学习二十六

3.4 开发参与投票页面 参与投票页面同样需要收集用户提交的信息&#xff0c;哪个用户在哪个投票选择了什么选项&#xff0c;因此它也是一个表单页面 3.4.1 如何获取投票信息 假设用户A在投票创建页面后填了表单&#xff08;1.创建投票&#xff09;&#xff0c;用户A 点了提交…

合并两个有序链表,剑指offer,力扣

目录 力扣题目地址&#xff1a; 原题题目&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 审题目事例提示&#xff1a; 解题思路&#xff1a; 具体流程如下&#xff1a; 代码实现&#xff1a; 知识补充&#xff1a; 力扣题目地址&#xff1a; 21. 合并两个有序…

基于C#实现Prim算法

图论在数据结构中是非常有趣而复杂的&#xff0c;作为 Web 码农的我&#xff0c;在实际开发中一直没有找到它的使用场景&#xff0c;不像树那样的频繁使用&#xff0c;不过还是准备仔细的把图论全部过一遍。 一、最小生成树 图中有一个好玩的东西叫做生成树&#xff0c;就是用…

前缀和——724. 寻找数组的中心下标

文章目录 &#x1f353;1. 题目&#x1fad2;2. 算法原理&#x1f984;解法一&#xff1a;暴力枚举&#x1f984;解法二&#xff1a;前缀和 &#x1f954;3. 代码实现 &#x1f353;1. 题目 题目链接&#xff1a;724. 寻找数组的中心下标 - 力扣&#xff08;LeetCode&#xff0…

排查光模块故障原因,少不了这2条命令!

光模块故障定位常用命令 根据光模块的告警信息查找故障原因&#xff1a; display interface transceiver查看光模块光功率是否正常 display interface transceiver verbose根据光模块的告警信息查找故障原因 执行命令display interface transceiver查看“Alarm information”…

传统制造业如何有效实现数字化?企业数字化转型可以借助哪些工具?

2020年&#xff0c;制造业数字化转型行业的价值为2630亿美元。然而&#xff0c;到2026年&#xff0c;这一数字预计将达到惊人的7670亿美元。随着新技术的出现&#xff0c;工业4.0时代已经开始。这是由软件开发和自动化带来的对数字化的日益依赖所决定的&#xff0c;这使得制造过…

python获取json所有节点和子节点

使用python获取json的所有父结点和子节点 并使用父节点加下划线命名子节点 先展示一段json代码 {"level1": {"level2": {"level3": [{"level4": "4value"},{"level4_2": "4_2value"}]},"level2_…

深入剖析预约上门服务系统源码:构建高效服务的代码之旅

在本文中&#xff0c;我们将深入研究预约上门服务系统的源码&#xff0c;透过代码的层层剖析&#xff0c;揭示系统背后的技术奥秘。我们将关注系统的核心功能&#xff0c;并通过代码示例演示其实现过程&#xff0c;为读者提供一个深度技术解读的体验。 1. 技术栈选择&#xf…

plantUML学习与实战

背景 在日常工作或者生活中&#xff0c;使用交互图来描述想法&#xff0c;往往相对于文字来说&#xff0c;可读性更高&#xff0c;同时一定程度上可以提高沟通效率&#xff0c;但是苦于&#xff0c;不想对一堆控件拖拖拉拉&#xff0c;本人就是一个很讨厌画图&#xff0c;但是…

java学习part09类的构造器

1. 2.默认构造器 如果没有显式定义任何构造器&#xff0c;系统会默认加一个默认构造器。 如果定义了&#xff0c;则不会有默认构造器。 默认构造器的权限和类的权限一样&#xff0c;类是public构造器就是public&#xff0c;类是缺省默认构造器就是缺省 反编译之后添加的构造…

Astute Graphics 2023(ai创意插件合集)

Astute Graphics 2023是一家专注于图形编辑软件的公司&#xff0c;以制作高质量、功能强大的图像编辑工具而闻名。如Poser Pro、Poser 3D、Smart Shapes、Astute Sketch Pro等。 Astute Graphics的软件具有以下特点&#xff1a; 强大的图像编辑功能&#xff1a;Astute Graphi…