查看: 2410|回复: 10

切换漫游器时,碰撞检测出现错误

[复制链接]

该用户从未签到

发表于 2012-7-10 17:10:20 | 显示全部楼层 |阅读模式
view里面加了一个带碰撞检测的漫游器1,程序运行正常。检测的部分代码:

osg::Vec3 newPos = m_Position + delta;
osgUtil::IntersectVisitor ivr;
osg::ref_ptr<osg:ineSegment> line = new osg:ineSegment(newPos,m_Position);
iv.addLineSegment(lineZ.get());
m_node ->accept(iv);// m_node是场景根结点

后来又用KeySwitchMatrixManipulator的方式添加了一个路径漫游器2(osg::ref_ptr<osgGA::AnimationPathManipulator> apm = new osgGA::AnimationPathManipulator("../data/animation.path");keyswitchManipulator->addMatrixManipulator( '3', "path",apm );)。
由漫游器2切换到漫游器1的时候出现错误
m_node ->accept(iv);
访问了空指针,为什么m_node成了空指针?
是路径漫游器的关系吗?

该用户从未签到

 楼主| 发表于 2012-7-11 09:19:50 | 显示全部楼层
用了最差的解决方法,将m_node设置成了全局的变量

该用户从未签到

发表于 2012-7-13 09:37:30 | 显示全部楼层
这不是解决方案,而是您的问题所在。您显然没有正确地管理m_node以致它不知道什么时候被释放掉了

