前言

本示例分析osgearth操作深空场景,或者是银河系场景,可以想象人拿着相机站在地球表面上观看天空/银河系的场景。

重点是相机操作器的使用。

在命令框输入执行程序,在data路径下有加载的图,且被写入了earth文件。

// 两个文件仅加载图片不同
osgearth_skyviewd.exe ..\..\..\tests\skyview1.earthosgearth_skyviewd.exe ..\..\..\tests\skyview2.earth

运行结果

天球场景。

第三幅图,特别像带VR眼镜,周围可以看到不同的场景,相机此时像站在十字路口,看周围的场景。

类分析

重点就是处理handle的操作器。下面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;

代码分析

仅将操作器的实现文件和主程序文件拷贝到此处。

osgearth_skyview.cpp文件

#include <osgViewer/Viewer>
#include <osg/CullFace>
#include <osgEarth/Notify>
#include <osgEarthUtil/ExampleResources>
#include "SkyManipulator"#define LC "[viewer] "using namespace osgEarth;
using namespace osgEarth::Util;int
usage(const char* name)
{OE_NOTICE << "\nUsage: " << name << " file.earth" << std::endl<< MapNodeHelper().usage() << std::endl;return 0;
}int
main(int argc, char** argv)
{osg::ArgumentParser arguments(&argc,argv);// help?if ( arguments.read("--help") )return usage(argv[0]);// Increase the fov to provide a more immersive experience.// 增加fov值以提供更沉浸的体验。vfov:视野(Field of View),通常设置45度// 如果想要一个末日风格的结果,可以将其设置一个更大的值float vfov = 100.0f;arguments.read("--vfov", vfov); // 也可以支持命令行输入// create a viewer:osgViewer::Viewer viewer(arguments);// Tell the database pager to not modify the unref settings 不修改任何设置viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy( false, false );// thread-safe initialization of the OSG wrapper manager. Calling this here// prevents the "unsupported wrapper" messages from OSG// 获取 图片 包装管理器osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper("osg::Image");// disable the small-feature cullingviewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);// set a near/far ratio that is smaller than the default. This allows us to get// closer to the ground without near clipping. If you need more, use --logdepthviewer.getCamera()->setNearFarRatio(0.0001);if ( vfov > 0.0 ){double fov, ar, n, f;viewer.getCamera()->getProjectionMatrixAsPerspective(fov, ar, n, f);// 获取到透视矩阵的各个参数viewer.getCamera()->setProjectionMatrixAsPerspective(vfov, ar, n, f);// 重新设置透视矩阵的各个参数}// load an earth file, and support all or our example command-line options// and earth file <external> tags    osg::Node* node = MapNodeHelper().load( arguments, &viewer );//Set our custom manipulatorviewer.setCameraManipulator(new SkyManipulator());// 天空的操作器,继承自osgGA::CameraManipulator的操作器//viewer.setCameraManipulator( new osgGA::FirstPersonManipulator() );if ( node ){// Disable backface cullingnode->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);viewer.setSceneData( node );while(!viewer.done()){viewer.frame();            }}else{return usage(argv[0]);}
}

SkyManipulator.cpp 文件

#include "SkyManipulator"
#include <iostream>SkyManipulator::SkyManipulator():
_heading(0.0), // 偏航角
_pitch(0.0),   // 俯仰角
_distance(1.0),// 距离
_prevX(FLT_MAX),// 初始(X, Y) 坐标点值
_prevY(FLT_MAX)
{
}void SkyManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}void SkyManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
{
}osg::Matrixd SkyManipulator::getMatrix() const
{osg::Quat rot = getRotation();return osg::Matrixd::translate(0,0,-_distance) *  osg::Matrixd::rotate(rot);
}osg::Matrixd SkyManipulator::getInverseMatrix() const
{return osg::Matrixd::inverse(getMatrix());
}bool SkyManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{double maxDistance = osg::WGS_84_RADIUS_EQUATOR;// 地球(赤道/长)半径if (ea.getEventType() == osgGA::GUIEventAdapter::SCROLL){double speed = 0.1;double diff = (maxDistance - _distance) * speed;if (ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_UP){_distance += diff; // 滚轮向上}else{_distance -= diff; // 滚轮向下}_distance = osg::clampBetween(_distance, 0.0, maxDistance);return true;}else if (ea.getEventType() == osgGA::GUIEventAdapter::DRAG)// 拖拽{if (_prevX != FLT_MAX && _prevY != FLT_MAX){float dx = ea.getX() - _prevX;float dy = ea.getY() - _prevY;double maxSpeed = osg::PI * 2.0 / 300.0;double minSpeed = osg::PI * 2.0 / 30000.0;// _distance距离较远时,速度大;_distance距离较近时,速度减小double speed = minSpeed + (1.0 - _distance / maxDistance) * (maxSpeed - minSpeed);_heading -= dx * speed;_pitch -= dy * speed;}_prevX = ea.getX();_prevY = ea.getY();return true;}else if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH)// 获取坐标位置{_prevX = ea.getX();_prevY = ea.getY();}else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)//释放鼠标后,两个点位置还原{_prevX = FLT_MAX;_prevY = FLT_MAX;}else if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN){if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Space)// 空格键,回到home位置{home(0.0);}}return false;
}
// 得到旋转角
osg::Quat SkyManipulator::getRotation() const
{osg::Quat azim_q (  _heading,            osg::Vec3d(0,0,1) );osg::Quat pitch_q( -_pitch-osg::PI_2, osg::Vec3d(1,0,0) );osg::Matrix newRot = osg::Matrixd( azim_q * pitch_q );return osg::Matrixd::inverse(newRot).getRotate();
}void
SkyManipulator::home(double unused)
{_heading = 0.0;_pitch = 0.0;_distance = 0.0;
}void
SkyManipulator::home(const osgGA::GUIEventAdapter& ,osgGA::GUIActionAdapter& us)
{home( 0.0 );us.requestRedraw();
}

