osgearth仿真平台之特效(4)

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

卫星轨道的添加:

osgearth仿真平台之特效(4)_第1张图片

 爆炸效果的添加:

 波束等效果的添加:

 扫描波束:

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 SimEffect::Explosion::createExp()
{
    osg::AutoTransform* at = new osg::AutoTransform;
    osg::Group* exRoot = new osg::Group;
    exRoot->setName("Explosion");
    osg::ref_ptrex = 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;
}

你可能感兴趣的:(仿真,OSG,osgearth,c++,软件开发)