查看: 3206|回复: 8

如何取消透视

[复制链接]

该用户从未签到

发表于 2008-8-27 12:33:18 | 显示全部楼层 |阅读模式
载入地形后,用DriveManipulator漫游器进行浏览,从坡下往坡上走会发生透视的问题(即视角会“穿过”地面)。应如何解决?例如以下代码:
  1. int _tmain(int argc, _TCHAR* argv[])
  2. {
  3.         osg::ref_ptr<osg::Group> rootnode = new osg::Group;
  4.         osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("lz.osg");
  5.         rootnode->addChild( loadedModel.get() );
  6.         osgViewer::Viewer viewer;
  7.         viewer.setSceneData(rootnode.get());
  8.         const osg::BoundingSphere& boundingSphere=loadedModel->getBound();
  9.         osg ::ref_ptr<osgGA::DriveManipulator> trm= new osgGA::DriveManipulator;
  10.         trm->setHomePosition(boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius+2000.0f,0.0f),boundingSphere._center+osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,0.0f,1.0f));
  11.         viewer.setCameraManipulator(trm.get());
  12.         while (!viewer.done())
  13.         {
  14.                 viewer.frame();
  15.         }
  16.         return 0;
  17. }
复制代码
请各位帮帮忙啊~~先谢过了~

该用户从未签到

发表于 2008-8-27 13:45:44 | 显示全部楼层
可以自己继承DriveManipulator,重写一个漫游器,以实现诸如碰撞检测,以及上坡时抬升摄像机角度等工作,OSG自带的漫游器不会提供那么复杂的功能

该用户从未签到

发表于 2008-8-27 16:58:23 | 显示全部楼层

自己写一个操作器就可以了,, 关于碰撞检测的算法,可以参考小车爬坡,,最简单的就是线与模型相交检测~~~~~~~~

该用户从未签到

 楼主| 发表于 2008-8-27 17:49:26 | 显示全部楼层
原帖由 FlySky 于 2008-8-27 16:58 发表

自己写一个操作器就可以了,, 关于碰撞检测的算法,可以参考小车爬坡,,最简单的就是线与模型相交检测~~~~~~~~

小车爬坡的例子是哪个啊?在哪能找到啊?

该用户从未签到

发表于 2008-8-27 19:22:14 | 显示全部楼层
  1. 小车爬坡碰撞~~~~~

  2. void PopManipulator::computeHomePosition()
  3. {
  4. if(_node.get())
  5. {
  6. const osg::BoundingSphere& boundingSphere=_node->getBound();

  7. osg::Vec3d ep = boundingSphere._center;
  8. osg::Vec3d bp = ep;

  9. osg::CoordinateFrame cf=getCoordinateFrame(ep);

  10. ep -= getUpVector(cf)* _modelScale*0.0001;
  11. bp -= getUpVector(cf)* _modelScale;

  12. // check to see if any obstruction in front.
  13. osgUtil::IntersectVisitor iv;
  14. iv.setTraversalMask(_intersectTraversalMask);

  15. bool positionSet = false;

  16. osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
  17. segDown->set(ep,bp);
  18. iv.addLineSegment(segDown.get());

  19. _node->accept(iv);

  20. if (iv.hits())
  21. {
  22. osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
  23. if (!hitList.empty())
  24. {
  25. // notify(INFO) << "Hit terrain ok"<< std::endl;
  26. osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
  27. osg::Vec3d np = hitList.front().getWorldIntersectNormal();

  28. osg::Vec3d uv;
  29. if (np * getUpVector(cf)>0.0) uv = np;
  30. else uv = -np;

  31. ep = ip;
  32. ep += getUpVector(cf)*_height;
  33. osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0);

  34. setHomePosition(ep,ep+lv,uv);

  35. positionSet = true;

  36. }

  37. }

  38. if (!positionSet)
  39. {
  40. bp = ep;
  41. bp += getUpVector(cf)*_modelScale;

  42. osg::ref_ptr<osg::LineSegment> segUp = new osg::LineSegment;
  43. segUp->set(ep,bp);
  44. iv.addLineSegment(segUp.get());

  45. _node->accept(iv);

  46. if (iv.hits())
  47. {
  48. osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segUp.get());
  49. if (!hitList.empty())
  50. {
  51. // notify(INFO) << "Hit terrain ok"<< std::endl;
  52. osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
  53. osg::Vec3d np = hitList.front().getWorldIntersectNormal();

  54. osg::Vec3d uv;
  55. if (np*getUpVector(cf)>0.0) uv = np;
  56. else uv = -np;

  57. ep = ip;
  58. ep += getUpVector(cf)*_height;
  59. osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0);
  60. setHomePosition(ep,ep+lv,uv);

  61. positionSet = true;

  62. }

  63. }
  64. }

  65. if (!positionSet)
  66. {
  67. setHomePosition(
  68. boundingSphere._center+osg::Vec3d( 0.0,-2.0 * boundingSphere._radius,0.0),
  69. boundingSphere._center+osg::Vec3d( 0.0,-2.0 * boundingSphere._radius,0.0)+osg::Vec3d(0.0,1.0,0.0),
  70. osg::Vec3d(0.0,0.0,1.0));
  71. }

  72. }
  73. }
复制代码

该用户从未签到

 楼主| 发表于 2008-8-28 12:34:55 | 显示全部楼层
osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0);是什么意思啊?对象还能异或?

该用户从未签到

发表于 2008-8-28 13:57:21 | 显示全部楼层
原帖由 Sailent 于 2008-8-28 12:34 发表
osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0);是什么意思啊?对象还能异或?


^ 表示叉乘
* 表示点乘
请仔细阅读OSG的API文档

该用户从未签到

 楼主| 发表于 2008-8-28 15:31:35 | 显示全部楼层
原帖由 array 于 2008-8-28 13:57 发表


^ 表示叉乘
* 表示点乘
请仔细阅读OSG的API文档


谢谢啦~~~OSG的API文档哪有啊?

该用户从未签到

发表于 2008-8-28 15:52:26 | 显示全部楼层
原帖由 Sailent 于 2008-8-28 15:31 发表


谢谢啦~~~OSG的API文档哪有啊?


这一页就有……
http://bbs.osgchina.org/viewthread.php?tid=491

本站(包括文件中转站)其实是一个非常大的OSG资源集散地,教程、示例代码、安装包、文档……很多问题没必要挠头的,仔细找找就会有收获了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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