查看: 1640|回复: 6

关于相机跟踪节点的问题

[复制链接]

该用户从未签到

发表于 2011-7-27 00:23:46 | 显示全部楼层 |阅读模式
各位朋友大家好!
最近我通过学习OSG的视频教程和Array的书,做了一个简单的程序,主要功能是这样的:飞机沿着给定的路径飞行,然后摄像机跟踪飞机!
未标题-2A.JPG
现在出现了个问题!
相机与飞机是相对静止的,我在给飞机设置沿路经飞行时,设置了飞机的高度、朝向、以及飞机的横滚!当飞机沿路经飞行时,相机在跟踪飞机飞行的情况下,当飞机有沿着上图的方向转动时(即为飞机的横滚),由于飞机和相机是相对静止的,所以当转动时,从屏幕上看到的却是:地形在沿着反方向转动。

所以,我想做到的目标是;相机-飞机-地形,相机跟随飞机,飞机转动时,地形和相机是相对静止的,看到的结果是飞机在转动。

飞机沿路经飞机:
  我使用的是osg视频教程上的例子!我增加沿高度方向上的飞行!
相机跟随:
    我借用的是海军教程上的例子:这个例子使我可以动态调整观察飞机的位置!使用这几个参数来调整:UpDownMove、LeftRigtMove、movestep(相机与飞机之间的距离)。
  1. class orbit : public osg::NodeCallback
  2. {
  3. public:
  4. orbit(): heading(3.1415926/2.0) {}

  5. osg::Matrix getWCMatrix(){return worldCoordMatrix;}

  6. virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
  7. {
  8. osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
  9. if( tx != NULL )
  10. {
  11. osg::Matrixd orbitRotation;
  12. orbitRotation.makeRotate(
  13. osg::DegreesToRadians(0.0), osg::Vec3(0,1,0), // roll
  14. UpDownMove, osg::Vec3(1,0,0) , // pitch
  15. LeftRigtMove, osg::Vec3(0, 0, 1) ); // heading
  16. osg::Matrixd orbitTranslation;
  17. orbitTranslation.makeTranslate( 0,movestep, 0 );
  18. tx->setMatrix ( orbitTranslation * orbitRotation);
  19. worldCoordMatrix = osg::computeWorldToLocal( nv->getNodePath() );
  20. }

  21. traverse(node, nv);
  22. }
  23. private:
  24. osg::Matrix worldCoordMatrix;
  25. float heading;
  26. };
复制代码

等待大家的帮助!
谢谢!

该用户从未签到

发表于 2011-7-27 08:19:42 | 显示全部楼层
您完全没有给出,您是如何让相机跟随飞机运动的,因此我们也就无从判断您目前的方案应该如何改进

该用户从未签到

 楼主| 发表于 2011-7-27 08:49:28 | 显示全部楼层
回复 2# array
这是海军教程上的例子,我做了修改!新增加了3个参数,来动态控制相机的位置!我就是用这个类 class orbit : public osg::NodeCallback  来做的。

