osgearth仿真平台之特效(4)

osgearth特效主要是开发了圆锥波、菱形波、干扰、通信、爆炸等特效,因为特效开发起来比较麻烦,有时候在osg上效果很好,放到osgearth上效果就不行了,特效如下:

卫星轨道的添加:

 

 

 

爆炸效果的添加:

 

 

 

波束等效果的添加:

 

 

 

扫描波束:

void CScan::Init()
{
this->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
this->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
osg::Depth* dp = new osg::Depth();
dp->setWriteMask(false);
this->getOrCreateStateSet()->setAttribute(dp, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);

m_gnode = new osg::Geode;
addChild(m_gnode);

m_rpDrawCallback = new DrawableDrawCallback(m_pos);

m_geom = new osg::Geometry;
m_gnode->addDrawable(m_geom);
m_geom->setDrawCallback(m_rpDrawCallback);
m_geom->setUseDisplayList(false);
m_geom->setUseVertexBufferObjects(true);

//顶点序列
osg::Vec3dArray* vertex = new osg::Vec3dArray;
m_geom->setVertexArray(vertex);

//颜色序列
osg::Vec4dArray* colorArray = new osg::Vec4dArray;
m_geom->setColorArray(colorArray);
m_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

//勾边,循环线
osg::DrawElementsUInt* edge = new osg::DrawElementsUInt(GL_LINE_LOOP);
//m_geom->addPrimitiveSet(edge);
/// 不能使用索引构造边框线, 因为在绘制更新时清空了节点,导致其他地方遍历DrawElementsUInt时出错。(2017.4.12 g00034)

//顶点设置,首先求出除卫星点,地球中心点之外的第三个点
osg::Vec3d thirdPos = osg::Matrix(osg::Matrix::translate(m_pos) * osg::Matrix::rotate(osg::inDegrees(50.0), osg::Vec3d(1.0, 0.0, 0.0))).getTrans() - m_pos;

//勾边,三个点
{
vertex->push_back(m_pos);
edge->push_back(0);
colorArray->push_back(m_color);
vertex->push_back(osg::Vec3d(0.0, 0.0, 0.0));
edge->push_back(1);
colorArray->push_back(m_color);
vertex->push_back(thirdPos);
edge->push_back(2);
colorArray->push_back(m_color);

m_geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_LOOP, 0, vertex->size()));
}

//开始中间分段,着色
{
osg::Vec3d center = osg::Vec3d(0.0, 0.0, 0.0);
osg::Vec3d right = thirdPos;
float deltaRadio = 0.01;

//四个形状
osg::Vec3d m0, m1, m2, m3;

//起初m0和m2为起点
m0 = m_pos;
m2 = m_pos;

float deltaAlpha = 0.01;
float m02Alaph = 0.01;
float m13Alpha = m02Alaph + deltaAlpha;

for(float radio = deltaRadio; radio<1.0; radio+=deltaRadio)
{
//求出左中心
m1 = m_pos + (center - m_pos) * radio;
m3 = m_pos + (right - m_pos) * radio;

m_geom->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, vertex->size(), 4));

vertex->push_back(m0);
colorArray->push_back(osg::Vec4d(m_color.r(), m_color.g(), m_color.b(), m02Alaph));

vertex->push_back(m1);
colorArray->push_back(osg::Vec4d(m_color.r(), m_color.g(), m_color.b(), m13Alpha));

vertex->push_back(m2);
colorArray->push_back(osg::Vec4d(m_color.r(), m_color.g(), m_color.b(), m02Alaph));

vertex->push_back(m3);
colorArray->push_back(osg::Vec4d(m_color.r(), m_color.g(), m_color.b(), m13Alpha));

m0 = m1;
//float temp = m02Alaph;
m02Alaph = m13Alpha;
m2 = m3;
m13Alpha += deltaAlpha;

if(m13Alpha>0.3)
{
deltaAlpha = -0.04;
}

if(m13Alpha<0.01)
{
deltaAlpha = 0.01;
}

if(m13Alpha <0.0) m13Alpha = 0.0;
}

}

}
爆炸:

osg::ref_ptr<osg::Node> SimEffect::Explosion::createExp()
{
osg::AutoTransform* at = new osg::AutoTransform;
osg::Group* exRoot = new osg::Group;
exRoot->setName("Explosion");
osg::ref_ptr<osg::Node>ex = createEffect(200.0);
exRoot->addChild(ex);
//ex->setNodeMask(1);

at->addChild(exRoot);
at->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
at->setAutoScaleToScreen(true);
at->setMinimumScale(100.0);
at->setMaximumScale(10000);
at->setAutoScaleTransitionWidthRatio(0.0);
return at;
}
————————————————
版权声明:本文为CSDN博主「吉生太」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41157291/article/details/127157145

posted @ 2022-11-20 18:59  远方是什么样子  阅读(429)  评论(0编辑  收藏  举报