osgEarth示例分析——osgearth_manip
生活随笔
收集整理的這篇文章主要介紹了
osgEarth示例分析——osgearth_manip
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
前言
本示例主要演示osgEarth的事件處理的用法,內(nèi)容比較多,這部分功能也很重要。
輸入命令依然采用china-simple.earth的示例,加上了模型,但是模型并沒(méi)有看到,可能是因?yàn)槟P蜎](méi)有放大太小的原因。在代碼中設(shè)置了不加載模型的話,會(huì)繪制兩個(gè)半圓。
// 加載模型,但是看不到,估計(jì)是模型太小,需要放大 osgearth_manipd.exe earth_image/china-simple.earth --model axes.osgt// 并沒(méi)有加載模型 osgearth_manipd.exe earth_image/china-simple.earth --model modelToLoad// 不加載模型,會(huì)默認(rèn)創(chuàng)建一個(gè)半球,距離太遠(yuǎn)的話,半球也看不到 osgearth_manipd.exe earth_image/china-simple.earth執(zhí)行效果
按下W鍵,開(kāi)啟坐標(biāo),也就是黃色的兩條線,交點(diǎn)始終跟隨 Thing 1 節(jié)點(diǎn)。
按鍵說(shuō)明
| * | 左鍵 | 按住左鍵拖動(dòng)地球 | * | u | 看不出來(lái),沒(méi)啥變化 |
| * | 中鍵 | 按住中鍵可以旋轉(zhuǎn)地球 | * | o | 切換操作器,地球會(huì)有大小變化 |
| * | 右鍵 | 按住右鍵前后移動(dòng),縮放地球 | * | 8 | 視角綁定thing 1,也可以說(shuō)跟蹤 |
| * | 右鍵/左鍵 雙擊 | 越來(lái)越遠(yuǎn)/越來(lái)越近 | * | 9 | 視角綁定thing 2,也可以說(shuō)跟蹤 |
| * | 滾輪滾動(dòng) | 視角遠(yuǎn)近控制 | * | t | 地球三種轉(zhuǎn)動(dòng)狀態(tài)的切換 |
| * | arrows | shift+上/下/左/右鍵, 好像沒(méi)啥作用 | * | b | 解除綁定 '8' ‘9’,,或者說(shuō)解除跟蹤 |
| * | shift+左鍵 | 看不出來(lái),沒(méi)啥變化 | * | a | 看不出來(lái),沒(méi)啥變化 |
| * | q | 看不出來(lái),沒(méi)啥變化 | |||
| * | k | 看不出來(lái),沒(méi)啥變化 | |||
| * | L | 看不出來(lái),沒(méi)啥變化 | |||
| * | j | 定位到可以看見(jiàn)一組點(diǎn)的視點(diǎn) | |||
| * | W | 繪制兩條線,交點(diǎn)始終定位在thing 1上,屏幕坐標(biāo)系 |
[注] 必須在英文下輸入,如果沒(méi)有注意,在中文狀態(tài)下輸入字符,地球會(huì)被卡住。此時(shí)只能退出重新運(yùn)行程序。
thing1 thing 2,這兩個(gè)文本是移動(dòng)的。
代碼分析
#include <string>#include <osg/Notify> #include <osg/Timer> #include <osg/ShapeDrawable> #include <osg/Depth> #include <osg/PositionAttitudeTransform> #include <osgGA/StateSetManipulator> #include <osgGA/GUIEventHandler> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osgEarth/GeoMath> #include <osgEarth/GeoTransform> #include <osgEarth/MapNode> #include <osgEarth/TerrainEngineNode> #include <osgEarth/Viewpoint> #include <osgEarthUtil/EarthManipulator> #include <osgEarthUtil/Controls> #include <osgEarthUtil/ExampleResources> #include <osgEarthUtil/LogarithmicDepthBuffer> #include <osgEarthUtil/ViewFitter> #include <osgEarthAnnotation/AnnotationUtils> #include <osgEarthAnnotation/LabelNode> #include <osgEarthSymbology/Style> #include <osgEarth/ScreenSpaceLayout>using namespace osgEarth::Util; using namespace osgEarth::Util::Controls; using namespace osgEarth::Annotation;#define D2R (osg::PI/180.0) #define R2D (180.0/osg::PI)namespace {/*** Tether callback test.是否綁定*/struct TetherCB : public EarthManipulator::TetherCallback{void operator()(osg::Node* node){if ( node ) {OE_WARN << "Tether on\n";}else {OE_WARN << "Tether off\n";}}};/*** Builds our help menu UI.創(chuàng)建左上角的說(shuō)明文檔*/Container* createHelp( osgViewer::View* view ){const char* text[] ={"left mouse :", "pan","middle mouse :", "rotate","right mouse :", "continuous zoom","double-click :", "zoom to point","scroll wheel :", "zoom in/out","arrows :", "pan",//"1-6 :", "fly to preset viewpoints","shift-left-mouse :", "locked pan","u :", "toggle azimuth lock","o :", "toggle perspective/ortho","8 :", "Tether to thing 1","9 :", "Tether to thing 2","t :", "cycle tethermode","b :", "break tether","a :", "toggle viewpoint arcing","q :", "toggle throwing","k :", "toggle collision","L :", "toggle log depth buffer"//"W :", "坐標(biāo)系", // 源代碼并沒(méi)有這兩個(gè)提示//"j :", "定位到指定點(diǎn)組的視點(diǎn)",};Grid* g = new Grid();// 創(chuàng)建網(wǎng)格unsigned i, c, r;std::cout << sizeof(text) << std::endl; // 存儲(chǔ)所有指針占位多少std::cout << sizeof(text[0]) << std::endl; // 每個(gè)指針占位多少for( i=0; i<sizeof(text)/sizeof(text[0]); ++i ){c = i % 2;r = i / 2;g->setControl( c, r, new LabelControl(text[i]) );// 兩列c,i行r,顯示label控件}VBox* v = new VBox();v->addControl( g );// 將網(wǎng)格控件放入VBox控件中return v;}/*** Some preset viewpoints to show off the setViewpoint function.*/static Viewpoint VPs[] = {Viewpoint( "Africa", 0.0, 0.0, 0.0, 0.0, -90.0, 10e6 ),Viewpoint( "California", -121.0, 34.0, 0.0, 0.0, -90.0, 6e6 ),Viewpoint( "Europe", 0.0, 45.0, 0.0, 0.0, -90.0, 4e6 ),Viewpoint( "Washington DC", -77.0, 38.0, 0.0, 0.0, -90.0, 1e6 ),Viewpoint( "Australia", 135.0, -20.0, 0.0, 0.0, -90.0, 2e6 ),Viewpoint( "Boston", -71.096936, 42.332771, 0, 0.0, -90, 1e5 )};/*** Handler that demonstrates the "viewpoint" functionality in * osgEarthUtil::EarthManipulator. Press a number key to fly to a viewpoint.*/struct FlyToViewpointHandler : public osgGA::GUIEventHandler {FlyToViewpointHandler( EarthManipulator* manip ) : _manip(manip) { }bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ){if ( ea.getEventType() == ea.KEYDOWN && ea.getKey() >= '1' && ea.getKey() <= '6' ){_manip->setViewpoint( VPs[ea.getKey()-'1'], 4.0 );// 根據(jù)設(shè)置好的位置,123456定位不同的地點(diǎn)aa.requestRedraw();}return false;}osg::observer_ptr<EarthManipulator> _manip;};/*** Toggles the logarithmic depth buffer切換對(duì)數(shù)深度緩沖區(qū)*/struct ToggleLDB : public osgGA::GUIEventHandler{ToggleLDB(char key) : _key(key), _installed(false) { }// key=Lbool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){if ( !_installed ){_nfratio = aa.asView()->getCamera()->getNearFarRatio();// 獲取到近/遠(yuǎn)率_ldb.install(aa.asView()->getCamera());aa.asView()->getCamera()->setNearFarRatio(0.00001);}else{_ldb.uninstall(aa.asView()->getCamera());aa.asView()->getCamera()->setNearFarRatio(_nfratio);}_installed = !_installed;// 每次切換return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle LDB"));}char _key;float _nfratio;bool _installed;osgEarth::Util::LogarithmicDepthBuffer _ldb;};/*** Toggles screen space layout on the sismulated objects 切換模擬對(duì)象的屏幕空間布局*/struct ToggleSSL : public osgGA::GUIEventHandler{ToggleSSL(osg::Group* g, char key) : _group(g), _key(key), _installed(false) { }// key=)bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){_installed = !_installed;ScreenSpaceLayout::setDeclutteringEnabled(_installed);// 啟動(dòng)或禁用清理return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle SSL"));}char _key;osg::Group* _group;bool _installed;};/*** Handler to toggle "azimuth locking", which locks the camera's relative Azimuth* while panning. For example, it can maintain "north-up" as you pan around. The* caveat is that when azimuth is locked you cannot cross the poles.*/struct LockAzimuthHandler : public osgGA::GUIEventHandler // 鎖定/解鎖 方位角{LockAzimuthHandler(char key, EarthManipulator* manip) // 傳入key = u: _key(key), _manip(manip) { }bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){bool lockAzimuth = _manip->getSettings()->getLockAzimuthWhilePanning();std::cout << "按下 u" << std::endl;// 確實(shí)收到消息,但是在操作上并沒(méi)有看到所定方位角_manip->getSettings()->setLockAzimuthWhilePanning(!lockAzimuth);// 設(shè)置為當(dāng)前狀態(tài)相反的狀態(tài)aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle azimuth locking"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Handler to toggle "viewpoint transition arcing", which causes the camera to "arc"* as it travels from one viewpoint to another.*/struct ToggleArcViewpointTransitionsHandler : public osgGA::GUIEventHandler{ToggleArcViewpointTransitionsHandler(char key, EarthManipulator* manip): _key(key), _manip(manip) { }// key=abool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){bool arc = _manip->getSettings()->getArcViewpointTransitions();std::cout << "按下 a" << std::endl;// 確實(shí)收到消息,但是沒(méi)看出什么變化_manip->getSettings()->setArcViewpointTransitions(!arc);aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Arc viewpoint transitions"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Toggles the throwing feature.切換投擲功能。*/struct ToggleThrowingHandler : public osgGA::GUIEventHandler{ToggleThrowingHandler(char key, EarthManipulator* manip): _key(key), _manip(manip)// key=q{}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){bool throwing = _manip->getSettings()->getThrowingEnabled();std::cout << "按下 q" << std::endl;// 確實(shí)收到消息,但是沒(méi)看出什么變化_manip->getSettings()->setThrowingEnabled( !throwing );aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle throwing"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Toggles the collision feature.切換碰撞功能。*/struct ToggleCollisionHandler : public osgGA::GUIEventHandler{ToggleCollisionHandler(char key, EarthManipulator* manip): _key(key), _manip(manip)// key=k{}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){bool value = _manip->getSettings()->getTerrainAvoidanceEnabled();std::cout << "按下 k" << std::endl;// 確實(shí)收到消息,但是沒(méi)看出什么變化_manip->getSettings()->setTerrainAvoidanceEnabled( !value );aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle terrain avoidance"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Breaks a tether.三種狀態(tài)的切換*/struct CycleTetherMode : public osgGA::GUIEventHandler{CycleTetherMode(char key, EarthManipulator* manip): _key(key), _manip(manip) { }// key=tbool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){EarthManipulator::TetherMode mode = _manip->getSettings()->getTetherMode();if ( mode == _manip->TETHER_CENTER ) { _manip->getSettings()->setTetherMode( _manip->TETHER_CENTER_AND_HEADING );// 相機(jī)將跟隨節(jié)點(diǎn),僅跟隨方向旋轉(zhuǎn)OE_NOTICE << "Tether mode = TETHER_CENTER_AND_HEADING\n";}else if ( mode == _manip->TETHER_CENTER_AND_HEADING ) {_manip->getSettings()->setTetherMode( _manip->TETHER_CENTER_AND_ROTATION ); // 攝影機(jī)將跟隨節(jié)點(diǎn)和節(jié)點(diǎn)所做的所有旋轉(zhuǎn)OE_NOTICE << "Tether mode = TETHER_CENTER_AND_ROTATION\n";}else {_manip->getSettings()->setTetherMode( _manip->TETHER_CENTER );// 攝影機(jī)將跟隨節(jié)點(diǎn)的中心。OE_NOTICE << "Tether mode = CENTER\n";}aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Cycle Tether Mode"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Breaks a tether.解綁*/struct BreakTetherHandler : public osgGA::GUIEventHandler{BreakTetherHandler(char key, EarthManipulator* manip): _key(key), _manip(manip) { }//key=bbool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){_manip->clearViewpoint();// 解除所有操作器綁定,恢復(fù)自由狀態(tài)。thing1和 thing2 的狀態(tài)改變明顯aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Break a tether"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** Adjusts the position offset.調(diào)整位置偏移。*/struct SetPositionOffset : public osgGA::GUIEventHandler{SetPositionOffset(EarthManipulator* manip): _manip(manip) { }bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && (ea.getModKeyMask() & ea.MODKEY_SHIFT) ){Viewpoint oldvp = _manip->getViewpoint();double seconds = 0.5; // 時(shí)間秒。每次切換都需要0.5秒if ( ea.getKey() == ea.KEY_Left )// 左鍵{Viewpoint vp;vp.positionOffset() = oldvp.positionOffset().get() + osg::Vec3f(-1000,0,0);_manip->setViewpoint( vp, seconds );}else if ( ea.getKey() == ea.KEY_Right )// 右鍵{Viewpoint vp;vp.positionOffset() = oldvp.positionOffset().get() + osg::Vec3f(1000,0,0);_manip->setViewpoint( vp, seconds );}else if ( ea.getKey() == ea.KEY_Up )// 上鍵{Viewpoint vp;vp.positionOffset() = oldvp.positionOffset().get() + osg::Vec3f(0,0,1000);_manip->setViewpoint( vp, seconds );}else if ( ea.getKey() == ea.KEY_Down )// 下鍵{Viewpoint vp;vp.positionOffset() = oldvp.positionOffset().get() + osg::Vec3f(0,0,-1000);_manip->setViewpoint( vp, seconds );}aa.requestRedraw();return true;}return false;}osg::ref_ptr<EarthManipulator> _manip;};/*** Toggles perspective/ortho projection matrix. 切換投影矩陣,透視投影矩陣和正射投影矩陣*/struct ToggleProjMatrix : public osgGA::GUIEventHandler{ToggleProjMatrix(char key, EarthManipulator* manip): _key(key), _manip(manip)// ley=o{}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){osg::Matrix proj = aa.asView()->getCamera()->getProjectionMatrix();if ( proj(3,3) == 0 ){OE_NOTICE << "Switching to orthographc.\n";proj.getPerspective(_vfov, _ar, _zn, _zf); // 獲取值aa.asView()->getCamera()->setProjectionMatrixAsOrtho(-1, 1, -1, 1, _zn, _zf);// 正射投影矩陣}else{OE_NOTICE << "Switching to perspective.\n";aa.asView()->getCamera()->setProjectionMatrixAsPerspective(_vfov, _ar, _zn, _zf);// 透視矩陣}aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Toggle projection matrix type"));}char _key;osg::ref_ptr<EarthManipulator> _manip;double _vfov, _ar, _zn, _zf;};// 定位到某組點(diǎn)的視點(diǎn),一組點(diǎn)都可以看到struct FitViewToPoints : public osgGA::GUIEventHandler{std::vector<GeoPoint> _points;const SpatialReference* _mapSRS;FitViewToPoints(char key, EarthManipulator* manip, const SpatialReference* mapSRS): _key(key), _manip(manip), _mapSRS(mapSRS)// key=j{// Set up a list of control pointsconst SpatialReference* srs = SpatialReference::get("wgs84");_points.push_back(GeoPoint(srs, -120, 30, 0));_points.push_back(GeoPoint(srs, -100, 45, 0));}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){// fitter 創(chuàng)建適合攝影機(jī)視圖平截頭體的視點(diǎn),以盡可能緊密地包圍一組地理空間點(diǎn)。ViewFitter fitter(_mapSRS, aa.asView()->getCamera());fitter.setBuffer( 100000.0 );Viewpoint vp;if (fitter.createViewpoint(_points, vp))// 根據(jù)_points重新生成一個(gè)vp視點(diǎn){_manip->setViewpoint(vp);// 定位到vp視點(diǎn)aa.requestRedraw();}return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("FitViewToPoints"));}char _key;osg::ref_ptr<EarthManipulator> _manip;};/*** A simple simulator that moves an object around the Earth. We use this to* demonstrate/test tethering.*/// 一個(gè)簡(jiǎn)單的模擬器,可以使物體繞地球運(yùn)動(dòng)。用來(lái)演示跟蹤thingstruct Simulator : public osgGA::GUIEventHandler{Simulator( osg::Group* root, EarthManipulator* manip, MapNode* mapnode, osg::Node* model, const char* name, char key): _manip(manip), _mapnode(mapnode), _model(model), _name(name), _key(key) // key=8 或 9{if ( !model ){ // 模型不存在,則創(chuàng)建一個(gè)半球,半徑和顏色_model = AnnotationUtils::createHemisphere(250.0, osg::Vec4(1,.7,.4,1));std::cout << "no model" << std::endl;}_geo = new GeoPositionNode();_geo->getPositionAttitudeTransform()->addChild(_model);Style style;TextSymbol* text = style.getOrCreate<TextSymbol>();text->size() = 32.0f;text->declutter() = false;text->pixelOffset()->set(50, 50);// 文本偏移像素點(diǎn)_label = new LabelNode(_name, style);// _name 即要顯示的名稱_label->setDynamic( true );// 因?yàn)槲谋疽苿?dòng),所以此處設(shè)置為true_label->setHorizonCulling(false);// 不需要裁剪_geo->getPositionAttitudeTransform()->addChild(_label);mapnode->addChild(_geo.get());}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if ( ea.getEventType() == ea.FRAME )// 此語(yǔ)段為標(biāo)簽添加了動(dòng)畫(huà){double t0 = osg::Timer::instance()->time_s();// 儒略日時(shí)間double t = fmod( t0, 6000.0 ) / 6000.0;// t0%6000/6000, 將數(shù)字控制在[0,1)范圍內(nèi)GeoPoint p = _start.interpolate(_end, t);// 差值,在_end和t之間// GeoMath::bearing 以弧度計(jì)算從一個(gè)點(diǎn)到下一個(gè)點(diǎn)的初始方位double bearing = GeoMath::bearing(_start.y(), _start.x(), p.y(), p.x());float a = sin(t0*0.2);// a值沒(méi)有被用float pitch = 0.0;_geo->setPosition(p);_geo->setLocalRotation(osg::Quat(pitch, osg::Vec3d(1, 0, 0)) *osg::Quat(bearing, osg::Vec3d(0, 0, -1)));}else if ( ea.getEventType() == ea.KEYDOWN ){if ( ea.getKey() == _key )// 8 或 9{ Viewpoint vp = _manip->getViewpoint();//vp.setNode( _pat.get() );vp.setNode(_model);vp.range() = 25000.0;vp.pitch() = -45.0;_manip->setViewpoint(vp, 2.0);// 2秒內(nèi)飛到指定位置}return true;}return false;}std::string _name;char _key;MapNode* _mapnode;EarthManipulator* _manip;GeoPoint _start, _end;LabelNode* _label;osg::Node* _model;float _heading;float _pitch;osg::ref_ptr<GeoPositionNode> _geo;};/*** Place an X at the sim entity position, in screen space.* The point of this is to test the EarthManipulator::UpdateCameraCallback* which provides a frame-synched camera matrix (post-update traversal)*/// 創(chuàng)建一個(gè)十字坐標(biāo)struct CalculateWindowCoords : public osgGA::GUIEventHandler{CalculateWindowCoords(char key, EarthManipulator* manip, Simulator* sim): _key(key), _active(false), _sim(sim), _xform(0L){//nop}void onUpdateCamera(const osg::Camera* cam){if (_active){if (!_xform){osg::Geometry* geom = new osg::Geometry();osg::Vec3Array* verts = new osg::Vec3Array();verts->push_back(osg::Vec3(-10000, 0, 0));verts->push_back(osg::Vec3( 10000, 0, 0));verts->push_back(osg::Vec3( 0, -10000, 0));verts->push_back(osg::Vec3( 0, 10000, 0));verts->push_back(osg::Vec3( 0, 0, -10000));verts->push_back(osg::Vec3( 0, 0, 10000));geom->setVertexArray(verts);osg::Vec4Array* colors = new osg::Vec4Array();colors->push_back(osg::Vec4(1, 1, 0, 1));// 黃色線colors->setBinding(colors->BIND_OVERALL);geom->setColorArray(colors);geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, 6));// 6個(gè)點(diǎn),繪制3條線,但屏幕上僅能看出2條線,水平和垂直geom->setCullingActive(false);// 不裁剪geom->getOrCreateStateSet()->setAttributeAndModes(new osg::Depth(osg::Depth::ALWAYS, 0, 1, true), 1);//深度設(shè)置_xform = new osg::MatrixTransform();_xform->addChild(geom);osg::View* view = const_cast<osg::View*>(cam->getView());ControlCanvas::getOrCreate(view)->addChild(_xform);}/// 坐標(biāo)變換 V_clip=M_projection?M_view?M_model?V_local 裁剪坐標(biāo)=透視矩陣*觀察矩陣*模型矩陣*本地坐標(biāo)——來(lái)自O(shè)penGLGeoPoint p = _sim->_geo->getPosition();// 獲取thing1的坐標(biāo)點(diǎn)osg::Vec3d world;p.toWorld(world);// 轉(zhuǎn)化為世界坐標(biāo)osg::Matrix worldToWindow =cam->getViewMatrix() *cam->getProjectionMatrix() *cam->getViewport()->computeWindowMatrix();// 世界坐標(biāo)轉(zhuǎn)到窗口坐標(biāo)osg::Vec3d win = world * worldToWindow;// 得到窗口坐標(biāo)_xform->setMatrix(osg::Matrix::translate(win));}}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == _key){_active = !_active;aa.requestRedraw();return true;}return false;}void getUsage(osg::ApplicationUsage& usage) const{using namespace std;usage.addKeyboardMouseBinding(string(1, _key), string("Show Window Coords"));}osg::MatrixTransform* _xform;Simulator* _sim;bool _active;char _key;};// 更新相機(jī)回調(diào)struct CameraUpdater : public EarthManipulator::UpdateCameraCallback{CalculateWindowCoords* _calc;CameraUpdater(CalculateWindowCoords* calc) : _calc(calc) { }void onUpdateCamera(const osg::Camera* cam){_calc->onUpdateCamera(cam);// 當(dāng)物體運(yùn)動(dòng)時(shí),需要讓十字線跟隨物體運(yùn)動(dòng)}}; }int main(int argc, char** argv) {osg::ArgumentParser arguments(&argc,argv);if (arguments.read("--help") || argc==1){OE_WARN << "Usage: " << argv[0] << " [earthFile] [--model modelToLoad]"<< std::endl;return 0;}osgViewer::Viewer viewer(arguments);// install the programmable manipulator.安裝操作器EarthManipulator* manip = new EarthManipulator();viewer.setCameraManipulator( manip );// UI: 創(chuàng)建幫助說(shuō)明控件,在左上角的位置。當(dāng)鼠標(biāo)移動(dòng)到控件上之后,是無(wú)法點(diǎn)擊到地球上的,沒(méi)有鼠標(biāo)穿透功能。Container* help = createHelp(&viewer);// MapNodeHelper 顯示幫助// load() 加載earth映射文件并處理所有內(nèi)置示例命令行參數(shù)和XML外部變量(help)。osg::Node* earthNode = MapNodeHelper().load( arguments, &viewer, help );if (!earthNode){OE_WARN << "Unable to load earth model." << std::endl;return -1;}osg::Group* root = new osg::Group();root->addChild( earthNode );// 獲取mapNodeosgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode );// user model?// 加載模型,這里傳入osg osgt格式的模型,并沒(méi)有顯示osg::ref_ptr<osg::Node> model;std::string modelFile;if (arguments.read("--model", modelFile))model = osgDB::readRefNodeFile(modelFile + ".osgearth_shadergen");osg::Group* sims = new osg::Group();root->addChild( sims );const SpatialReference* wgs84 = SpatialReference::get("wgs84");// 坐標(biāo)系// Simulator for tethering: 系留模擬器// thing 1 和 thing 2 會(huì)隨著時(shí)間移動(dòng)Simulator* sim1 = new Simulator(sims, manip, mapNode, model.get(), "Thing 1", '8');// 8:綁住第一個(gè)物體sim1->_name = "Thing 1";sim1->_start = GeoPoint(wgs84, 45.0, 55.0, 10000);// 開(kāi)始坐標(biāo)點(diǎn)sim1->_end = GeoPoint(wgs84, -45, -55.0, 10000); // 結(jié)束坐標(biāo)點(diǎn)viewer.addEventHandler(sim1); // 加入到操作器Simulator* sim2 = new Simulator(sims, manip, mapNode, model.get(), "Thing 2", '9');// 9:綁住第二個(gè)物體sim2->_name = "Thing 2";sim2->_start = GeoPoint(wgs84, 45.0, 54.0, 10000);sim2->_end = GeoPoint(wgs84, -44.0, -54.0, 10000);viewer.addEventHandler(sim2);manip->getSettings()->getBreakTetherActions().push_back( EarthManipulator::ACTION_GOTO ); // 操作器動(dòng)作,直接過(guò)去 // Set the minimum distance to something larger than the default// 距離物體小于最小距離時(shí),物體會(huì)變大manip->getSettings()->setMinMaxDistance(10.0, manip->getSettings()->getMaxDistance());// Sets the maximum focal point offsets (usually for tethering)manip->getSettings()->setMaxOffset(5000.0, 5000.0);// Pitch limits. 俯仰角范圍manip->getSettings()->setMinMaxPitch(-90, 90);viewer.setSceneData( root );//為 鼠標(biāo)左鍵按下、修改鍵、拖動(dòng)鼠標(biāo)的動(dòng)作指定行為。manip->getSettings()->bindMouse(EarthManipulator::ACTION_EARTH_DRAG,osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON,osgGA::GUIEventAdapter::MODKEY_SHIFT );manip->getSettings()->bindMouseClick(EarthManipulator::ACTION_GOTO,osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON,osgGA::GUIEventAdapter::MODKEY_SHIFT);manip->getSettings()->setArcViewpointTransitions( true ); // 設(shè)置tether連接和斷裂時(shí)的動(dòng)作回調(diào)manip->setTetherCallback( new TetherCB() );//viewer.addEventHandler(new FlyToViewpointHandler( manip ));// 添加 自定義的各個(gè)事件處理viewer.addEventHandler(new LockAzimuthHandler('u', manip));viewer.addEventHandler(new ToggleArcViewpointTransitionsHandler('a', manip));viewer.addEventHandler(new ToggleThrowingHandler('q', manip));viewer.addEventHandler(new ToggleCollisionHandler('k', manip));viewer.addEventHandler(new ToggleProjMatrix('o', manip));viewer.addEventHandler(new BreakTetherHandler('b', manip));viewer.addEventHandler(new CycleTetherMode('t', manip));viewer.addEventHandler(new SetPositionOffset(manip));// 設(shè)置偏移viewer.addEventHandler(new ToggleLDB('L'));viewer.addEventHandler(new ToggleSSL(sims, ')'));viewer.addEventHandler(new FitViewToPoints('j', manip, mapNode->getMapSRS()));// 根據(jù) thing 1 的位置,更新相機(jī)CalculateWindowCoords* calc = new CalculateWindowCoords('W', manip, sim1);// 根據(jù)thing 1計(jì)算窗口坐標(biāo)viewer.addEventHandler(calc);manip->setUpdateCameraCallback(new CameraUpdater(calc));// 相機(jī)回調(diào)viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);while(!viewer.done()){viewer.frame();// simulate slow frame rate//OpenThreads::Thread::microSleep(1000*1000);}return 0; }總結(jié)
以上是生活随笔為你收集整理的osgEarth示例分析——osgearth_manip的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 域控服务器怎么开策略,组策略(域和域服务
- 下一篇: 《想做视频号必须要懂的知识——音质篇》