OSG粒子系统应用:喷泉效果

时间:2021-05-23 20:14:00

粒子系统主要分为两大类:
- 一是Effective中已有的效果,如雨雪的效果应用;
- 二类是一步步从模版,发射器等创建。

关于第一种的使用可以参见上一篇博客OSG粒子系统应用:雨雪效果。本篇博客来使用第二种方式创建一个喷泉的效果。
废话补多说,直接上代码:

osg::ref_ptr<osg::Node> Fountain::createFountain(osg::Group* parent)
{
    // 设置粒子模板的参数,包括生命周期、颜色、透明度、半径、重量等
    osgParticle::Particle pParticle;
    pParticle.setLifeTime(3);
    pParticle.setColorRange(osgParticle::rangev4(
        osg::Vec4(0.7, 1.0, 1.0, 1.0),
        osg::Vec4(0.8, 1.0, 1.0, 0.0)));
    pParticle.setSizeRange(osgParticle::rangef(0.1f, 0.1f));
    pParticle.setAlphaRange(osgParticle::rangef(1.0f, 0.5f));
    pParticle.setRadius(m_dParticlesSize);
    pParticle.setMass(0.05);

    osg::ref_ptr<osgParticle::ParticleSystem> pParticleSys =
        new osgParticle::ParticleSystem;
    pParticleSys->setDefaultAttributes("Image/smoke.rgb", false, false);
    pParticleSys->setDefaultParticleTemplate(pParticle);

    // 发射器
    osg::ref_ptr<osgParticle::ModularEmitter> pEmitter = new osgParticle::ModularEmitter;
    pEmitter->setParticleSystem(pParticleSys);

    osg::ref_ptr<osgParticle::RandomRateCounter> pRandomCounter = new osgParticle::RandomRateCounter;
    pRandomCounter->setRateRange(osgParticle::rangef(m_dParticlesNum, m_dParticlesNum));
    pEmitter->setCounter(pRandomCounter);

    // 粒子发射枪
    osg::ref_ptr<osgParticle::RadialShooter> pShooter = new osgParticle::RadialShooter;
    pShooter->setInitialSpeedRange(m_dParticlesSpeed, 0);
    pEmitter->setShooter(pShooter);

    // 速度细节控制
    osg::ref_ptr<osgParticle::ModularProgram> pProgram = new osgParticle::ModularProgram;
    pProgram->setParticleSystem(pParticleSys);
    osg::ref_ptr<osgParticle::AccelOperator> pAccelOperator = new osgParticle::AccelOperator;
    pAccelOperator->setToGravity();
    pProgram->addOperator(pAccelOperator);
    osg::ref_ptr<osgParticle::FluidFrictionOperator> pOperator = new osgParticle::FluidFrictionOperator;
    pOperator->setFluidToAir();
    pProgram->addOperator(pOperator);

    osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
    pGeode->addDrawable(pParticleSys);
    parent->addChild(pEmitter);
    parent->addChild(pProgram);
    parent->addChild(pGeode);

    osg::ref_ptr<osgParticle::ParticleSystemUpdater> pParticleSysUpdate =
        new osgParticle::ParticleSystemUpdater;
    pParticleSysUpdate->addParticleSystem(pParticleSys);
    return pParticleSysUpdate;
}

创建粒子的时候传入一个osg::Group*参数,创建成功后,返回一个osg::Node*值,这个Node还可以成为传入参数的子节点。

PS:此篇博客代码以及前几篇的均已放在github,欢迎获取,欢迎交流!