代码
osg::ref_ptr<osg::Group> createParticle(osg::ref_ptr<osg::Group> root) { //osg::ref_ptr<osg::Group> root = new osg::Group() ; //创建粒子系统模板 osgParticle::Particle ptemplate; //设置生命周期 ptemplate.setLifeTime(2); //设置粒子大小变化范围 ptemplate.setSizeRange(osgParticle::rangef(0.01f, 1.0f)); //设置例子Alpha变化范围 ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.0f)); //设置粒子颜色变化范围 ptemplate.setColorRange(osgParticle::rangev4(osg::Vec4(189/255.0,183/255.0,107/255.0,1), osg::Vec4(189/255.0,183/255.0,107/255.0,0.5))); //设置半径 ptemplate.setRadius(0.05f); //设置重量 ptemplate.setMass(0.05f); //创建粒子系统 osg::ref_ptr<osgParticle::ParticleSystem> ps = new osgParticle::ParticleSystem(); //设置材质,是否放射例子,是否添加光照 ps->setDefaultAttributes("Images/smoke.rgb", false, false); //加入模板 ps->setDefaultParticleTemplate(ptemplate); //创建粒子放射器(包括计数器,放置器,发射器) osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter(); //关联粒子系统 emitter->setParticleSystem(ps.get()); //创建发射器计数器,调整每一帧增加的粒子的数目 osg::ref_ptr<osgParticle::RandomRateCounter> counter = new osgParticle::RandomRateCounter(); //设置每秒添加的粒子的个数 counter->setRateRange(5.0f, 5.0f); //关联计数器 emitter->setCounter(counter.get()); //设置一个点放置器 osg::ref_ptr<osgParticle::MultiSegmentPlacer> placer = new osgParticle::MultiSegmentPlacer(); //设置位置 //placer->setCenter(osg::Vec3(0.0f,-3.0f,0.0f)); placer->addVertex(-1.5,-1.5,0); placer->addVertex(1.5,-1.5,0); //关联点放置器 emitter->setPlacer(placer.get()); //创建弧度发射器 osg::ref_ptr<osgParticle::RadialShooter> shooter = new osgParticle::RadialShooter(); //设置发射器速度变化范围
// 这里是一个 from to的关系 shooter->setInitialSpeedRange(0, 3);
// 与x轴的夹角,是一个球锥体啊 shooter->setThetaRange(-M_PI/2,-M_PI/2);
//与xy面夹角 仔细的想一下,画画图,模型就出来了 shooter->setPhiRange(M_PI/2,M_PI/2); //关联发射器 emitter->setShooter(shooter.get()); //加入到场景中f root->addChild(emitter.get()); //创建标准编程器对象,控制粒子在生命周期中的更新 osg::ref_ptr<osgParticle::ModularProgram> program = new osgParticle::ModularProgram(); //关联粒子系统 program->setParticleSystem(ps.get()); //创建重力模拟对象 osg::ref_ptr<osgParticle::AccelOperator> ap = new osgParticle::AccelOperator(); //设置重力加速度,默认为9.80665f ap->setToGravity(0.0); //关联重力 program->addOperator(ap.get()); //创建空气阻力模拟 osg::ref_ptr<osgParticle::FluidFrictionOperator> ffo = new osgParticle::FluidFrictionOperator(); //设置空气属性 //FluidViscosity为1.8e-5f FluidDensity为1.2929f ffo->setFluidToAir(); //关联空气阻力 program->addOperator(ffo.get()); //添加到场景 root->addChild(program.get()); //添加更新器,实现每帧粒子的管理 osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu = new osgParticle::ParticleSystemUpdater(); //关联粒子系统 psu->addParticleSystem(ps.get()); //加入场景 osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(ps.get()); root->addChild(geode.get()); root->addChild(psu.get()); return root.get() ; }
一副广为流传的图:不过好像有些小问题,粒子模板应该是加入到粒子系统属性中的,而不是加入到emitter中的。而且粒子系统是要加入到Geode节点中,(因为它属于一种billboard效果)再加入到根节点中的。
结合 <osg程序设计教程> 第八章看。