用irrlicht实现烟火粒子效果

 用irrlicht实现烟火粒子效果

算是加深对08.SpecialFX_vc8的学习吧。

首先看irrlicht粒子系统的构成吧:

粒子系统由粒子系统场景节点、粒子发射器、粒子影响器组成。

粒子场景节点负责运行发射器来产生新的粒子,运行影响器更新粒子状态,更新粒子位置、存活时间等属性,绘制粒子等。

粒子发射器负责根据当前时间判断是否发射新粒子,设置粒子属性。

粒子影响器负责更新除粒子场景节点处理的属性之外的其他状态和属性。

 

我要实现的烟火比较简单,就是从一点每隔一定时间喷发一定数目的粒子,每个粒子方向随机,所有粒子综合起来看就成了一个圆球。

 

 s32 CParticleFireWorkEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray) { //每隔MaxLifeTime就发射一次 if (now - Time < MaxLifeTime) return 0; SParticle p; u32 numberOfParticles = MaxParticlesPerSecond; if (Particles.size() == numberOfParticles) { for (u32 i=0; i<numberOfParticles; ++i) initParticle(now, Particles[i]); } //如果第一次发射则一次性创建所有粒子 else { for (u32 i=0; i<numberOfParticles; ++i) { initParticle(now, p); Particles.push_back(p); } } //更新时间 Time = now; outArray = Particles.pointer(); return Particles.size(); }

粒子是可重用的,生命周期结束后并不销毁,而是又被重新初始化。

void CParticleFireWorkEmitter::initParticle(u32 now, SParticle &p) { //设置起止时间 p.startTime = now; if (MaxLifeTime - MinLifeTime == 0) p.endTime = now + MinLifeTime; else p.endTime = now + MinLifeTime + (os::Randomizer::rand() % (MaxLifeTime - MinLifeTime)); //设置起止颜色 p.color = MinStartColor.getInterpolated( MaxStartColor, (os::Randomizer::rand() % 100) / 100.0f); p.startColor = p.color; //设置起始速度和方向(相对) p.vector = Direction; if (MaxAngleDegrees) { core::vector3df tgt = Direction; tgt.rotateXYBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees); tgt.rotateYZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees); tgt.rotateXZBy((os::Randomizer::rand()%(MaxAngleDegrees*2)) - MaxAngleDegrees); p.vector = tgt; p.startVector = p.vector; } //设置起止大小 if (MinStartSize==MaxStartSize) p.startSize = MinStartSize; else p.startSize = MinStartSize.getInterpolated( MaxStartSize, (os::Randomizer::rand() % 100) / 100.0f); p.size = p.startSize; }

 

调用和08例子一样:

scene::IParticleSystemSceneNode* ps = smgr->addParticleSystemSceneNode(false); scene::IParticleEmitter *em = ps->createFireWorkEmitter( 1024, core::vector3df(0,0,0), core::vector3df(0,0.03,0), video::SColor(0,0,0,0), video::SColor(0,255,255,0), 2000, 2000, 180, core::dimension2df(1.f,1.f), core::dimension2df(1.f,1.f)); ps->setEmitter(em); // this grabs the emitter em->drop(); // so we can drop it here without deleting it scene::IParticleAffector* paf = ps->createFadeOutParticleAffector(); ps->addAffector(paf); // same goes for the affector paf->drop(); ps->setPosition(core::vector3df(-70,100,40)); ps->setScale(core::vector3df(2,2,2)); ps->setMaterialFlag(video::EMF_LIGHTING, false); ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); ps->setMaterialTexture(0, driver->getTexture("../../../media/fire.bmp")); ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); ps->setDebugDataVisible(true);

 

 

 

你可能感兴趣的:(vector,video,OS)