如何在openscenegraph中旋转相机(模型中的Walk Through)?

时间:2015-01-23 06:41:09

标签: c++ openscenegraph

我已经在我的场景中加载了3D模型,我想在世界中走过。 我实现了向前,向后,向左,向右,向上和向下但我需要在相机位置旋转我的相机x,y,z,但我不能得到请帮帮我吗?

#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

#include <osg/Camera>



#include <math.h>



osg::Matrixd md ;
osg::Matrixd originalmd ;
osg::Quat qua;
float angle=0;

   osgViewer::Viewer viewer;
   osg::Vec3f eye=osg::Vec3f(1.0,-200.0,2.0);
   osg::Vec3f centre=osg::Vec3f(0.0,0.0,0.0);
   osg::Vec3f up=osg::Vec3f(0.0,0.0,1.0);

   osg::Vec3f originaleye=osg::Vec3f(0.0,-200.0,0.0);
   osg::Vec3f originalcentre=osg::Vec3f(0.0,0.0,0.0);
   osg::Vec3f originalup=osg::Vec3f(0.0,0.0,1.0);

   int ConstantVariation=5;


class PickHandler : public osgGA::GUIEventHandler 
{
public: 

PickHandler() {}

~PickHandler() {}

bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);


protected:

};

bool PickHandler::handle(const osgGA::GUIEventAdapter&          ea,osgGA::GUIActionAdapter& aa)
{
switch(ea.getEventType())
{
    case(osgGA::GUIEventAdapter::PUSH):
    {
        osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
        //if (view) pick(view,ea);
        return false;
    }    
    case(osgGA::GUIEventAdapter::KEYDOWN):
    {
        if (ea.getKey()=='c')
        {    
            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
            osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter(ea);
            event->setX((ea.getXmin()+ea.getXmax())*0.5);
            event->setY((ea.getYmin()+ea.getYmax())*0.5);
           // if (view) pick(view,*event);
        }
        if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Up)
        {   
            std::cout<<"Forward"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans=md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            md.getLookAt(eye,centre,up);

            trans.z()=trans.z()+5;

            md.setTrans(trans);
        }
    if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down)
        { 
            std::cout<<"BackWard"<<std::endl;  


            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans=md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            md.getLookAt(eye,centre,up);
            trans.z()=trans.z()-5;

            md.setTrans(trans);

        }
        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left)
        {        

            std::cout<<"LEFT Side"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans=md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            md.getLookAt(eye,centre,up);

            trans.x()=trans.x()+5;

            md.setTrans(trans);
        }

        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right)
        {        

            std::cout<<"Right Side"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.x()=trans.x()-5;
            md.setTrans(trans);


        }
        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up)
        {
            std::cout<<"UP"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.y()=trans.y()-5;
            md.setTrans(trans);


        }

        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down)
        {
            std::cout<<"Down"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.y()=trans.y()+5;
            md.setTrans(trans);


        }

        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_8)
        {
            std::cout<<"Rotation"<<std::endl;
            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans=md.getTrans();
            double a=trans.x();
            double b=trans.y();
            double c=trans.z();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;
            md.setTrans(osg::Vec3d(0,0,0));
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            angle=0.077;
            //osg::Quat qa(angle,osg::Vec3d(0.0,0.0,1.0));

            md.getLookAt(eye,centre,up);
            osg::Quat qa(angle,up);
            md.setRotate(qa);
            up=md.getRotate()*trans;

            md.setRotate(qa);
            trans.x()=a;
            trans.y()=b;
            trans.z()=c;
            md.setTrans(trans);

            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;
            std::cout<<" End Rotation"<<std::endl;
        }           


        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Space)
        {
            md=originalmd;

        }
        return false;
    }    
    default:
        return false;
 }
}



int main( int argc, char **argv )
{



osg::ref_ptr<osg::Group> scene = new  osg::Group;

scene->addChild(osgDB::readNodeFile("cessna.osg"));

viewer.addEventHandler(new osgViewer::WindowSizeHandler);
viewer.addEventHandler(new PickHandler());

viewer.setSceneData(scene.get());

const osg::BoundingSphere& bs = scene->getBound();


viewer.getCamera()->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f, -(3*bs.radius()),0.0f), bs.center(), osg::Z_AXIS) ;

md=viewer.getCamera()->getViewMatrix();
originalmd=md;



viewer.realize();

while(!viewer.done())
{
    viewer.getCamera()->setViewMatrix(md);
    viewer.frame();
 }


}

编辑: - 我怀疑是否正在以适当的方式执行任务,即我需要移动相机但是上面的代码翻译并旋转对象以感觉相机被旋转......很多网站都说在opengl中没有相机链接({{3} })。

2 个答案:

答案 0 :(得分:0)

就像翻译一样,您使用getTrans()获取现有翻译并向其添加增量或减量,类似于旋转也使用getRotate()获取现有旋转,然后添加一个小的增量或减量对它来说,不要每次都直接将它设置为相同的值。

答案 1 :(得分:0)

按照我的需要表演,但我能做得比这更好......

#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

#include <osg/Camera>



 #include <math.h>




// class to handle events with a pick


osg::Matrixd md ;
osg::Matrixd originalmd ;
osg::Quat qua;
float angle=0;

   osgViewer::Viewer viewer;
   osg::Vec3f eye=osg::Vec3f(0.0,-200.0,0.0);
   osg::Vec3f centre=osg::Vec3f(0.0,0.0,0.0);
   osg::Vec3f up=osg::Vec3f(0.0,0.0,1.0);

   osg::Vec3f originaleye=osg::Vec3f(0.0,-200.0,0.0);
   osg::Vec3f originalcentre=osg::Vec3f(0.0,0.0,0.0);
   osg::Vec3f originalup=osg::Vec3f(0.0,0.0,1.0);

   int ConstantVariation=5;


  class PickHandler : public osgGA::GUIEventHandler {
  public: 

  PickHandler() {}

  ~PickHandler() {}

  bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);


