博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原][osgEarth]添加自由飞行漫游器
阅读量:6344 次
发布时间:2019-06-22

本文共 16263 字,大约阅读时间需要 54 分钟。

//头文件里

#define MANIPULATOR_W 0x01

#define MANIPULATOR_A 0x02
#define MANIPULATOR_S 0x04
#define MANIPULATOR_D 0x08
#define MANIPULATOR_R 0x10
#define MANIPULATOR_F 0x20

 

#define MANIPULATOR_MAX 127

//所有漫游器都必须实现的4个纯虚函数          virtual void setByMatrix(const osg::Matrixd& matrix);  //设置相机的位置姿态矩阵          virtual void setByInverseMatrix(const osg::Matrixd& matrix) {}  //设置相机的视图矩阵          virtual osg::Matrixd getMatrix() const;  //获取相机的姿态矩阵         virtual osg::Matrixd getInverseMatrix() const;   //获取相机的视图矩阵         //所有操作在这里响应        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);        void reFreshSawEarth();//在当前经纬度,姿态回正:1.视点向地面 2.头部向正北        void reFreshSawSkyline(osg::Vec3d eye=osg::Vec3d(0,0,0));//在当前经纬度,头部回正:1.视点中心不变 2.头部向天        osg::Vec3d   _eye;               //视点位置          osg::Quat    _rotate;            //旋转姿态         osg::Quat    _rotateNew;            //旋转姿态         osg::ref_ptr
_root; osg::observer_ptr
_node; osg::observer_ptr
_mapNode; osg::ref_ptr
_srs; float _speed; //速度 float _speedBase; float _speedMultiple; //速度倍数 float _timerRoll; bool _updateAltitude; bool _updateRollStart; //更新滚转 bool _updateRoll; //更新滚转 bool _openStree; // Internal event stack comprising last two mouse events. osg::ref_ptr
_ga_t1; osg::ref_ptr
_ga_t0;

 

 

