ParticleEmitter - point emitter - Why does it only emit one?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

ParticleEmitter - point emitter - Why does it only emit one?

Post by dracflamloc »

Heres the code for emitting it. It is called when a monster is hit by a bullet. I want to create a sort of spray of blood effect. I think this will work, but my problem is that it only emits on little blood particle when they get hit. I want it to emit a bunch so it has the desired effect.

[edit]On a second glance it appears to emit several. However they are always in a stream in the same direction. How can i get them to emit in varied directions?[/edit]

code here:

Code: Select all

IParticleSystemSceneNode* ps = device->getSceneManager()->addParticleSystemSceneNode(false,entityArray[eid].node,0,vector3df(0,10,0));
                                IParticleEmitter* em=ps->createPointEmitter(vector3df(0.05,0.05,0.05),100,1000,SColor(0,120,0,0),SColor(0,255,0,0),1000,2000,60);
                                ps->setEmitter(em);
                                em->drop();
                                ps->setParticleSize(dimension2d<f32>(0.5,0.5));
                                IParticleAffector* p=ps->createGravityAffector(vector3df(0,-0.5,0));
                                ps->addAffector(p);
                                p->drop();
                                ps->setMaterialFlag(video::EMF_LIGHTING, false);
                                ps->setMaterialTexture(0, driver->getTexture("./textures/blood.jpg"));
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

Post by dracflamloc »

By doing this i pretty got the desired effect:

Code: Select all

//Show bloodspray
                                IParticleSystemSceneNode* ps;
                                IParticleEmitter* em;
                                IParticleAffector* p;

                                for (int z=0; z < particleCount; z++)
                                {
                                    ps = device->getSceneManager()->addParticleSystemSceneNode(false,entityArray[eid].node,0,vector3df(0,10,0));
                                    em=ps->createPointEmitter(vector3df(0.03f,0.03f,0.03f),1000,2000,SColor(0,120,0,0),SColor(0,255,0,0),1000,1500,60);
                                    ps->setEmitter(em);
                                    em->drop();
                                    ps->setParticleSize(dimension2d<f32>(0.1f,0.1f));
                                    p=ps->createGravityAffector(vector3df(0,particleGravity,0));
                                    ps->addAffector(p);
                                    p->drop();
                                    p=ps->createFadeOutParticleAffector(SColor(0,0,0,0),1500);
                                    ps->addAffector(p);
                                    p->drop();
                                    ps->setMaterialFlag(video::EMF_LIGHTING, false);
                                    ps->setMaterialTexture(0, driver->getTexture("./textures/blood.jpg"));
                                    ps->setParticlesAreGlobal(false);
                                }
Problem is, is this efficient? I never drop ps() because I don't know when it's done and theres no callback, is that a problem?

Also it goes on emitting forever, and depending on my angle to the zombie, its not even visible!

How can i limit how long it lasts?
Guest

Post by Guest »

normally the particles are emitted all the time so you dont have to put it in a loop, so yes its very inefficient.
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

Post by dracflamloc »

Thats called when a bullet hits. I have to create a few point emitters so get a "splash effect" instead of just a straight stream of blood.

Your post wasn't too helpful to my questions sadly, but thanks anyway.

If you know how to set a overall particle system lifetime limit that'd be much appreciated
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

Post by dracflamloc »

Whats weird also, is if the particals are not set to "global" then they will continue to emit forever.

But if the particles are global they emit for the time i want them too (i think), except after a while particles start showing up all over the place when a zombie is hit.
Guest

Post by Guest »

this is what i use:

Code: Select all

ParticleEmitter = ParticleSystem->createPointEmitter(Direction, 		minParticlesPerSec, maxParticlesPerSec, startColor, endColor,		minParticleTime, maxParticleTime, maxAngleDegrees);

ParticleSystem->setEmitter(ParticleEmitter);
ParticleEmitter->drop();
Direction is a vector3df which is used to point the direction where the particles emit to. set it to 0,0.1,0 or something like that (that will let the particles go up for example, its X,Z,Y)

