osgearth相控阵雷达

张开发
2026/5/5 3:44:14 15 分钟阅读

分享文章

osgearth相控阵雷达
一、前言实现思路先绘制半个圆再添加四个裁剪面这么拼凑一下就感觉有那么点意思呢。二、效果三、关键代码void EffectPhasedArrayRadar::RebuildEntityBody() { if (m_pGeode.valid()) { mat-removeChild(m_pGeode.get()); m_pGeode nullptr; } if (m_pGridCopy.valid()) { mat-removeChild(m_pGridCopy.get()); m_pGridCopy nullptr; } if (m_pPatch1.valid()) { mat-removeChild(m_pPatch1.get()); m_pPatch1 nullptr; } if (m_pPatch2.valid()) { mat-removeChild(m_pPatch2.get()); m_pPatch2 nullptr; } if (m_pPatch3.valid()) { mat-removeChild(m_pPatch3.get()); m_pPatch3 nullptr; } if (m_pPatch4.valid()) { mat-removeChild(m_pPatch4.get()); m_pPatch4 nullptr; } if (m_pClippedSubgraph.valid()) { mat-removeChild(m_pClippedSubgraph.get()); m_pClippedSubgraph nullptr; } if (m_pFanMT.valid()) { mat-removeChild(m_pFanMT.get()); m_pFanMT nullptr; } m_pGeode new Geode(); //设置三维曲面采样步长 constexpr double dStep 11.25; //垂直方向循环 for (double vAngle 0; vAngle 60; vAngle dStep) { //三维曲面的半透明蒙皮通过QUAD_STRIP图元合成 m_polySkin new Geometry(); //计算蒙皮所需要的采样点数量 constexpr int numCoordsSkin (360 / dStep 1) * 2;//146 //申请蒙皮采样点 Vec3 myCoordsSkin[numCoordsSkin];// new Vec3[numCoordsSkin]; osg::ref_ptrVec4Array colorsSkin new Vec4Array; osg::ref_ptrVec3Array normals new Vec3Array; normals-push_back(Vec3(0.0f, -1.0f, 0.0f)); int index 0; //水平方向循环 for (double hAngle 0; hAngle 360; hAngle dStep) { double vAngleR DegreesToRadians(vAngle); double hAngleR DegreesToRadians(hAngle); double vAngleNextStepR DegreesToRadians(vAngle dStep); //计算蒙皮的采样点坐标同时计算对应的显示颜色 //圈上的点 myCoordsSkin[index] Vec3( m_dRadius *sin(vAngleR)*cos(hAngleR), m_dRadius *sin(vAngleR)* sin(hAngleR), m_dRadius * cos(vAngleR)); //圈上方点 myCoordsSkin[index 1] Vec3( m_dRadius *sin(vAngleNextStepR) * cos(hAngleR), m_dRadius *sin(vAngleNextStepR) * sin(hAngleR), m_dRadius * cos(vAngleNextStepR)); colorsSkin-push_back(Vec4(0.0,1.0,1.0, m_dColorAlpha)); colorsSkin-push_back(Vec4(0.0, 1.0, 1.0, m_dColorAlpha)); index 2; } m_verticesSkin new Vec3Array(numCoordsSkin, myCoordsSkin); m_polySkin-setVertexArray(m_verticesSkin); //设置曲面的颜色为逐点设置 m_polySkin-setColorArray(colorsSkin.get(), Array::BIND_PER_VERTEX); //m_polySkin-setNormalArray(normals, Array::BIND_OVERALL); //设置曲面的图元类型为QUAD_STRIP m_polySkin-addPrimitiveSet(new DrawArrays(PrimitiveSet::QUAD_STRIP, 0, numCoordsSkin));//QUAD_STRIP为四边形三角面数相同 //设置曲面半透明效果的一条关键语句少了该句会导致半透明显示错误暂未搞清楚该句的原理 m_polySkin-getOrCreateStateSet()-setAttribute(new Depth(Depth::LESS, 0.0, 1.0, false)); //开启曲面的半透明效果 m_polySkin-getOrCreateStateSet()-setMode(GL_BLEND, StateAttribute::ON); m_polySkin-getOrCreateStateSet()-setRenderingHint(StateSet::TRANSPARENT_BIN); m_polySkin-getOrCreateStateSet()-setMode(GL_LIGHTING, StateAttribute::OFF); //背面剔除 m_polySkin-getOrCreateStateSet()-setMode(GL_CULL_FACE, StateAttribute::OFF); //smooth geoset by creating per vertex normals. osgUtil::SmoothingVisitor::smooth(*m_polySkin.get()); m_pGeode-addDrawable(m_polySkin); } //绘制网格线 m_pGridCopy dynamic_castGeode *(m_pGeode-clone(CopyOp::DEEP_COPY_ALL)); ref_ptrStateSet spStateSet m_pGridCopy-getOrCreateStateSet(); ref_ptrPolygonMode polyMode new PolygonMode(PolygonMode::FRONT_AND_BACK, PolygonMode::LINE); spStateSet-setAttribute(polyMode); // 设置线框颜色 osg::ref_ptrosg::Material material new osg::Material(); material-setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 1, 1, 1)); material-setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 1, 1, 1)); spStateSet-setAttributeAndModes(material, osg::StateAttribute::ON); // 启用多边形偏移解决Z-fighting ref_ptrPolygonOffset polyOffset new PolygonOffset; polyOffset-setFactor(-1.0f); polyOffset-setUnits(-1.0f); spStateSet-setAttributeAndModes(polyOffset, StateAttribute::ON); // 关闭透明混合 spStateSet-setMode(GL_BLEND, StateAttribute::OFF); spStateSet-setRenderingHint(StateSet::OPAQUE_BIN); // 确保深度测试正确 spStateSet-setMode(GL_DEPTH_TEST, StateAttribute::ON); spStateSet-setMode(GL_LIGHTING, StateAttribute::OFF); ref_ptrLineWidth lineWidth new LineWidth(1.0f); spStateSet-setAttribute(lineWidth); // 创建裁剪节点和裁剪平面 osg::ref_ptrosg::ClipPlane clipPlane1 new osg::ClipPlane(0, osg::Vec4d(0, 0.707, 0.707, 0.0)); osg::ref_ptrosg::ClipPlane clipPlane2 new osg::ClipPlane(1, osg::Vec4d(0, -0.707, 0.707, 0.0)); osg::ref_ptrosg::ClipPlane clipPlane3 new osg::ClipPlane(2, osg::Vec4d(0.707, 0, 0.707, 0.0)); osg::ref_ptrosg::ClipPlane clipPlane4 new osg::ClipPlane(3, osg::Vec4d(-0.707, 0, 0.707, 0.0)); m_pClippedSubgraph new osg::Group; osg::ref_ptrosg::StateSet stateset m_pClippedSubgraph-getOrCreateStateSet(); //添加裁剪面 stateset-setAttributeAndModes(clipPlane1, osg::StateAttribute::ON); stateset-setAttributeAndModes(clipPlane2, osg::StateAttribute::ON); stateset-setAttributeAndModes(clipPlane3, osg::StateAttribute::ON); stateset-setAttributeAndModes(clipPlane4, osg::StateAttribute::ON); //stateset-setMode(GL_CLIP_PLANE0, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); //stateset-setMode(GL_CLIP_PLANE1, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); //stateset-setMode(GL_CLIP_PLANE2, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); //stateset-setMode(GL_CLIP_PLANE3, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); // 被裁剪的部分原半球 m_pClippedSubgraph-addChild(m_pGeode.get()); m_pClippedSubgraph-addChild(m_pGridCopy.get()); /* 创建补全的四个面,y朝下x朝右 如果将四个补面和扇子添加到m_pClippedSubgraph里面就更完美但不知道为什么添加进去就会闪烁 有时间了再演技。 */ //x轴方向的补面 m_pPatch1 CreatePatch(-45.0, osg::Vec3d(0, 1, 0), 45.0, -45.0); mat-addChild(m_pPatch1.get()); //-y轴方向的补面 m_pPatch2 CreatePatch(45.0, osg::Vec3d(1, 0, 0), 135.0, 45.0); mat-addChild(m_pPatch2.get()); //-x轴方向补面 m_pPatch3 CreatePatch(45.0, osg::Vec3d(0, 1, 0), 225.0, 135.0); mat-addChild(m_pPatch3.get()); //y轴方向补面 m_pPatch4 CreatePatch(-45.0, osg::Vec3d(1, 0, 0), 315.0, 225.0); mat-addChild(m_pPatch4.get()); //中间的扇子 m_pFanMT new osg::MatrixTransform(); m_pFanMT-addChild(CreateSector(135, 45, 0.5).get()); mat-addChild(m_pFanMT.get()); mat-addChild(m_pClippedSubgraph.get()); }原创不易记得点赞加关注哦我会持续分享实用的功能:-

更多文章