//cpp文件void setByMatrix(const osg::Matrixd& matrix)//设置相机的位置姿态矩阵  {    gMinpulatorContgrol = 0;    _eye = matrix.getTrans();    osg::Vec3d  v3Eye, v3Center, v3Up;    v3Eye = _eye;//使用相机实际位置    osg::Vec3d v3EyeLonLat;    _srs->transformFromWorld(v3Eye, v3EyeLonLat);    //先获取当前位置的经纬度,再获取当前正上,正北    osg::Matrix mRealAttitude;    if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正        //reFreshSawSkyline();        _updateRoll = true;    else        reFreshSawEarth();}  osg::Matrixd getInverseMatrix() const{    osg::Matrix mat;    mat.setRotate(-_rotate);    mat.preMultTranslate(-_eye);    return mat;    //return osg::Matrixd::inverse(getMatrix());}void setNode(osg::Node* node){    // you can only set the node if it has not already been set, OR if you are setting    // it to NULL. (So to change it, you must first set it to NULL.) This is to prevent    // OSG from overwriting the node after you have already set on manually.    if (node == 0L || !_node.valid())    {        _root = node;        _node = node;        _mapNode = 0L;        _srs = 0L;        established();        osg::Matrix matrixGood1;        GeoPoint point1(_srs, 0, 0, 10000.0);        point1.createLocalToWorld(matrixGood1);        _eye = matrixGood1.getTrans();        osg::Vec3d worldup;        point1.createWorldUpVector(worldup);        osg::Matrix mat;        matrixGood1.getRotate().get(mat);        osg::Vec3d eye, center, up;        mat.getLookAt(eye, center, up);        mat.makeLookAt(eye, -worldup, up);        _rotate = mat.getRotate();    }}void reFreshSawSkyline(osg::Vec3d eye){    osg::Vec3d v3Eye;    osg::Vec3d v3EyeLonLat;    v3Eye = _eye;//使用相机实际位置        if (eye != osg::Vec3d(0, 0, 0))    {        v3Eye += eye;    }    _srs->transformFromWorld(v3Eye, v3EyeLonLat);    //先获取当前位置的经纬度,再获取当前正上,正北    if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正    {
osg::Matrix mRealAttitude; GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z()); gEyeGeo.createLocalToWorld(mRealAttitude); osg::Vec3d v3HorizonUp;//指天向量 gEyeGeo.createWorldUpVector(v3HorizonUp); _rotate.get(mRealAttitude);//要使用当前相机的姿态 osg::Vec3d theEye,v3Center, v3Up; mRealAttitude.getLookAt(theEye, v3Center, v3Up);//获取新的位置和姿态 osg::Vec3d v3Direction = v3Center - theEye; mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), v3Direction, v3HorizonUp); _rotate = mRealAttitude.getRotate(); } //_eye = v3Eye;}void reFreshSawEarth(){ osg::Vec3d v3Eye, v3Center, v3Up; v3Eye = _eye;//使用相机实际位置 osg::Vec3d v3EyeLonLat; _srs->transformFromWorld(v3Eye, v3EyeLonLat); //先获取当前位置的经纬度,再获取当前正上,正北 osg::Matrix mRealAttitude; if (v3EyeLonLat.z() < 0)//v3EyeLonLat.z()是眼点实际海拔 v3EyeLonLat.z() = 100;//将海拔0以下的物体拉到海拔100米 GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z()); gEyeGeo.createLocalToWorld(mRealAttitude); osg::Vec3d v3HorizonUp;//指天向量 gEyeGeo.createWorldUpVector(v3HorizonUp); _eye = mRealAttitude.getTrans(); mRealAttitude.getLookAt(v3Eye, v3Center, v3Up);//获取新的位置和姿态 osg::Matrix mDeviationAttitude;//向北位置偏移0.00001纬度,为了计算正北方向 GeoPoint gDeviationEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y() + 0.00001, v3EyeLonLat.z()); gDeviationEyeGeo.createLocalToWorld(mDeviationAttitude); osg::Vec3d v3DeviationNorthPoint = mDeviationAttitude.getTrans(); osg::Vec3d v3NorthHeadUp = v3DeviationNorthPoint - v3Eye; v3NorthHeadUp.normalize();//指北向量 if (v3EyeLonLat.y() < 89.99999 && v3EyeLonLat.y() > -90.0) { mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), -v3HorizonUp, v3NorthHeadUp); } _rotate = mRealAttitude.getRotate();}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us){ bool handled = false; switch (ea.getEventType()) { case(osgGA::GUIEventAdapter::FRAME): { if (gMinpulatorContgrol & MANIPULATOR_MAX) { osg::Vec3d v3Direction; //视点方向 osg::Matrix mCameraQuat; osg::Vec3d v3Eye, v3Center, v3Up; _rotate.get(mCameraQuat); mCameraQuat.getLookAt(v3Eye, v3Center, v3Up);//这里的v3Eye不是实际相机的位置,而是0,0,0 v3Direction = v3Center - v3Eye; v3Direction.normalize(); /*********************************************************/ osg::Vec3d RealEye = _eye; osg::Vec3d testHight = v3Direction*100; double _DvalueHight = 0.0; { osg::Vec3d testLonLat1, testLonLat2; _srs->transformFromWorld(RealEye, testLonLat1); RealEye = _eye; osg::Vec3d testEye = RealEye + testHight; _srs->transformFromWorld(testEye, testLonLat2); _DvalueHight = abs(testLonLat2.z() - testLonLat1.z()); if (_DvalueHight < 10)//趋近水平使用水平方向 { testLonLat2.z() = testLonLat1.z(); _srs->transformToWorld(testLonLat2, testEye); v3Direction = testEye - RealEye; v3Direction.normalize(); } } osg::Vec3d v3CrossVector = v3Up^v3Direction; v3CrossVector.normalize(); /*********************************************************/ //计算地面高度 osg::Vec3d v3EyeLonLat; v3Eye = _eye; _srs->transformFromWorld(v3Eye, v3EyeLonLat); double mAltitude = VRE_ENGINE.GetToolsFunc()->GetGeoPointAltitude(v3EyeLonLat.x(), v3EyeLonLat.y()); float height = osg::clampBetween(v3EyeLonLat.z() - mAltitude, 100.0, 1000000.0); _speed = height / 200.0;//根据离地面高度计算当前速度值 RealEye = _eye; if (gMinpulatorContgrol & MANIPULATOR_W) { RealEye += v3Direction * _speed *_speedMultiple * _speedBase; _updateAltitude = false; }if (gMinpulatorContgrol & MANIPULATOR_A) { RealEye += v3CrossVector * _speed *_speedMultiple * _speedBase; _updateAltitude = false; }if (gMinpulatorContgrol & MANIPULATOR_S) { RealEye -= v3Direction * _speed *_speedMultiple * _speedBase; _updateAltitude = false; }if (gMinpulatorContgrol & MANIPULATOR_D) { RealEye -= v3CrossVector * _speed *_speedMultiple * _speedBase; _updateAltitude = false; }if (gMinpulatorContgrol & MANIPULATOR_R) { //_eye += v3Up * _speed *_speedMultiple * _speedBase; v3EyeLonLat.z() += _speed *_speedMultiple * _speedBase; osg::Vec3d newv3Eye; _srs->transformToWorld(v3EyeLonLat, newv3Eye); RealEye = newv3Eye; _updateAltitude = false; }if (gMinpulatorContgrol & MANIPULATOR_F) { //_eye -= v3Up * _speed *_speedMultiple * _speedBase; v3EyeLonLat.z() -= _speed *_speedMultiple * _speedBase; osg::Vec3d newv3Eye; _srs->transformToWorld(v3EyeLonLat, newv3Eye); RealEye = newv3Eye; _updateAltitude = false; } _eye = RealEye; //reFreshSawSkyline(RealEye); } if (_updateRoll) { osg::Vec3d v3Eye; osg::Vec3d v3EyeLonLat; v3Eye = _eye;//使用相机实际位置 _srs->transformFromWorld(v3Eye, v3EyeLonLat); //先获取当前位置的经纬度,再获取当前正上,正北 if (v3EyeLonLat.z() < 10000)//距离地面1千万米以内需要矫正 { osg::Matrix mRealAttitude; GeoPoint gEyeGeo(_srs, v3EyeLonLat.x(), v3EyeLonLat.y(), v3EyeLonLat.z()); gEyeGeo.createLocalToWorld(mRealAttitude); osg::Vec3d v3HorizonUp;//指天向量 gEyeGeo.createWorldUpVector(v3HorizonUp); _rotate.get(mRealAttitude);//要使用当前相机的姿态 osg::Vec3d theEye, v3Center, v3Up; mRealAttitude.getLookAt(theEye, v3Center, v3Up);//获取新的位置和姿态 osg::Vec3d v3Direction = v3Center - theEye; mRealAttitude.makeLookAt(osg::Vec3d(0, 0, 0), v3Direction, v3HorizonUp); _rotateNew = mRealAttitude.getRotate(); _updateRoll = false; _updateRollStart = true; _timerRoll = 0.0; } else { _updateRoll = false; } } if (_updateRollStart) { _timerRoll += 0.01; if (_timerRoll > 1.0) { _timerRoll = 1.0; _updateRollStart = false; } _rotate.slerp(_timerRoll, _rotate, _rotateNew); } if (_updateAltitude) { //每帧调节高度 osg::Vec3d newEye = _eye; osg::Vec3d v3EyeLonLat; _srs->transformFromWorld(newEye, v3EyeLonLat); double _mAltitude = v3EyeLonLat.z(); double mAltitude = VRE_ENGINE.GetToolsFunc()->GetGeoPointAltitude(v3EyeLonLat.x(), v3EyeLonLat.y()) + MANIPULATOR_PERSONVIEWHEIGHT; double interprolationAltitude = mAltitude - _mAltitude; if (interprolationAltitude > 1) { interprolationAltitude /= 10.0; v3EyeLonLat.z() += interprolationAltitude; } else if (interprolationAltitude > 0.1) { v3EyeLonLat.z() += 0.1; } else { _updateAltitude = false; } osg::Vec3d FinalEye; _srs->transformToWorld(v3EyeLonLat, FinalEye); _eye = FinalEye; } }break; case(osgGA::GUIEventAdapter::PUSH): { }break; case(osgGA::GUIEventAdapter::RELEASE): { flushMouseEventStack(); }break; case(osgGA::GUIEventAdapter::DRAG): { if (calcMovement(ea))//根据鼠标在屏幕中的位置调整相机转向 { //reFreshSawSkyline(); _updateRoll = true; us.requestRedraw(); return true; } }; case(osgGA::GUIEventAdapter::SCROLL)://由于已经每帧都调整姿态,所以手动滚动不需要了 { osg::Vec3d v3Direction; //视点方向 osg::Matrix mCameraQuat; osg::Vec3d v3Eye, v3Center, v3Up; _rotate.get(mCameraQuat); mCameraQuat.getLookAt(v3Eye, v3Center, v3Up);//这里的v3Eye不是实际相机的位置,而是0,0,0 v3Direction = v3Center - v3Eye; v3Direction.normalize(); osg::Vec3d v3CrossVector = v3Up^v3Direction; v3CrossVector.normalize(); switch (ea.getScrollingMotion()) { case osgGA::GUIEventAdapter::ScrollingMotion::SCROLL_UP: { _eye += v3Direction * _speed *_speedMultiple; //reFreshSawSkyline(); _updateRoll = true; }break; case osgGA::GUIEventAdapter::ScrollingMotion::SCROLL_DOWN: { _eye -= v3Direction * _speed *_speedMultiple; //reFreshSawSkyline(); _updateRoll = true; }break; } //reFreshSawSkyline(); return true; }break; case (osgGA::GUIEventAdapter::KEYDOWN): { if (ea.getKey() == 'r' || ea.getKey() == 'R')//往头部前进 { gMinpulatorContgrol |= MANIPULATOR_R; } if (ea.getKey() == 'f' || ea.getKey() == 'F')//往尾部后退 { gMinpulatorContgrol |= MANIPULATOR_F; } if (ea.getKey() == 'w' || ea.getKey() == 'W' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)//前进 { gMinpulatorContgrol |= MANIPULATOR_W; } if (ea.getKey() == 's' || ea.getKey() == 'S' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)//后退 { gMinpulatorContgrol |= MANIPULATOR_S; } if (ea.getKey() == 'a' || ea.getKey() == 'A' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)//左移 { gMinpulatorContgrol |= MANIPULATOR_A; } if (ea.getKey() == 'd' || ea.getKey() == 'D' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)//右移 { gMinpulatorContgrol |= MANIPULATOR_D; } if (ea.getKey() == '-' || ea.getKey() == '_' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Down)//减10倍移动速度 { _speedBase /= 10.0; if (_speedBase < 0.1) { _speedBase = 0.1; } } if (ea.getKey() == '=' || ea.getKey() == '+' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Up)//加10倍移动速度 { _speedBase *= 10.0; if (_speedBase > 1000.0) { _speedBase = 1000.0; } } if (ea.getKey() == 'h' || ea.getKey() == 'H')//在当前经纬度,姿态回正:1.视点向地面 2.头部向正北 { reFreshSawEarth(); } if (ea.getKey() == 'g' || ea.getKey() == 'G')//在当前经纬度,头部回正:1.视点中心不变 2.头部向天 { reFreshSawSkyline(); } if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_L || ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_R) { _speedMultiple = 10.0; } }break; case (osgGA::GUIEventAdapter::KEYUP): { if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_L || ea.getKey() == osgGA::GUIEventAdapter::KEY_Shift_R) { _speedMultiple = 1.0; } if (ea.getKey() == 'a' || ea.getKey() == 'A' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)//左移 { gMinpulatorContgrol &= ~MANIPULATOR_A; _updateAltitude = true; } if (ea.getKey() == 'd' || ea.getKey() == 'D' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)//右移 { gMinpulatorContgrol &= ~MANIPULATOR_D; _updateAltitude = true; } if (ea.getKey() == 'w' || ea.getKey() == 'W' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)//前进 { gMinpulatorContgrol &= ~MANIPULATOR_W; _updateAltitude = true; } if (ea.getKey() == 'q' || ea.getKey() == 'Q' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Up)//往头部前进 { gMinpulatorContgrol &= ~MANIPULATOR_R; _updateAltitude = true; } if (ea.getKey() == 'e' || ea.getKey() == 'E' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Down)//往尾部后退 { gMinpulatorContgrol &= ~MANIPULATOR_F; _updateAltitude = true; } if (ea.getKey() == 's' || ea.getKey() == 'S' || ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)//后退 { gMinpulatorContgrol &= ~MANIPULATOR_S; _updateAltitude = true; } }break; default: break; } return handled;}

 

转载地址:http://picla.baihongyu.com/

你可能感兴趣的文章
ORM框架Hibernate (四)MyEclipse Hibernate Tool 逆向生成实体类
查看>>
js中substr与substring的区别
查看>>
去掉iphone连接电脑时会出现的弹出窗口
查看>>
【python】-- web开发之HTML
查看>>
vs2015 去除 git 源代码 绑定
查看>>
解决firefox的button按钮文字不能垂直居中
查看>>
网络协议端口号详解
查看>>
大话数据结构读后感——第一章
查看>>
各种排序
查看>>
ts 格式化日期输出
查看>>
Optional
查看>>
sed 命令编辑文本
查看>>
LRUCache 具体解释
查看>>
Activity调用isDestroyed()方法报出,java.lang.NoSuchMethodError
查看>>
使用AFNetworking第三方下载类
查看>>
fhq-treap小结
查看>>
about porting
查看>>
MySQL事务及ACID特性
查看>>
Hadoop_31_MapReduce参数优化
查看>>
linux运维常见英文报错中文翻译(菜鸟必知)
查看>>