protected:

 };

bool PickHandler::handle(const osgGA::GUIEventAdapter&   ea,osgGA::GUIActionAdapter& aa)
{
   switch(ea.getEventType())
   {
       case(osgGA::GUIEventAdapter::PUSH):
      {
         osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
         //if (view) pick(view,ea);
         return false;
     }    
    case(osgGA::GUIEventAdapter::KEYDOWN):
    {
        if (ea.getKey()=='c')
        {    
            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
            osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter(ea);
            event->setX((ea.getXmin()+ea.getXmax())*0.5);
            event->setY((ea.getYmin()+ea.getYmax())*0.5);
           // if (view) pick(view,*event);
        }
        if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Up)
        {   
            std::cout<<"Forward"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            md.getLookAt(eye,centre,up);

            osg::Vec3f actuallook=centre-eye;

            actuallook=actuallook/(actuallook.length());


            eye=eye+((actuallook)*10);
            centre=centre+((actuallook)*10);

            viewer.getCamera()->setViewMatrixAsLookAt(eye, centre, osg::Z_AXIS) ;
        }
    if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down)
        { 
            std::cout<<"BackWard"<<std::endl;  


            md=viewer.getCamera()->getViewMatrix();
            md.getLookAt(eye,centre,up);

            osg::Vec3f actuallook=centre-eye;

            actuallook=actuallook/(actuallook.length());


            eye=eye-((actuallook)*10);

            viewer.getCamera()->setViewMatrixAsLookAt(eye, centre, osg::Vec3d(up.x(),up.y(),up.z())) ;

        }
        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left)
        {        

            std::cout<<"LEFT Side"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans=md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            md.getLookAt(eye,centre,up);

            trans.x()=trans.x()+10;

            md.setTrans(trans);

            viewer.getCamera()->setViewMatrix(md);
        }

        if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right)
        {        

            std::cout<<"Right Side"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.x()=trans.x()-10;
            md.setTrans(trans);

            viewer.getCamera()->setViewMatrix(md);


        }
        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up)
        {
            std::cout<<"UP"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.y()=trans.y()-10;
            md.setTrans(trans);

            viewer.getCamera()->setViewMatrix(md);


        }

        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down)
        {
            std::cout<<"Down"<<std::endl;

            md=viewer.getCamera()->getViewMatrix();
            osg::Vec3d trans = md.getTrans();
            std::cout<<"translation="<<trans.x()<<","<<trans.y()<<","<<trans.z()<<std::endl;

            trans.y()=trans.y()+10;
            md.setTrans(trans);

            viewer.getCamera()->setViewMatrix(md);


        }
        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_7)
        {
            std::cout<<"Rotation"<<std::endl;
            md=viewer.getCamera()->getViewMatrix();


            angle=(3.142/180)*2;

            md.getLookAt(eye,centre,up);
            std::cout<<"up="<<up.x()<<up.y()<<up.z()<<std::endl;

            osg::Vec3f actuallook=centre-eye;
            actuallook=actuallook/(actuallook.length());

            osg::Quat qa(-angle,osg::Vec3f(up.x(),up.y(),up.z()));

            osg::Vec3f look= (qa * actuallook);
            look=look/(look.length());
            centre = eye+(look*actuallook.length());

            viewer.getCamera()->setViewMatrixAsLookAt(eye, centre, osg::Vec3d(up.x(),up.y(),up.z())) ;
            std::cout<<"up="<<up.x()<<up.y()<<up.z()<<std::endl;

            std::cout<<" End Rotation"<<std::endl;
        }

        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_8)
        {
            std::cout<<"Rotation"<<std::endl;
            md=viewer.getCamera()->getViewMatrix();


            angle=(3.142/180)*2;

            md.getLookAt(eye,centre,up);
            std::cout<<"up="<<up.x()<<up.y()<<up.z()<<std::endl;

            osg::Vec3f actuallook=centre-eye;
            actuallook=actuallook/(actuallook.length());

            osg::Quat qa(angle,osg::Vec3f(up.x(),up.y(),up.z()));

            osg::Vec3f look= (qa * actuallook);
            look=look/(look.length());
            centre = eye+(look*actuallook.length());

            viewer.getCamera()->setViewMatrixAsLookAt(eye, centre, osg::Vec3d(up.x(),up.y(),up.z())) ;
            std::cout<<"up="<<up.x()<<up.y()<<up.z()<<std::endl;

            std::cout<<" End Rotation"<<std::endl;
        }           


        if(ea.getKey()==osgGA::GUIEventAdapter::KEY_Space)
        {
            md=originalmd;
            viewer.getCamera()->setViewMatrix(originalmd);

        }
        return false;
    }    
    default:
        return false;
}
}



int main( int argc, char **argv )
 {



osg::ref_ptr<osg::Group> scene = new  osg::Group;

//scene->addChild(osgDB::readNodeFile("F:\\Fantasy Mall\\Fantasy Mall\\Fantasy_Mall.obj"));

scene->addChild(osgDB::readNodeFile("cessna.osg"));

viewer.addEventHandler(new osgViewer::WindowSizeHandler);
viewer.addEventHandler(new PickHandler());

viewer.setSceneData(scene.get());

const osg::BoundingSphere& bs = scene->getBound();


viewer.getCamera()->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f, -(3*bs.radius()),0.0f), bs.center(), osg::Z_AXIS) ;

md=viewer.getCamera()->getViewMatrix();
originalmd=md;



viewer.realize();

while(!viewer.done())
{

    //viewer.getCamera()->setViewMatrix(md);
    viewer.frame();
}


}