minParticlesPerSec is a s32 and is used for the minimal particles per second
maxParticlesPerSec is .. well the same like above but just for the maximum
startColor and endColor are SColor type and i think self-explaining
minParticleTime is f32 and the minimal lifetime of a particle
maxParticleTime is f32 and the maximal lifetime of a particle

---IMPORTANT TO YOU---
maxAngleDegrees is f32 and sets the randomness of the particles, this is important to you. if you do not set this, the particles will just go out in a straight line.


the particles will dissappear after the maxParticleTime without any fading, to have fading you have to attach a fadeout affector

i hope this helped you :D

ps: i think to remove a particle system you have to call "YourParticleSystem->remove();"
dracflamloc
Posts: 142
Joined: Sat Dec 11, 2004 8:13 am
Contact:

Post by dracflamloc »

Okay. Forget the previous problems.

Heres the gist of it. I need a way to have the particlesystemSceneNode emit particles for a total of say, 2 seconds, then drop itself.

Can this be done and how?
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

try a box emitter, you can choose a box shaped area for the particles to spawn in and lets you set min and max angles. it's better than adding and destroying 30 or so particle systems. if thats not the effect you're looking for, you might want to make your own emitter that acts like a load of point emitters (easy - just copy the point emitter code, or even better have a look at Spintz's emitters)
oh and to delete it, add a deletion animator to the particle system and it will remove its self after however long you say
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
daniel.retief
Posts: 5
Joined: Thu Sep 07, 2006 9:22 am

Post by daniel.retief »

The problem with the box emitters are that they project the particles in a squarish shape. Im trying to make somthing that looks like a water fountain, but the fountains are always square in shape, which is a really pain in the ass. Any way to solve this problem? or setup a point emitter that will go constantly like the box emitter?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

It really sounds like you want to use a point emitter. Take a look at the documentation for createPointEmitter(). The last parameter is the one that you care about.

If you want it to be destroyed after 2 seconds, then use a delete animator.

Code: Select all

IParticleSystemSceneNode* psn = smgr->addParticleSystemSceneNode(false, target, -1, pos);
psn->setMaterialTexture(0, driver->getTexture("media/blood.jpg"));
psn->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);

IParticleEmitter* ppe = psn->createPointEmitter(-vectorToTarget, minPPS, maxPPS, bloodColor, bloodColor, minLife, maxLife, splatter);
  psn->setEmitter(ppe);
ppe->drop();

ISceneNodeAnimator* sna = smgr->createDeleteAnimator(2000);
  psn->addAnimator(sna);
sna->drop();
xiangshushu
Posts: 2
Joined: Thu Sep 14, 2006 11:54 am

if you need the point emiiter work correctly

Post by xiangshushu »

add the code below into
s32 CParticlePointEmitter::emitt(u32 now, u32 timeSinceLastCall, SParticle*& outArray)

Code: Select all

if (Time > everyWhatMillisecond)
	{
		Time = 0;
		Particle.startTime = now;
		Particle.vector = Direction;

                                // add here
                                Particle.pos.x= 0;
                                Particle.pos.y= 0;
                                Particle.pos.z= 0;
                                // OK,try it again
    ...
                }

 I think it is a bug.right?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, that is not necessary. The attribute Particle is all the time reused, but pos is never changed throughout the existence of the emitter. Thus, pos is always initialized with the default (0,0,0)-vector.
xiangshushu
Posts: 2
Joined: Thu Sep 14, 2006 11:54 am

Post by xiangshushu »

I doubt wheather you have ever tested it by yourself?
The value will be changed and just initialled once.If ParticlesAreGlobal is ture(in most condition)

Code: Select all

AbsoluteTransformation.transformVect(array[i].pos);
When the code is invoked, the pos is changed.It will be chaged again when an now particle produced.It is wrong,right?
So the point emitter can not produces particles persistently.In fact,They produced,but the position is not right, you just can not see them.
The value will be biger and biger and never be initialled more than twice.
It is a bug,right?
Post Reply