这个程序和我上贴图的程序,唯一区别就是给物体(tank或者plane)增加了个animationpathcallback,相机的控制都是一样的用这个方法的!


   
  1. #include <osg/NodeCallback>
  2. #include <osg/PositionAttitudeTransform>
  3. #include <osgViewer/Viewer>
  4. #include <osg/MatrixTransform>
  5. #include <osgDB/ReadFile>
  6. #include <osgGA/TrackballManipulator>
  7. #include "KeyboardHandler.h"

  8. float LeftRigtMove =3.1415926/1800.0;//新增参数
  9. float UpDownMove = -20.0;//新增参数
  10. float movestep = -40;//新增参数

  11. class PickHandle: public osgGA::GUIEventHandler
  12. {
  13. public:
  14. PickHandle(osgViewer::Viewer *vt)
  15. {
  16. viewer = vt;
  17. controls = new osg::Vec3dArray;
  18. }

  19. bool handle (const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
  20. {
  21. switch (ea.getEventType())
  22. {
  23. case osgGA::GUIEventAdapter::KEYDOWN:
  24. {
  25. if (ea.getKey() == 'm' || ea.getKey() == 'M')
  26. {
  27. std::cout<<"oasis"<<std::endl;
  28. }
  29. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)
  30. {
  31. LeftRigtMove += 3.1415926/180.0;
  32. std::cout<<"Press Key_Left!"<<std::endl;
  33. }
  34. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)
  35. {
  36. LeftRigtMove -= 3.1415926/180.0;
  37. std::cout<<"Press KEY_Right!"<<std::endl;
  38. }
  39. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)
  40. {
  41. UpDownMove -= 3.1415926/180.0;
  42. std::cout<<"Press KEY_Down!"<<std::endl;
  43. }
  44. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)
  45. {
  46. UpDownMove += 3.1415926/180.0;
  47. std::cout<<"Press KEY_Up!"<<std::endl;
  48. }
  49. if (ea.getKey() == '1')
  50. {
  51. movestep += 10;
  52. std::cout<<"Press 1 key!"<<std::endl;
  53. }
  54. if (ea.getKey() == '2')
  55. {
  56. movestep -= 10;
  57. std::cout<<"Press 2 key!"<<std::endl;
  58. }
  59. }
  60. break;
  61. default:
  62. break;
  63. }

  64. return false;
  65. }
  66. private:
  67. osgViewer::Viewer *viewer;
  68. osg::ref_ptr<osg::Vec3dArray> controls;
  69. };


  70. class orbit : public osg::NodeCallback
  71. {
  72. public:
  73. orbit(): heading(3.1415926/2.0) {}

  74. osg::Matrix getWCMatrix(){return worldCoordMatrix;}

  75. virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
  76. {
  77. osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
  78. if( tx != NULL )
  79. {
  80. heading += 3.1415926/1800.0;
  81. osg::Matrixd orbitRotation;
  82. orbitRotation.makeRotate(
  83. osg::DegreesToRadians(0.0), osg::Vec3(0,1,0), // roll
  84. UpDownMove, osg::Vec3(1,0,0) , // pitch
  85. LeftRigtMove, osg::Vec3(0, 0, 1) ); // heading
  86. osg::Matrixd orbitTranslation;
  87. orbitTranslation.makeTranslate( 0,movestep, 0 );
  88. tx->setMatrix ( orbitTranslation * orbitRotation);
  89. worldCoordMatrix = osg::computeWorldToLocal( nv->getNodePath() );
  90. }

  91. traverse(node, nv);
  92. }
  93. private:
  94. osg::Matrix worldCoordMatrix;
  95. float heading;
  96. };

  97. bool useTankOrbiterView = false;

  98. void toggleTankOrbiterView()
  99. {
  100. if (! useTankOrbiterView)
  101. useTankOrbiterView = true;
  102. else
  103. useTankOrbiterView = false;
  104. }

  105. int main()
  106. {
  107. osg::Node* groundNode = NULL;
  108. osg::Node* tankNode = NULL;
  109. osg::Group* root = NULL;
  110. osgViewer::Viewer viewer;
  111. osg::PositionAttitudeTransform* tankXform = NULL;

  112. groundNode = osgDB::readNodeFile("JoeDirt/JoeDirt/JoeDirt.flt");
  113. tankNode = osgDB::readNodeFile("t72-tank/T72-tank/t72-tank_des.flt");

  114. root = new osg::Group();

  115. // Create green Irish sky
  116. osg::ClearNode* backdrop = new osg::ClearNode;
  117. backdrop->setClearColor(osg::Vec4(0.1f,0.8f,0.0f,1.0f));
  118. root->addChild(backdrop);

  119. tankXform = new osg::PositionAttitudeTransform();

  120. root->addChild(groundNode);

  121. root->addChild(tankXform);
  122. tankXform->addChild(tankNode);

  123. tankXform->setPosition( osg::Vec3(10,10,8) );
  124. tankXform->setAttitude(
  125. osg::Quat(osg::DegreesToRadians(-45.0), osg::Vec3(0,0,1) ) );

  126. osgGA::TrackballManipulator *Tman = new osgGA::TrackballManipulator();
  127. viewer.setCameraManipulator(Tman);

  128. viewer.setSceneData( root );
  129. viewer.realize();

  130. osg::MatrixTransform* orbitTankXForm = new osg::MatrixTransform();
  131. orbit* tankOrbitCallback = new orbit();
  132. orbitTankXForm->setUpdateCallback( tankOrbitCallback );
  133. tankXform->addChild(orbitTankXForm);

  134. keyboardEventHandler* keh = new keyboardEventHandler();
  135. keh->addFunction('v',toggleTankOrbiterView);
  136. viewer.addEventHandler(keh);
  137. viewer.addEventHandler(new PickHandle(&viewer));

  138. while( !viewer.done() )
  139. {

  140. if (useTankOrbiterView)
  141. {
  142. Tman->setByInverseMatrix(tankOrbitCallback->getWCMatrix()
  143. *osg::Matrix::rotate( -3.1415926/2.0, 1, 0, 0 ));
  144. }

  145. viewer.frame();
  146. }
  147. }
复制代码

该用户从未签到

 楼主| 发表于 2011-7-27 12:04:14 | 显示全部楼层
补充下: 我给飞机设置的研三轴旋转,由于相机和飞机相对静止,所以从得到的结果(屏幕显示) 看起来都是地形在动;不仅仅是飞机在有横滚角时才有,只不过是在有横滚角度时候地形相对于飞机和相机转动比较大而已!

该用户从未签到

发表于 2011-7-27 19:33:22 | 显示全部楼层
你需求很纠结.你需要的是不是相机仅仅是位置跟随飞机,而旋转不跟随?

该用户从未签到

 楼主| 发表于 2011-7-28 08:25:07 | 显示全部楼层
本帖最后由 xairwolfcn 于 2011-7-28 08:27 编辑

回复 5# fenma3422
我表述有问题! 就是你说的!只是跟踪节点,沿三轴旋转不跟踪!同时还要能控制相机与节点之间的距离,方向等(在不同的角度观看飞机)!

该用户从未签到

发表于 2011-7-28 08:31:21 | 显示全部楼层
  1. if (useTankOrbiterView)
  2. {
  3. Tman->setByInverseMatrix(tankOrbitCallback->getWCMatrix()
  4. *osg::Matrix::rotate( -3.1415926/2.0, 1, 0, 0 ));
  5. }
复制代码
您所需的只是在这里调整Tman的观察矩阵即可,至于如何调整,我想这取决于您
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表