osgEarth示例分析——osgearth_skyview相关推荐

  1. osgEarth示例分析——osgearth_annotation

    前言 本章为osgearth_annotation示例分析,示例中采用osgEarth提供的类,绘制标签.线.billboard.遮盖图.墙等内容. 运行时,在生成的可执行路径下,打开命令框,输入: ...

  2. osgEarth示例分析——osgearth_manip

    前言 本示例主要演示osgEarth的事件处理的用法,内容比较多,这部分功能也很重要. 输入命令依然采用china-simple.earth的示例,加上了模型,但是模型并没有看到,可能是因为模型没有放 ...

  3. osgEarth示例分析——osgearth_elevation

    前言 osgearth_elevation示例,展示了如何通过点击地球获取不同定义下的高程数据.包括:MSL高程.HAE高程.EGM96高程.点击按钮,可以移除高程图层. MSL高程:是mean se ...

  4. osgEarth示例分析——osgearth_graticule

    前言 本示例最具有借鉴的功能:绘制网格.网格上的文字显示.拾取地球的坐标.在地球网格示例中,可以设置4种网格.执行命令如下: // --geodetic osgearth_graticuled.exe ...

  5. osgEarth示例分析——osgearth_srstest

    前言 osgearth_srstest示例,主要涉及到两个坐标系转换,wgs84→egm96  wgs84→plate-carre wgs84:World Geodetic System 1984,是 ...

  6. osgEarth示例分析——osgearth_eci

    前言 osgearth_eci示例,展示了J2000的天体坐标系和ECEF地固系的转换,绘制坐标系,以及读取卫星参数绘制卫星的功能.绘制卫星轨迹,添加差值效果和未添加差值的效果. 关于卫星两行根数的数 ...

  7. osgEarth示例分析——osgearth_terrainprofile

    前言 osgearth_terrainprofile示例,涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类),用来计算两个点连线之间的地形数据.左下角会根据点击的起 ...

  8. osgEarth示例分析——osgearth_features

    前言 osgearth_features示例,主要演示如何通过代码方式加载shp文件,并设置其样式.在执行时,通过不同 的命令,得到不一样的效果. cmd执行命令: // rasterize 光栅化, ...

  9. osgEarth示例分析——osgearth_los

    前言 osgearth_los示例,创建了模型动画路径.透视的用法.透视的顾名思义:两个点连线,从A到B,视线不被遮挡,则绘制绿色,视线被遮挡的部分,则设置为红色.此示例,加载earth文件时,需要加 ...

最新文章

  1. 华为笔记本写代码真爽,包邮送一台!
  2. Cpp6 封装、继承和多态
  3. Android 把第三方jar 打进java包
  4. a标签用ajax请求传参,Django中如何实现传参的Ajax请求
  5. Myeclipse快捷键总结大全
  6. error记录 | 不能将参数 1 从“const char [5]”转换为“LPCTSTR
  7. 如何使用 abp 创建 module 并应用单独的数据库迁移
  8. mybatisPlus中的updateById无法更新null值的字段
  9. Springboot初次学习
  10. sql server中的varchar和Nvarchar有什么区别?
  11. kingbase自带的驱动在哪_为什么别人家的广告语都能自带BUG?
  12. 浅谈ARP攻击现象和处理办法
  13. Qt环境下调用捷宇高拍仪OCX
  14. 万字详解 GoF 23 种设计模式(多图、思维导图、模式对比),让你一文全面理解
  15. Polynomial Commitments代码实现【2】——lovesh/kzg-poly-commit
  16. ios重签名工具ios-app-signer的使用
  17. 关于删除/卸载win10自带IE 11浏览器后恢复问题
  18. 基于线性回归对男性体脂率的预测
  19. CSS控制print打印样式
  20. win7 查看网络计算机和设备,WIN7 网络发现已关闭 网络计算机和设备不可见

热门文章

  1. DP问题之01背包如此简单
  2. Windows下faceswap的安装
  3. 【跨境电商】如何通过多种营销渠道赢得竞争
  4. JAVA 浏览器下载excel,自定义样式:合并单元格,设置多种背景填充颜色,冻结窗格
  5. RK方案OTG口 OTG与HOST切换
  6. RegularJS 0.2.12 发布,JavaScript MVC 框架
  7. AD报错 unknown pin
  8. ubuntu top命令详解
  9. Dubbo 入门教程与实战(一)上
  10. Perl中的bless的理解