该用户从未签到

 楼主| 发表于 2012-7-16 17:01:50 | 显示全部楼层
  1. #include <Windows.h>

  2. #include <osg/Math>
  3. #include <osgDB/ReadFile>
  4. #include <osg/NodeCallback>
  5. #include <osg/MatrixTransform>
  6. #include <osg/PositionAttitudeTransform>
  7. #include <osg/DrawPixels>
  8. #include <osg/Texture2D>
  9. #include <osg/Array>
  10. #include <osg/Geometry>
  11. #include<osg/Node>
  12. #include<osg/Geode>
  13. #include<osg/Group>
  14. #include <osg/Point>

  15. #include<osgViewer/Viewer>
  16. #include<osgViewer/ViewerEventHandlers>

  17. #include<osg/MatrixTransform>
  18. #include<osgGA/CameraManipulator>
  19. #include<osgDB/ReadFile>
  20. #include<osgDB/WriteFile>

  21. #include<osgUtil/Optimizer>
  22. #include <osgUtil/IntersectVisitor>
  23. #include <vector>
  24. #include<iostream>
  25. #include <osgGA/KeySwitchMatrixManipulator>
  26. #include <osgGA/TerrainManipulator>
  27. #include <osgGA/TrackballManipulator>
  28. #include <osg/Matrixd>
  29. #include <osg/Quat>
  30. //osg::ref_ptr<osg::Node>m_node=NULL;

  31. class TravelManipulator:public osgGA::CameraManipulator
  32. {
  33. public:
  34.         TravelManipulator():m_fMoveSpeed(1.5f),
  35.                 m_bLeftButtonDown(false),
  36.                 m_fpushX(0),
  37.                 m_fpushY(0),
  38.                 m_fAngle(2.5),
  39.                 m_bPeng(true)
  40.         {
  41.                 //m_vPosition=osg::Vec3(0.0f,0.0f,100.0f);
  42.                 //m_vRotation=osg::Vec3(osg::PI_2,0.0f,0.0f);
  43.                

  44.         }
  45.         ~TravelManipulator()
  46.         {

  47.         }

  48.         /*static TravelManipulator*travelToScence(osg::ref_ptr<osgViewer::Viewer>viewer)
  49.         {
  50.                 TravelManipulator*camera=new TravelManipulator;
  51.                 viewer->setCameraManipulator(camera);
  52.                 camera->m_pHostViewer=viewer;
  53.                 return camera;

  54.         }*/
  55. private:
  56.         //osg::ref_ptr<osgViewer::Viewer>m_pHostViewer;
  57.         osg::ref_ptr<osg::Node>m_node;
  58.         float m_fMoveSpeed;
  59.         osg::Vec3 m_vPosition;
  60.         osg::Vec3 m_vRotation;
  61.         osg::Vec3 m_vScale;
  62.         //float m_vdistance;
  63.         //osg::Matrixd m_Matrix;

  64. public:
  65.         bool m_bLeftButtonDown;
  66.         float m_fpushX;
  67.         float m_fpushY;
  68.        
  69.         virtual void setByMatrix(const osg::Matrixd& matrix)
  70.         {
  71.                 //osg::Quat quat(osg::inDegrees(90.0f),osg::Vec3f(1.0,0.0,0.0));

  72.        
  73.                 //m_vRotation=(matrix.getRotate()/**quat*/).asVec3();
  74.                 //m_Matrix=matrix;
  75.                 double angle0,angle1,angle2;
  76.                 osg::Quat quat=matrix.getRotate();
  77.                 quat.getRotate(angle0,osg::Vec3f(1.0,0.0,0.0));
  78.                 quat.getRotate(angle1,osg::Vec3f(0.0,1.0,0.0));
  79.                 quat.getRotate(angle2,osg::Vec3f(0.0,0.0,1.0));
  80.                 m_vRotation[0]=osg::inRadians(angle0);
  81.                 m_vRotation[1]=osg::DegreesToRadians(angle1)/*-osg::PI_2*/;
  82.                 m_vRotation[2]=osg::DegreesToRadians(angle2);
  83.                 //m_vRotation=matrix.getRotate().asVec3();
  84.                 m_vPosition=matrix.getTrans();
  85.        
  86.         }
  87.         virtual void setByInverseMatrix(const osg::Matrixd& matrix)
  88.         {
  89.                
  90.                 osg::Matrixd matrix1= osg::Matrixd::inverse(matrix);
  91.                 osg::Quat quat=matrix1.getRotate();
  92.                 m_vPosition=matrix1.getTrans();
  93.                 double angle0,angle1,angle2;
  94.                 quat.getRotate(angle0,osg::Vec3f(1.0,0.0,0.0));
  95.                 quat.getRotate(angle1,osg::Vec3f(0.0,1.0,0.0));
  96.                 quat.getRotate(angle2,osg::Vec3f(0.0,0.0,1.0));
  97.                 m_vRotation[0]=osg::DegreesToRadians(angle0);
  98.                 m_vRotation[1]=osg::DegreesToRadians(angle1)/*-osg::PI_2*/;
  99.                 m_vRotation[2]=osg::DegreesToRadians(angle2);
  100.                 //m_vRotation=matrix1.getRotate().asVec3();
  101.                 //m_Matrix=matrix1;

  102.         }
  103.         virtual osg::Matrixd getMatrix(void)const
  104.         {
  105.                 //return m_Matrix;
  106.                 osg::Matrixd mat;
  107.                 mat.makeRotate(m_vRotation._v[0],osg::Vec3f(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3f(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3f(0.0,0.0,1.0));
  108.                 return mat*osg::Matrixd::translate(m_vPosition);
  109.         }
  110.         virtual osg::Matrixd getInverseMatrix()const
  111.         {
  112.                 /*return osg::Matrixd::inverse(m_Matrix);*/

  113.                 osg::Matrixd mat;
  114.                 mat.makeRotate(m_vRotation._v[0],osg::Vec3f(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3f(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3f(0.0,0.0,1.0));
  115.                 return osg::Matrixd::inverse(mat*osg::Matrixd::translate(m_vPosition));
  116.         }

  117.         virtual bool handle(const osgGA::GUIEventAdapter&ea,osgGA::GUIActionAdapter&us)
  118.         {
  119.                
  120.                 float mouseX=ea.getX();
  121.                 float mouseY=ea.getY();
  122.        
  123.                 switch(ea.getEventType())
  124.                 {
  125.                 case(osgGA::GUIEventAdapter::KEYDOWN):
  126.                         {
  127.                                 if (ea.getKey()==0x20)//空格键
  128.                                 {
  129.                                         us.requestRedraw();
  130.                                         us.requestContinuousUpdate(false);
  131.                                         //m_pHostViewer->getCameraManipulator()->setHomePosition(osg::Vec3d(0.0,-5.0,0.0),osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,0.0,1.0));
  132.                                         return true;
  133.                                 }
  134.                                 if (ea.getKey()==0xFF50)// KEY_Home = 0xFF50,KEY_Left = 0xFF51,KEY_Up = 0xFF52, KEY_Right = 0xFF53, KEY_Down = 0xFF54,
  135.                                 {
  136.                                         ChangePosition(osg::Vec3(0,0,m_fMoveSpeed));//抬高视点
  137.                                         return true;
  138.                                 }
  139.                                 if (ea.getKey()==0xFF57)//KEY_End = 0xFF57
  140.                                 {
  141.                                         ChangePosition(osg::Vec3(0,0,-m_fMoveSpeed));//降低视点
  142.                                         return true;
  143.                                 }
  144.                                 if (ea.getKey()==0x2B)//KEY_Plus = 0x2B  “+”号键
  145.                                 {
  146.                                         m_fMoveSpeed+=1.0f;
  147.                                         return true;
  148.                                 }
  149.                                 if (ea.getKey()==0x2D)//KEY_Minus = 0x2D   “-”号键
  150.                                 {
  151.                                         m_fMoveSpeed-=1.0f;
  152.                                         if (m_fMoveSpeed<1.0f)
  153.                                         {
  154.                                                 m_fMoveSpeed=1.0f;
  155.                                         }
  156.                                         return true;
  157.                                 }
  158.                                 if (ea.getKey()== 0xFF52||ea.getKey()== 0x57||ea.getKey()== 0x77)//,KEY_Up = 0xFF52
  159.                                 {
  160.                                         ChangePosition(osg::Vec3(0,m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0));
  161.                                         ChangePosition(osg::Vec3(m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0,0));
  162.                                         return true;
  163.                                 }
  164.                                 if (ea.getKey()== 0xFF54||ea.getKey()== 0x53||ea.getKey()== 0x73)// KEY_Down = 0xFF54
  165.                                 {
  166.                                         ChangePosition(osg::Vec3(0,-m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0));
  167.                                         ChangePosition(osg::Vec3(-m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0,0));
  168.                                         return true;
  169.                                 }
  170.                                 if (ea.getKey()== 0x41||ea.getKey()== 0x61)//A 向左
  171.                                 {
  172.                                         ChangePosition(osg::Vec3(-m_fMoveSpeed*sinf((osg::PI)/2+m_vRotation._v[2]),0,0));
  173.                                         ChangePosition(osg::Vec3(-m_fMoveSpeed*cosf((osg::PI)/2+m_vRotation._v[2]),0,0));
  174.                                         return true;
  175.                                 }
  176.                                 if (ea.getKey()== 0x44||ea.getKey()== 0x64)//D 向右
  177.                                 {
  178.                                         ChangePosition(osg::Vec3(m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0,0));
  179.                                         ChangePosition(osg::Vec3(m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0,0));
  180.                                         return true;
  181.                                 }
  182.                                 if (ea.getKey()== 0xFF53)//KEY_Right转弯向右
  183.                                 {
  184.                                         m_vRotation._v[2]-=osg::DegreesToRadians(m_fAngle);
  185.                                         return true;
  186.                                 }
  187.                                 if (ea.getKey()== 0xFF51)//KEY_Left转弯向左
  188.                                 {
  189.                                         m_vRotation._v[2]+=osg::DegreesToRadians(m_fAngle);
  190.                                         return true;
  191.                                 }
  192.                                 if (ea.getKey()== 0x46||ea.getKey()== 0x66)//F 改变屏角
  193.                                 {
  194.                                         computeHomePosition();
  195.                                         m_fAngle-=0.2;
  196.                                         return true;
  197.                                 }
  198.                                 if (ea.getKey()== 0x47||ea.getKey()== 0x67)//G
  199.                                 {
  200.                                         m_fAngle+=0.2;
  201.                                         return true;
  202.                                 }
  203.                                 return false;
  204.                         }
  205.                 case(osgGA::GUIEventAdapter::PUSH)://鼠标按下
  206.                         {
  207.                                 if (ea.getButton()==1)
  208.                                 {
  209.                                         m_fpushX=mouseX;
  210.                                         m_fpushY=mouseY;
  211.                                         m_bLeftButtonDown=true;
  212.                                 }
  213.                                 return false;
  214.                         }
  215.                 case(osgGA::GUIEventAdapter::DRAG)://拖动
  216.                         if (m_bLeftButtonDown)
  217.                         {
  218.                                 m_vRotation._v[2]-=osg::DegreesToRadians((m_fAngle/1000)*(mouseX-m_fpushX));
  219.                                 //m_vRotation._v[0]+=osg::DegreesToRadians(1.1*(mouseY-mouseX));
  220.                                 /*if (m_vRotation._v[0]>=3.14)
  221.                                 {
  222.                                 m_vRotation._v[0]=3.14;
  223.                                 }
  224.                                 if (m_vRotation._v[0]<=0)
  225.                                 {
  226.                                 m_vRotation._v[0]=0;
  227.                                 }*/
  228.                                 if (mouseY-m_fpushY<0)
  229.                                 {

  230.                                         ChangePosition(osg::Vec3f (0.0,10.0,0.0));
  231.                                 }
  232.                                 if (mouseY-m_fpushY>0)
  233.                                 {

  234.                                         ChangePosition(osg::Vec3f (0.0,-10.0,0.0));
  235.                                 }

  236.                         }
  237.                         return false;
  238.                 case(osgGA::GUIEventAdapter::RELEASE)://鼠标释放

  239.                         {
  240.                                 if (ea.getButton()==1)
  241.                                 {
  242.                                         m_bLeftButtonDown=false;
  243.                                 }
  244.                                 return false;
  245.                         }
  246.                 default:
  247.                         return false;
  248.                 }
  249.         }
  250.         float m_fAngle;
  251.         void ChangePosition(osg::Vec3&delta)
  252.         {
  253.                 if (m_bPeng)
  254.                 {
  255.                         osg::Vec3 newPos1=m_vPosition+delta;
  256.                         osgUtil::IntersectVisitor ivXY;
  257.                         osg::ref_ptr<osg::LineSegment>lineXY=new osg::LineSegment(newPos1,m_vPosition);
  258.                         osg::ref_ptr<osg::LineSegment>lineZ=new osg::LineSegment(newPos1+osg::Vec3(0.0f,0.0f,m_fMoveSpeed),newPos1-osg::Vec3f(0.0,0.0,m_fMoveSpeed));
  259.                         ivXY.addLineSegment(lineZ.get());
  260.                         ivXY.addLineSegment(lineXY.get());
  261.                         //m_pHostViewer->getSceneData()->accept(ivXY);
  262.                         m_node->accept(ivXY);
  263.                         if (!ivXY.hits())
  264.                         {
  265.                                 m_vPosition+=delta;
  266.                         }
  267.                 }
  268.                 else
  269.                 {
  270.                         m_vPosition+=delta;
  271.                 }
  272.                 //m_vPosition+=delta;
  273.         }
  274.         bool m_bPeng;
  275.         float getSpeed()
  276.         {
  277.                 return m_fMoveSpeed;
  278.         }
  279.         void setSpeed(float&sp)
  280.         {
  281.                 m_fMoveSpeed=sp;
  282.         }
  283.         //void setDistance( double distance )
  284.         //{
  285.         //        m_vdistance = distance;
  286.         //}


  287.         ///** Get the distance of the camera to the center. */
  288.         //double getDistance() const
  289.         //{
  290.         //        return m_vdistance;
  291.         //}
  292.         void SetPosition(osg::Vec3&position)
  293.         {
  294.                 m_vPosition=position;
  295.         }
  296.         osg::Vec3 GetPosition()
  297.         {
  298.                 return m_vPosition;
  299.         }
  300.         void setNode(osg::Node* node)
  301.         {
  302.                 m_node=node;
  303.         }
  304.         void computeHomePosition()
  305.         {
  306.                 if (m_node.get())
  307.                 {
  308.                         const osg::BoundingSphere&boundingSpere=m_node->getBound();
  309.                         osg::Vec3 bp=boundingSpere._center;
  310.                         m_vRotation=osg::Vec3(osg::PI_2,0.0f,0.0f);
  311.                         SetPosition(bp);
  312.                 }
  313.         }
  314. };

  315. int main()
  316. {
  317.         osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer();
  318.         //TravelManipulator::travelToScence(viewer.get());
  319.         osg::ref_ptr<osg::Group>root=new osg::Group();
  320.         osg::ref_ptr<osg::Node>node=osgDB::readNodeFile("lz.osg");
  321.         osg::ref_ptr<osgGA::AnimationPathManipulator> apm = new osgGA::AnimationPathManipulator("../data/animation.path");
  322.         //viewer->setCameraManipulator(apm.get());
  323.         osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
  324.    // keyswitchManipulator->setNode(node.get());
  325.         //keyswitchManipulator->addMatrixManipulator( '4', "TrackballTravel", new osgGA::TrackballManipulator());
  326.         keyswitchManipulator->addMatrixManipulator( '1', "TerrianTravelTravel", new osgGA::TerrainManipulator());
  327.         keyswitchManipulator->addMatrixManipulator( '2', "ControlTravel", new TravelManipulator());
  328.         keyswitchManipulator->addMatrixManipulator( '3', "path",apm );
  329.        

  330.         //m_node=node.get();
  331.         root->addChild(node.get());
  332.         /*osgUtil::Optimizer optimizer;
  333.         optimizer.optimize(root.get());*/
  334.         viewer->setSceneData(root.get());
  335.         viewer->setCameraManipulator( keyswitchManipulator.get() );
  336.         //viewer->setCameraManipulator(new TravelManipulator() );
  337.         viewer->realize();
  338.         viewer->run();
  339.         //while(!viewer->done())
  340.         //{
  341.         //         
  342.         //    viewer->frame();
  343.         //     // 让其它程也占用CPU,放出MS
  344.         //}
  345.        
  346.         return 0;
  347. }
复制代码
可是osgGA::TerrainManipulator()或是自定义的漫游器,他们之间切换是可以的,贴上代码,望指点~~~

该用户从未签到

发表于 2012-7-18 09:20:27 | 显示全部楼层
您粘贴了这么大的代码段又不存在任何可以理解的信息。。。我如何去阅读?

该用户从未签到

发表于 2012-7-19 07:59:18 | 显示全部楼层

该用户从未签到

发表于 2012-7-19 10:05:02 | 显示全部楼层
我看了LZ的代码,问题出在AnimationPathManipulator这个漫游器上,因为AnimationPathManipulator漫游器不需要SetNode()函数,即它的这个函数仍然是基类的函数,即为NULL。

   所以在KeySwitchMatrixManipulator的Handle里切换漫游器时,
调用这句话:
   if(it->second.second->getNode()) (此时的节点为NULL)
  {  
     TrackballTravel->setNode()就不会被调用
  };

这个情况,你要调试下源代码才可以。

   

该用户从未签到

 楼主| 发表于 2012-7-19 13:53:43 | 显示全部楼层
CWorld 发表于 2012-7-19 10:05
我看了LZ的代码,问题出在AnimationPathManipulator这个漫游器上,因为AnimationPathManipulator漫游器不需 ...

多谢~~

该用户从未签到

发表于 2012-9-25 21:30:47 | 显示全部楼层
请问以上自己定义的 TravelManipulator,对相机先旋转了再沿x轴平移,实际的效果是沿看到的物体的x轴移动了,要想效果沿屏幕的x轴方向移动该怎样实现?谢谢

该用户从未签到

发表于 2012-9-26 07:59:43 | 显示全部楼层
smengq 发表于 2012-9-25 21:30
请问以上自己定义的 TravelManipulator,对相机先旋转了再沿x轴平移,实际的效果是沿看到的物体的x轴移动了 ...

相机的移动总是相对于场景,场景的移动跟相机是相反的

该用户从未签到

发表于 2012-9-26 08:28:41 | 显示全部楼层
liuzhiyu123 发表于 2012-9-26 07:59
相机的移动总是相对于场景,场景的移动跟相机是相反的

你好,这个我明白,我就是想实现相机旋转了一个角度后再平移,使图形能够沿看到的屏幕上的x轴平移,比如一个牛模型,头偏向右下方,也就是相机朝向左上方,怎样设置相机移动使模型沿屏幕x轴移动?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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