路径的导出示例
路径的导出示例的代码如程序清单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路的导入示例截图