void GraphicsView::addRadar()
{   /****************制作轨迹点数据,测试用**********************/osg::Vec3d startPoint = osg::Vec3d(115, 18, 100000);//起始位置queue <PlanePoint> *PlanePP = new queue <PlanePoint>;//飞机用queue <PlanePoint> *PlanePR = new queue <PlanePoint>;//雷达用int n = 20;double Alltime = 10.0;double Alldis = 10;double _addtime = Alltime / (double)n;double _addDis = 5 / (double)n;double time = 0.0;osg::Vec3d _add = osg::Vec3d(0.0, 0.0, 0.0);for (int i = 0; i < n; i++){osg::Vec3d newpoint = startPoint + _add;PlanePoint *pPP = new PlanePoint();pPP->point = newpoint;pPP->time = time;PlanePP->push(*pPP);PlanePR->push(*pPP);_add = _add + osg::Vec3d(_addDis, _addDis, 0.0);time = time + _addtime;}radarGroup = new osg::Group;//初始化雷达节点组/*添加雷达半球*/osg::Vec3 radarposition = osg::Vec3(116.7176, 20.699, 10); //0点对应的地球坐标double radarDistance = 500000;//雷达最大探测距离//创建精细度对象,精细度越高,细分就越多osg::Vec3d RWpoint;m_pMapSRS->transformToWorld(radarposition, RWpoint);osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;hints->setDetailRatio(1.0f);osg::Geode *geodeR = new osg::Geode;osg::ShapeDrawable* RadarShp = new osg::ShapeDrawable(new osg::Sphere(RWpoint, radarDistance), hints);geodeR->addDrawable(RadarShp);RadarShp->setColor(osg::Vec4(0.0, 0.0, 0.3, 0.2));//设置雷达罩透明效果osg::ref_ptr<osg::StateSet> statesetR = geodeR->getOrCreateStateSet();statesetR->setMode(GL_BLEND, osg::StateAttribute::ON);//Alpha混合开启statesetR->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);//设置透明渲染元statesetR->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);//statesetR->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); //取消深度测试radarGroup->addChild(geodeR);/********************加载雷达动画*************************/ {/****************绘制圆锥,并将顶点平移到0点**********************/        double radarRadius = 10000;//圆锥半径      osg::Cone *Cone = new osg::Cone(osg::Vec3(0, 0, 0), radarRadius, radarDistance);//初始化,cone不能做回调    osg::Matrixd rotMat = osg::Matrixd::rotate(osg::Z_AXIS, osg::Vec3(0, 0, -1));//转180Cone->setRotation(rotMat.getRotate());Cone->setCenter(osg::Vec3(0, 0, 3 * radarDistance / 4));//平移,使得0点位于顶点    /****************加载圆锥**********************/osg::Geode* geode = new osg::Geode;osg::ShapeDrawable* shpcone = new osg::ShapeDrawable(Cone);shpcone->setColor(osg::Vec4(0.5, 0.0, 0.0, 0.25));geode->addDrawable(shpcone);//设置圆锥透明效果osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();stateset->setMode(GL_BLEND, osg::StateAttribute::ON);stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); //取消深度测试//stateset->setRenderBinDetails(11, "RenderBin");//试着加回调函数,解决圆锥长度的问题,先将conebufen放到飞机里面去,这样也可以试试雷达,试了好像不行shpcone->setDataVariance(osg::Object::DYNAMIC);//DrawableUpdateCallback p;// = new DrawableUpdateCallback();//shpcone->setUpdateCallback(new DrawableUpdateCallback());//设置圆锥网格模型osg::ref_ptr<osg::PolygonMode> polyMode = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);stateset->setAttribute(polyMode);/****************加载圆锥1暂时没有找到骨架线和填充同时存在的接口,画两次实现**********************/osg::Geode* geode1 = new osg::Geode;osg::ShapeDrawable* shpcone1 = new osg::ShapeDrawable(Cone);shpcone1->setColor(osg::Vec4(1.0, 0.0, 0.0, 0.25));//geode1->addDrawable(shpcone1);//设置圆锥透明效果osg::ref_ptr<osg::StateSet> stateset2 = geode1->getOrCreateStateSet();stateset2->setMode(GL_BLEND, osg::StateAttribute::ON);stateset2->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);stateset2->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); //取消深度测试//stateset2->setRenderBinDetails(11, "RenderBin2");//优先级,暂时没用/****************加入平台**********************/osg::MatrixTransform* mtCone = new osg::MatrixTransform();//mtCone->addChild(geode);mtCone->addChild(geode1);osg::ref_ptr<GeoTransform> pGTRadar = new GeoTransform();//应该是模型移动平台的意思    radarGroup->addChild(pGTRadar);m_pRoot->addChild(radarGroup);pGTRadar->addChild(mtCone);pGTRadar->setPosition(GeoPoint(m_pMapSRS, radarposition, ALTMODE_ABSOLUTE));/****************生成雷达动画**********************/osg::AnimationPath* animationPathRadar = rotateCone1(mtCone, m_pMapSRS, radarposition, PlanePR, radarDistance);mtCone->setUpdateCallback(new osg::AnimationPathCallback(animationPathRadar, 0.0, 1.0));//mtCone->addUpdateCallback(new RotateCallback(osg::Z_AXIS, 0.01));//直接用,时间可以统一,但是回看怎么操作?自己写?还不如直接用path}/*****************添加飞机动画****************/   {osg::Node* glider = osgDB::readNodeFile("models\\f35c.osgb");glider->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);//glider->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); //取消深度测试if (glider){const osg::BoundingSphere& bs = glider->getBound();float size = 2000;//osg::MatrixTransform* planeMT = new osg::MatrixTransform;planeMT->setDataVariance(osg::Object::STATIC);planeMT->addChild(glider);planeMT->setMatrix(planeMT->getMatrix()*osg::Matrix::scale(size, size, size));// *osg::Matrix::translate(-(bs.center()))* osg::Matrix::rotate(osg::DegreesToRadians(90.0 - earthCenter.y()), 0, 1, 0)*osg::Matrixd::translate(bs.center()));// /*osg::Matrix::rotate(osg::DegreesToRadians(90.0), 1, 0, 0) osg::Matrix::rotate(osg::DegreesToRadians(90.0), 0, 1, 0)*osg::Matrix::translate(bs.center()));///*osg::Matrix::rotate(osg::inDegrees(earthCenter.x()), 0.0f, 0.0f, 1.0f)*osg::Matrix::rotate(osg::inDegrees(90.0f - earthCenter.y()), 0.0f, 1.0f, 0.0f)* / );//osg::ref_ptr<GeoTransform> pGTPlane = new GeoTransform();//pGTPlane->addChild(planeMT);radarGroup->addChild(pGTPlane);osg::AnimationPath* animationPathPlane = createAnimationPath(PlanePP, planeMT);//动画的关键。依然使用了回调函数,执行完{},再执行它,后面两个参数是干啥用的?pGTPlane->setUpdateCallback(new osg::AnimationPathCallback(animationPathPlane, 0.0, 1.0));       }}//飞机添加动画 结束/***********窗口定位*****************/osgEarth::Viewpoint vp("", radarposition.x(), radarposition.y(), radarposition.z(), -2.50, 0, 1.5e6);//窗口定位到(dynamic_cast<osgEarth::Util::EarthManipulator*>(m_pViewer->getCameraManipulator()))->setViewpoint(vp);
}
osg::AnimationPath* GraphicsView::createAnimationPath(queue <PlanePoint> *PlaneP, osg::MatrixTransform *planeMT)//需要改成地球坐标系
{osg::AnimationPath* animationPath = new osg::AnimationPath;//自动路径animationPath->setLoopMode(osg::AnimationPath::LOOP);//设置动画模式为循环(LOOP)/**********获取第一个点************/osg::Vec3d  FEpoint = PlaneP->front().point;    while (!PlaneP->empty()){double time = PlaneP->front().time;osg::Vec3d FWpoint;m_pMapSRS->transformToWorld(FEpoint, FWpoint);osg::Vec3d BEpoint = PlaneP->front().point;osg::Vec3d BWpoint;m_pMapSRS->transformToWorld(BEpoint, BWpoint);osg::Vec3  _vector = BWpoint - FWpoint;osg::Matrixd rotMat = osg::Matrixd::rotate((osg::Y_AXIS), _vector);//计算对应地面点的指天向量,方法1GeoPoint localPoint(m_pMapSRS, BEpoint.x(), FEpoint.y(), FEpoint.z());osg::Vec3d v3HorizonUp;//指天向量localPoint.createWorldUpVector(v3HorizonUp);osg::Matrixd rotMatsky = osg::Matrixd::rotate((osg::Z_AXIS), osg::Vec3(v3HorizonUp.x(), v3HorizonUp.y(), v3HorizonUp.z()));//计算移动向量对应的旋转角osg::Quat rotation = rotMat.getRotate();double heading = 0; double pitch = 0; double roll = 0;QuatToHPR(rotation, heading, pitch, roll);//计算翻滚向量对应的旋转角,瞎猫碰上死耗子,换地方不行,尤其是在高纬度地区osg::Quat rotation2 = (osg::Matrix::rotate(osg::DegreesToRadians(90-BEpoint.x()), 1, 0, 0)).getRotate()*(osg::Matrix::rotate(osg::DegreesToRadians(90.0 - BEpoint.y()), 0, 1, 0)).getRotate()*rotMatsky.getRotate();//double heading2 = 0; double pitch2 = 0; double roll2 = 0;QuatToHPR(rotation2, heading2, pitch2, roll2);//取移动向量的偏航角和俯仰角,翻滚向量的翻滚角,合成新的旋转角,并计算对应的矩阵osg::Quat rotation3 = HPRToQuat(heading, pitch, roll2);//合成旋转角//将新的坐标和角度压入动画const osg::BoundingSphere& bs = planeMT->getBound();//因为起始点用了两次,所以这里插入动画时用了后点,相当于飞机方向用了该点后面飞行路径产生的向量,如果改前点,需要考虑左后一个点的处理,因为后面没有点了animationPath->insert(time, osg::AnimationPath::ControlPoint(BWpoint, (osg::Matrixd::translate(-bs.center())).getRotate()*rotation3*(osg::Matrixd::translate(bs.center())).getRotate()));PlaneP->pop();    /*for (int i = 0; i < numSamples; ++i)//步长循环{osg::Vec3d oldposition;m_pMapSRS->transformToWorld(OldEarthPosition, oldposition);//osg::Vec3 NewEarthPosition(earthPosition + osg::Vec3(yaw, yaw, 0.0f));osg::Vec3d newposition;m_pMapSRS->transformToWorld(NewEarthPosition, newposition);//osgearth坐标转osg坐标//计算飞机移动的向量double a_x = (newposition.x())- (oldposition.x());double a_y = (newposition.y())- (oldposition.y());double a_z =(newposition.z())- (oldposition.z());//计算将飞机移动到向量osg::Vec3(a_x, a_y, a_z)的旋转矩阵osg::Matrixd rotMat = osg::Matrixd::rotate((osg::Y_AXIS), osg::Vec3(a_x, a_y, a_z));//计算对应地面点的指天向量,方法1GeoPoint localPoint(m_pMapSRS, NewEarthPosition.x(), NewEarthPosition.y(), NewEarthPosition.z());osg::Vec3d v3HorizonUp;//指天向量localPoint.createWorldUpVector(v3HorizonUp);//计算对应地面点的指天向量,方法2//osg::EllipsoidModel* em = new osg::EllipsoidModel();//osg::Vec3d v3HorizonUp2=(em->computeLocalUpVector(newposition.x(), newposition.y(), newposition.z()));//计算将飞机移动到向量v3HorizonUp的旋转矩阵osg::Matrixd rotMatsky = osg::Matrixd::rotate((osg::Z_AXIS), osg::Vec3(v3HorizonUp.x(), v3HorizonUp.y(), v3HorizonUp.z()));//计算移动向量对应的旋转角osg::Quat rotation = rotMat.getRotate();double heading = 0; double pitch = 0; double roll = 0;QuatToHPR(rotation, heading, pitch, roll);//计算翻滚向量对应的旋转角osg::Quat rotation2 = rotMatsky.getRotate();//double heading2 = 0; double pitch2 = 0; double roll2 = 0;QuatToHPR(rotation2, heading2, pitch2, roll2);//取移动向量的偏航角和俯仰角,翻滚向量的翻滚角,合成新的旋转角,并计算对应的矩阵osg::Quat rotation3=HPRToQuat(heading, pitch, roll2);//合成旋转角//将新的坐标和角度压入动画const osg::BoundingSphere& bs = modelmt->getBound();animationPath->insert(time, osg::AnimationPath::ControlPoint(newposition, (osg::Matrixd::translate(-bs.center())).getRotate()*rotation3*(osg::Matrixd::translate(bs.center())).getRotate()));yaw += yaw_delta;time += time_delta;//过程记录/*1得到的不是欧拉角而是四元素,pitch,yaw,roll来自航空界的叫法,翻译为俯仰角,偏航角,翻滚角2但是对于有缩放和位移的矩阵,不能直接使用上述方法, osg中提供了分解的方法3欧拉角转四元素 只需要清楚知道旋转的顺序,和旋转轴即可,一般是通过下面这种方式来旋转,即先y轴,再x轴,再z轴4应该是沿着前进方向逆时针翻滚,就是顺时针旋转,5翻滚量跟纬度有关,?6翻滚方向与经度有关,经度递增翻滚逆时针,经度递减翻滚顺时针????7得到合成的旋转角度,在跨维度90,经度180的时候好像有点问题,暂时用不到,待后续处理8翻滚角依然有问题,暂时先放一放*//*********绘制轨迹**********/std::vector<osg::Vec3d> m_vecPoint;m_vecPoint.push_back(FEpoint);m_vecPoint.push_back(BEpoint);createLine(m_vecPoint, radarGroup);FEpoint = BEpoint;}return animationPath;
}
void GraphicsView::removeRadar()
{if (radarGroup){radarGroup->removeChildren(0, radarGroup->getNumChildren());}m_pRoot->removeChild(radarGroup);
}
void GraphicsView::rotateCone(osg::MatrixTransform* mt, const osgEarth::SpatialReference* sr, osg::Vec3d lonlat1, osg::Vec3d lonlat2)// osg与OSGearth坐标不一致,添加矩阵变换函数。lonlat1:雷达波圆锥顶点, lonlat2:目标点
{// 雷达波模型所在位置osgEarth::GeoPoint geoPoint1(sr,lonlat1.x(),lonlat1.y(),lonlat1.z(),osgEarth::ALTMODE_ABSOLUTE);osg::Matrixd matrix1;// 获取雷达波模型从原点变换到lonlat1位置的变换矩阵geoPoint1.createLocalToWorld(matrix1);// 经纬度高程到xyz的变换osg::Vec3d world1, world2;// geoPoint1.toWorld(world1);//等同于    sr->transformToWorld(lonlat1,world1);sr->transformToWorld(lonlat2, world2);// 计算轨迹点在雷达波模型坐标系下的位置osg::Vec3 point2InRadarCoordinateSystem = world2 * osg::Matrix::inverse(matrix1);// 在雷达波模型坐标系下,对Z轴进行旋转,与连接原点指向轨迹点方向的矢量重合,计算出此旋转矩阵osg::Matrixd rotMat = osg::Matrixd::rotate(osg::Z_AXIS, point2InRadarCoordinateSystem - osg::Vec3(0, 0, 0));// 将计算出的旋转矩阵赋给雷达波模型所在的mtmt->setMatrix(rotMat);
}
osg::AnimationPath* GraphicsView::rotateCone1(osg::MatrixTransform* mt, const osgEarth::SpatialReference* sr, osg::Vec3d lonlat1, queue <PlanePoint> *PlaneP/*飞机轨迹点*/, double radarDistance)// osg与OSGearth坐标不一致,添加矩阵变换函数。lonlat1:雷达波圆锥顶点, lonlat2:目标点
{osg::AnimationPath* animationPath = new osg::AnimationPath;//自动路径animationPath->setLoopMode(osg::AnimationPath::LOOP);//设置动画模式为循环(LOOP)// 雷达波模型所在位置osgEarth::GeoPoint geoPoint1(sr,lonlat1.x(),lonlat1.y(),lonlat1.z(),osgEarth::ALTMODE_ABSOLUTE);osg::Matrixd matrix1;// 获取雷达波模型从原点变换到lonlat1位置的变换矩阵geoPoint1.createLocalToWorld(matrix1);while (!PlaneP->empty())  {osg::Vec3d  Epoint = PlaneP->front().point;double time = PlaneP->front().time;osg::Vec3d  Wpoint;sr->transformToWorld(Epoint, Wpoint);// 计算轨迹点在雷达波模型坐标系下的位置     osg::Vec3 point2InRadarCoordinateSystem = Wpoint * osg::Matrix::inverse(matrix1);// 在雷达波模型坐标系下,对Z轴进行旋转,与连接原点指向轨迹点方向的矢量重合,计算出此旋转矩阵osg::Matrixd rotMat = osg::Matrixd::rotate(osg::Z_AXIS, point2InRadarCoordinateSystem - osg::Vec3(0, 0, 0));// 将计算出的旋转矩阵赋给雷达波模型所在的mt//double newDistance = osgEarth::GeoMath::distance(lonlat1, Epoint, sr);//新的半径osg::Vec3d wop;sr->transformToWorld(lonlat1, wop);double newDistance= sqrt((Wpoint.x() - wop.x())*(Wpoint.x() - wop.x()) + (Wpoint.y() - wop.y())*(Wpoint.y() - wop.y())+ (Wpoint.z() - wop.z())*(Wpoint.z() - wop.z()));double scale1 = newDistance / radarDistance;osg::Vec3d scale2 = osg::Vec3d(1, 1, scale1);animationPath->insert(time, osg::AnimationPath::ControlPoint(lonlat1/*位置不变,没啥用*/, rotMat.getRotate(), scale2));PlaneP->pop();//调整雷达波束长度,不起作用,cone只是图形数据,似乎需要再绘制成图形,在这里回调不行/*double radarDistance = osgEarth::GeoMath::distance(lonlat1, Epoint, sr);Cone->setHeight(radarDistance);Cone->setCenter(osg::Vec3(0, 0, 3 * radarDistance / 4));//平移,使得0点位于顶点*/}   return animationPath;
}
#ifndef RADARMAP_H
#define RADARMAP_H#include "framehandle.h"
#include "graphicsview.h"class RadarMap : public QObject
{Q_OBJECTpublic:RadarMap(GraphicsView* view, QObject *parent = nullptr);~RadarMap();void setGeomtry(int x = 20, int y = 20, int width = 320, int height = 180){m_iX = x; m_iY = y; m_iWidth = width; m_iHeight = height;}void enableMap();void disableMap();private slots:void slotFrameViewport(const osg::Vec3d& pos);private:void createMap();// 根据世界坐标去经纬度坐标osg::Vec3d getLonLat(const osg::Vec3d& worldPos);private:// 显示的区域int m_iX;int m_iY;int m_iWidth;int m_iHeight;// HUD相机osg::ref_ptr<osg::Camera> m_pHUDCamera;GraphicsView* m_pOSGViewer;osg::ref_ptr<osg::Group> m_pGroup;FrameHandle* m_pFrameHandle;// 十字架,显示当前视点位置osg::ref_ptr<osg::Geode> m_pGeodeCross;osg::ref_ptr<osg::Vec3dArray> m_pVertexCross;
};#endif // RADARMAP_H
#include "radarmap.h"RadarMap::RadarMap(GraphicsView* view, QObject* parent/* = nullptr*/): m_pOSGViewer(view), QObject(parent)
{m_pHUDCamera = nullptr;m_pGroup = new osg::Group;m_pOSGViewer->getRoot()->addChild(m_pGroup);//添加到大的视图中m_pFrameHandle = new FrameHandle;m_pGeodeCross = nullptr;setGeomtry();
}RadarMap::~RadarMap()
{}void RadarMap::enableMap()
{if (m_pHUDCamera == nullptr){createMap();}m_pGroup->addChild(m_pHUDCamera);m_pOSGViewer->getOSGViewer()->addEventHandler(m_pFrameHandle);connect(m_pFrameHandle, SIGNAL(signalFrameViewport(const osg::Vec3d&)),this, SLOT(slotFrameViewport(const osg::Vec3d&)));
}void RadarMap::disableMap()
{if (m_pHUDCamera){m_pGroup->removeChild(m_pHUDCamera);m_pHUDCamera = nullptr;disconnect(m_pFrameHandle, SIGNAL(signalFrameViewport(const osg::Vec3d&)),this, SLOT(slotFrameViewport(const osg::Vec3d&)));m_pOSGViewer->getOSGViewer()->removeEventHandler(m_pFrameHandle);}
}void RadarMap::slotFrameViewport(const osg::Vec3d& pos)
{if (m_pGeodeCross == nullptr){m_pGeodeCross = new osg::Geode;osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry;// 使用VBO,每帧实时的修改数据pGeometry->setUseVertexBufferObjects(true);m_pVertexCross = new osg::Vec3dArray;pGeometry->setVertexArray(m_pVertexCross);osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array;normal->push_back(osg::Vec3(0, 0, 1));pGeometry->setNormalArray(normal, osg::Array::BIND_OVERALL);osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;color->push_back(osg::Vec4(0.8, 0.8, 0.8, 1));pGeometry->setColorArray(color, osg::Array::BIND_OVERALL);pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 4));m_pGeodeCross->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);m_pGeodeCross->getOrCreateStateSet()->setAttribute(new osg::LineWidth(0.5), osg::StateAttribute::ON);m_pGeodeCross->addDrawable(pGeometry);m_pHUDCamera->addChild(m_pGeodeCross);}osg::Vec3d mapPos = getLonLat(pos);// 经纬度是-180~180,-90~90,保证算出的是0~360和0~180double x = (mapPos.x() + 180.0) * m_iWidth / 360.0;double y = (mapPos.y() + 90.0) * m_iHeight / 180.0;// 更新缓冲区数据m_pVertexCross->clear();m_pVertexCross->push_back(osg::Vec3d(x, y - 5, 0));m_pVertexCross->push_back(osg::Vec3d(x, y + 5, 0));m_pVertexCross->push_back(osg::Vec3d(x - 5, y, 0));m_pVertexCross->push_back(osg::Vec3d(x + 5, y, 0));m_pVertexCross->dirty();
}void RadarMap::createMap()
{m_pHUDCamera = new osg::Camera;// 设置投影矩阵m_pHUDCamera->setProjectionMatrixAsOrtho2D(m_iX, m_iWidth, m_iY, m_iHeight);// 设置视口矩阵m_pHUDCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);m_pHUDCamera->setViewMatrix(osg::Matrix::identity());// 只清除深度缓冲区m_pHUDCamera->setClearMask(GL_DEPTH_BUFFER_BIT);// 设置HUD相机在主相机之后渲染m_pHUDCamera->setRenderOrder(osg::Camera::POST_RENDER);// HUD相机不获取Event的焦点m_pHUDCamera->setAllowEventFocus(false);m_pHUDCamera->setViewport(m_iX, m_iY, m_iWidth, m_iHeight);// 增加HUD相机的渲染内容,即maposg::ref_ptr<osg::Geode> pGeode = new osg::Geode;// 创建纹理osg::ref_ptr<osg::Geometry> pGeometry = new osg::Geometry;{// 顶点osg::ref_ptr<osg::Vec3Array> verArray = new osg::Vec3Array;verArray->push_back(osg::Vec3(0, 0, -1));verArray->push_back(osg::Vec3(m_iWidth, 0, -1));verArray->push_back(osg::Vec3(m_iWidth, m_iHeight, -1));verArray->push_back(osg::Vec3(0, m_iHeight, -1));pGeometry->setVertexArray(verArray);// 纹理坐标osg::ref_ptr<osg::Vec2Array> textArray = new osg::Vec2Array;textArray->push_back(osg::Vec2(0, 0));textArray->push_back(osg::Vec2(1, 0));textArray->push_back(osg::Vec2(1, 1));textArray->push_back(osg::Vec2(0, 1));pGeometry->setTexCoordArray(0, textArray);// 法线,指向用户,即y轴osg::ref_ptr < osg::Vec3Array> normal = new osg::Vec3Array;normal->push_back(osg::Vec3(0, 1, 0));pGeometry->setNormalArray(normal);pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);// 指定绘制方式pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));// 纹理图片osg::ref_ptr<osg::Image> image = osgDB::readImageFile("./Images/image_formats/png/world.png");// E:\osg\data\Images\image_formats\pngif (image){osg::ref_ptr<osg::Texture2D> text2D = new osg::Texture2D;text2D->setImage(image);text2D->setDataVariance(osg::Object::DYNAMIC);pGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, text2D, osg::StateAttribute::ON);}}// 创建HUD相机的边框osg::ref_ptr<osg::Geometry> pGeoBorder = new osg::Geometry;{// 顶点osg::ref_ptr<osg::Vec3Array> verBorder = new osg::Vec3Array;verBorder->push_back(osg::Vec3(1.0, 1.0, 0));verBorder->push_back(osg::Vec3(m_iWidth - 1.0, 1.0, 0));verBorder->push_back(osg::Vec3(m_iWidth - 1.0, m_iHeight - 1.0, 0));verBorder->push_back(osg::Vec3(1.0, m_iHeight - 1.0, 0));pGeoBorder->setVertexArray(verBorder);// 法线osg::ref_ptr<osg::Vec3Array> normalBorder = new osg::Vec3Array;normalBorder->push_back(osg::Vec3(0.0, 0.0, 1.0));pGeoBorder->setNormalArray(normalBorder, osg::Array::BIND_OVERALL);// 颜色osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;color->push_back(osg::Vec4(1, 0.8, 0, 1));pGeoBorder->setColorArray(color);pGeoBorder->addPrimitiveSet(new osg::DrawArrays(osg::DrawArrays::LINE_LOOP, 0, 4));pGeoBorder->getOrCreateStateSet()->setAttribute(new osg::LineWidth(2), osg::StateAttribute::ON);}pGeode->addDrawable(pGeometry);pGeode->addDrawable(pGeoBorder);pGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);m_pHUDCamera->addChild(pGeode);
}osg::Vec3d RadarMap::getLonLat(const osg::Vec3d& worldPos)
{osg::Vec3d vecPos = osg::Vec3d();if (m_pOSGViewer){m_pOSGViewer->getSRS()->getEllipsoid()->convertXYZToLatLongHeight(worldPos.x(), worldPos.y(), worldPos.z(), vecPos.y(), vecPos.x(), vecPos.z());vecPos.x() = osg::RadiansToDegrees(vecPos.x());vecPos.y() = osg::RadiansToDegrees(vecPos.y());}return vecPos;
}

时间久了,代码整理的不是很全,请见谅。

代码下载地址:https://download.csdn.net/download/sailingw/16781009

OsgEarth下实现雷达波束扫描飞机动画相关推荐

  1. ios开发oc高仿京东金融白条额度余额的 ios开发水波纹 ios开发水正弦曲线波纹 ios开发雷达扫描的动画效果

    ios开发oc高仿京东金融白条额度余额的   ios开发水波纹   ios开发水正弦曲线波纹 直接上代码,复制粘贴就可以 vc里的 WaterRippleView *topView = [[Water ...

  2. ios开发oc高仿京东金融白条额度余额的 ios开发水波纹 ios开发水正弦曲线波纹 ios开发雷达扫描的动画效果...

    ios开发oc高仿京东金融白条额度余额的   ios开发水波纹   ios开发水正弦曲线波纹 直接上代码,复制粘贴就可以 vc里的 WaterRippleView *topView = [[Water ...

  3. 【雷达通信】基于matlab距离角度解耦法MIMO-OFDM雷达波束形成【含Matlab源码 2208期】

    ⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[雷达通信]基于matlab距离角度解耦法MIMO-OFDM雷达波束形成[含Matlab源码 2208期] 点击上面蓝色字体,直接付费下载 ...

  4. HFSS仿真宝典 | 阵列天线的波束扫描

    目录 前言 1. 阵列天线的波束扫描 2. HFSS阵列天线模型 3. 仿真求解设置技巧 4. 波束扫描方法一:变量扫参 5. 波束扫描方法二:自定义权值表 关注"电磁学社",让电 ...

  5. 人脸扫描Canvas动画

    最近研究web端人脸识别,H5拉起摄像头截取单帧图片,提交到后台进行人脸1:N搜索,发现web端没有人脸扫码的动画,因此,抽空写了个人脸扫描的动画. html代码如下: <!DOCTYPE ht ...

  6. 相控阵天线(一):直线阵列天线特性和阵列因子(方向图乘积定理、波束扫描、含python代码)

    目录 方向图乘积定理 阵列因子方向图 波束扫描 阵列方向图和单元方向图 方向图乘积定理的python代码示例 方向图乘积定理 任意形式单元天线构成的直线阵如下图所示: 阵中第n个单元的远区辐射场可表示 ...

  7. 相控阵天线(波束扫描)

    波束扫描动图 源代码 仿真结果 源代码 %%%%%%%%%%%%%%%%%%%%%

  8. 3D飞机动画网页js特效代码

    下载地址 3D飞机动画网页特效代码,鼠标控制视差改变方向. dd:

  9. OpenGL 画出雷达动态扫描效果(二) 非底图

    OpenGL 画出雷达动态扫描效果(一)中给出了已一张图片作为底图的雷达扫面程序 如果有漂亮的雷达底图的话,效果应该非常不错的,另外也可以直接手绘雷达框架 效果如下 雷达主体代码 glLineWidt ...

  10. 兄弟打印机扫描文件至计算机显示无法找到,windows10系统下Brother打印机无法扫描如何解决...

    打印机是办公人员经常会用到的设备,但是难免会遇到一些情况,比如最近有windows10系统用户反映说在使用Brother打印机的时候无法扫描,该怎么办呢,经过分析可能是扫描仪驱动程序的网络设置不正确, ...

最新文章

  1. Matlab与线性代数 -- 矩阵的加法与减法
  2. 【学习笔记】python - pyecharts
  3. 敏捷与DevOps整合之道
  4. 服务器虚拟化win游戏,Win虚拟化之Windows Virtual PC 功能概述
  5. Python 面向对象编程基础
  6. Recyclerview不显示内容
  7. linux服务器搭建教程c,Linux服务器上搭建web项目环境
  8. 选课系统类图与数据结构图
  9. 为什么我旗帜鲜明的反对前后端分离
  10. 接口自动化测试框架搭建(3、excel的设计excel文件的读取)--python+HTMLTestRunnerCN+request+unittest+mock+db
  11. 用计算机控制人造卫星和导弹发射,用计算机控制人造卫星和导弹的发射,按计算机应用的分类,它应属于什么...
  12. uni-app学习:CSS之flex布局居中
  13. 微信公众号 语音转文字api_有没有语音转文字的APP?
  14. 苹果笔记本,电源指示灯一直为橙色的解决办法
  15. 数据结构-栈(Stack)-定义与基本操作
  16. 内网Gitlab如何拉取代码
  17. 2020曼彻斯特大学计算机2020,2020年曼彻斯特大学申请要求完整版
  18. Docker入门实战---修改Docker镜像源
  19. USACO 奶牛食品(最大流)
  20. 《最优状态估计-卡尔曼,H∞及非线性滤波》:第10章 有关卡尔曼滤波的其他讨论

热门文章

  1. 多项式拟合(polyfit和polyval)
  2. Android JNI开发笔记二:动态库和静态库
  3. 8大数据库性能优化方案,YYDS!
  4. 前端数据可视化之使用 canvas、svg、zrender画图
  5. 每日新闻丨阿里巴巴香港IPO指引价每股176港元左右;全球超级计算机500强榜单出炉...
  6. Java 单点登录安全性如何保障?
  7. 十三、PS 基本操作
  8. Arduino 测量交流电流
  9. Android学习别“走弯路”,移动端混合开发框架
  10. Nutch爬虫爬取视频研究文档