Jump to content

how to release resource of one time particle system


davychen
 Share

Recommended Posts

hi all,
 
i'm a developer from shanghai,

 

i use babylonjs' particle system to show a water spout, each time a bomb hits the water.

 

each time i will new a BABYLON.ParticleSystem,

then start it.

 

and i set 

 

particleSystem.disposeOnStop = true;

 

after several times, the frame rate slows down, start to block.

 

i log scene.particleSystems.length

out,

 

the number keep rising.

the particle system seems not disposing itsself.

 

is there a solution to avoid the issue?

 

i use it the wrong way?

 

if can't solve it,

i may have to write a particle system and manage it myself.

 

 

any suggestions?

 

thank you.

Link to comment
Share on other sites

Hi guys, sorry to interrupt.

I started a test playground for this... nothing is active.  I might work on it more, later, when I have more time.

http://playground.babylonjs.com/#OLPDM

Davychen, welcome to the BJS forum... good to have you with us!

I notice that you are pushing each particle system into an array called particleList.

Do you know that there is an array on the BabylonJS Scene object that already contains all scene particleSystems?

http://doc.babylonjs.com/classes/2.2/Scene#particlesystems-particlesystem-classes-2-2-particlesystem-

Davychen, if you would like to do some tests...

1.  For now, DO NOT push the particleSystems into your particleList array.

2.  Now, do tests on scene.particleSystems and see if THOSE array items are being disposed.

I do not know if particleList is causing the problem... but maybe so. 

Do your "Did it dispose properly?" -testing using scene.particleSystems instead.  At least this is something to TRY, for now.

Please report findings/success... and also feel free (anyone) to advance/activate the testing playground above.  Thanks!  We'll talk more soon.

By the way, cool game!

Link to comment
Share on other sites

hi Wingnut,

thank you for the kind help. ;)

1) yes, i know there is a list:

scene.particleSystems

i already use it to output logs for the issue.

2) the array "particleList" i added myself,

its for a test to dispose particles myself.

i deleted all the code about it,

the particle systems still do not dispose themselves.

 

and then, i'll try to use the playground you setup.

thank you.

happy new year, guys. :D

Link to comment
Share on other sites

Hi again!

http://playground.babylonjs.com/#OLPDM#1

I am doing some testing on a single particle system.  I have not learned much, yet.

In https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js ... I noticed that . _alive has not been initialized.  I'm not sure if that is a factor or not, yet.  I was hoping to monitor PS.isAlive() in the render loop, and when it changed to false, I was going to call PS.stop().  But, that did not work so well.  It could be my mistake, though.

And... disposeOnStop()... hmm.  I wonder if that means the programmer needs to call particleSystem.stop() before that will activate.  hmm.  Still testing and learning.  Maybe others will help. 

All in all, I think we have a good testing playground, now. 

Generally speaking, when one of our heroes (such as Deltakosh) requests a playground "repro" (or repo)... this is what he likes to see.  He (and others) like to have the issue shown as simple as is possible.  We all do.  It is easy to collaborate when a simple playground is provided, right?  *nod* 

I think we are traveling on a good trail to success.  Talk soon.  Happy New Year to you, too, davychen!

Link to comment
Share on other sites

hi Deltakosh,

 

thank you for clearing it.

 

 

 

hi Wingnut,

 

thank you for the explanation of playground repro,

 

i'm new to this forum, so not very clear about it.

 

 

i'll try to play with your playground, add some code to it maybe if needed.

 

 

i tried following code in my game:

 

 

            for (var i = 0; i < scene.particleSystems.length; i++)
            {
                if(scene.particleSystems.isAlive() == false)
                {
                    scene.particleSystems.dispose();
                }
            }

 

 

this can dispose particles,

 

but particles' lifetime on screen is shortened,

 

the particles can't be seen clearly as before,

 

 

seems

 

scene.particleSystems_alive is set false,

before particles finished their lifttime.

 

so, this is as far as i can do it now.

Link to comment
Share on other sites

Hello Davychen.

Yes, please do adjust that playground demo, and click RUN and SAVE as often as you wish.

It is confusing to me, as well.

Let's examine https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js

Line 150 seems to check particles.length, but with a .manualEmitCount, the particles array goes empty, but the particles have not reached their lifetime ending yet.  So, particles.length is a bad check for ._alive  (assuming ._alive is for testing when all particles have died).  I'm confused.

Lines 229 - 247 is also an area of _stopped, _started, _alive, and confusion, too.

I really cannot determine what the particle system programmer's plan is/was, yet.  The documentation only addresses .targetStopDuration but there is no .stopOnParticlesFinished or .stopOnNotAlive or .stopOnFinalParticleDead.  hmm.

scene.particleSystems.isAlive() should NOT == false before all particles have ended their lifetime... I would think.  hmm.  But maybe isAlive() is ONLY testing the particle SYSTEM, and not the particles.

It seems, with manualEmitCount, we maybe need to watch the age of the last particle that was launched, and not dispose until that particle has died.  *scratch scratch*

 We need to do more testing, I guess.  Or maybe others will help clarify.  Or maybe, both.  I will do more testing soon.  Thanks for the information about your game tests.

 Update #1:  I am having some problems with .manualEmitCount on another demo.  hmm.  http://playground.babylonjs.com/#15UMON I was once a pretty good particleSystem pilot.  Now I can't even find the cockpit.  :D

Link to comment
Share on other sites

http://playground.babylonjs.com/#7DAOO#1

Yet another.  Here, I have hijacked the PS source code into the playground.

In line 474, I have a manualEmitCount of 1500.

But in the console (via line 230), I am seeing a newParticles of far less-than 1500 particles.  I think there is something wrong with line 228.

Located at https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js#L223 in the real source.

@davychen, this is somewhat off-topic for your issue... maybe.  But it is yet another playground to do some tests upon, insert some console.logs and see the particleSystem operate.  That is what I will use it for, as well.  So, edit, run, save, grab zips, have fun.  Tell us whatever you discover, please.

I learned that emitRate is ignored when manualEmitCount is set.  I didn't know that until now, even though it says it in the docs.  :)  When manualEmitCount is set, it is just one giant "sneeze" of particles, and then isAlive() goes false immediately.  So, isAlive() seems to be a bad way to test if all particles have died.

But we WILL find a way to test for "hasLastParticleDied?"... even if WE die doing it.  :D

Link to comment
Share on other sites

hi Wingnut,
 
i was on other issues latest a few days.
 
i have a web site to take care,
so i was away from our topic this weekend...
 
 
back to our topic,
thank you anyway for taking so much time checking this issue.
 
i agree with you, that the code of particle system is not very long, not very complicated,
 
but i'm also confused.

 

https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js#L250

 

from source code, line #250,

 

VBOs are updated here,

as long as in particles' lifetime, this place should be called,

 

this.particles.length should be greater than 0 to update VBOs,

 

i think this.particles.length might be 0 sometimes during particles lifetime.

 

but i don't know why.

 

i'll take more time testing it.

 

regards

davy

Link to comment
Share on other sites

Hi DC, I was away, too... watching local snowmobile racing.  Pretty fun!

Quote
 

@davychen - scene.particleSystems_alive is set false, before particles finish their lifetime.

 Yeppers... you are exactly correct.

 

Hmm. 

 

As mentioned in the last post, I encountered another problem with .manualEmitRate producing only about 10 % of the requested particles.  So, for now, if you are seeing a shortage of particles, just increase the .manualEmitCount to higher levels.  I need to ask the professionals for help with that, or maybe you might understand WHY https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js#L223 ...  emitcout * this._scaledUpdateSpeed  is causing some problems... reducing the particle count well-below .manualEmitRate values.  

 In other words, you can help us find that problem, if you wish.  But that is not the issue that YOU have, with disposal after all particles have died.

 See line 151?   https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js#L151

 That line was added... to allow framework pilots to easily create their own custom update functions.

 http://playground.babylonjs.com/#15UMON#1  (see line 40)  That's a custom update function I created a long time ago.  Very few modifications from the normal default particleSystem.updateFunction.  I only did a couple lines ... 53 and 54, and I also added two "utility functions".   Sparkly particles!   Essentially, I removed the coloring and sizing lines from the normal default updater, and did my own coloring and sizing.  Fun!

 Keep in mind that custom update functions need to run very fast.  But, inside your custom update function, you have SOME time to ... umm... do SOMETHING.  I'm not sure what.  *scratch scratch*

 I still have no solution to the issue... but maybe... now that you have seen a custom updateFunction... maybe that will give you more ideas.  Maybe other readers will have ideas.  isAlive(), ._stopped, _started, _alive... they all seem useless for testing .haveAllParticlesDied.  But maybe there is a problem with .isAlive() and or ._alive.

 Monitoring VBO activity... watching for it to stop.  Maybe that is a good idea, DC.  I will study and test when I get a chance.  Interesting idea!

 Ok, forum users... we need more ideas/comments that might help.  We would love to have a .stopOnParticlesDone flag... but we don't want to slow PS speeds, if possible.  C'mon, who has a great idea?  Help!  :D

Link to comment
Share on other sites

Ok, here's another...

http://playground.babylonjs.com/#15UMON#2

In this one, everything is done in the render loop (Line 75 area), and quite badly.  :D  (I'm not a very good coder)

Watch the console.  PS1.particles.length IS counting down to zero!  Yay! 

I am seeing some inconsistency, but... this works for me.  scene.particleSystems.length stays at 1 until the particles have died, and then goes to zero (disposes).  But... hmm.  I am not sure if ALL the particles are launching before .stop() gets runned. 

http://playground.babylonjs.com/#15UMON#3 - Here I have changed my IF statement... to never run (so dispose never happens because stop() is never called).   According to the console, this version produces MANY more particles.  So the #2 demo above... is likely stopping the particle system too early.

There has to be a better way.  More tests ahead.

Link to comment
Share on other sites

Thanks for asking, DK! 

I/We need a fast and easy way to...   stopOnAllParticlesDead

My most recent playground uses the renderLoop to try (pseudo)....  .stop-on-particles.length == 0...

But, the renderLoop runs faster than this.particles.length gets filled.  So, stop() gets called before the ParticleSystem has time to produce all the particles.

There is another problem with manualEmitCount not producing enough particles, but that's for later.

For now, how best to get .stopOnAllParticlesDead flag/check? 

If we had that, then .disposeOnStop would wait for all manualEmitCount particles to finish.  Essentially, we are looking for dispose-On-Full-Finish-Of-ManualEmitCount-Explosion  :D  Thx.

Link to comment
Share on other sites

Right, in theory.  But that doesn't work inside the renderLoop.  http://playground.babylonjs.com/#15UMON#4

(line 76 goes true instantly)

The fountain turns red instantly.  It does not wait for particles to die.  It also stops the PS before ANY particles have been created.

This is because the FIRST time the render loop runs, particles.length == 0 (I think)  (thx for ideas/thoughts)

Davychen has probably solved this already, but Wingy hasn't.

 

First, see the game.  Now, let's pretend Davychen uses "shot class" objects... because his game can have many shots active all at the same time.  Each shot would need to have three particle systems.  #1 - shot trailing smoke.  #2 - shot hits water (miss), and #3 - shot hits target ship.  A shot-class object and its 3 particle systems cannot be recycled until its #2 or #3 particle explosion finishes completely.

Deltakosh - where would you put PS#2.particles.length == 0 and PS#3.particles.length == 0 testing?  Could it be put in a custom PS#2/PS#3.updateFunction?

Then... upon impact with water or target, Davychen does shot.PS2.start() or shot.PS3.start()  -  for a water explosion or target-hit explosion.

Right after the PS2 or PS3 start(), let's pretend Davychen starts checking for PS2/3.particles.length==0 inside a custom updateFunction.  From what I have seen in my tests, PS.particles.length WILL == 0 right away... instantly (the first time updateFunction runs) before producing ANY particles.  The test for particles.length == 0 seems to happen BEFORE the particleSystem has enough time to create any particles.  So, particles.length is still == 0 at the first run of the updateFunction.  The test sees particles.length == 0 and stops the PS.

My particles.length == 0 tests, though, are done inside the renderLoop.  Maybe that's the wrong place to test.  Maybe when the particles.length==0 testing is done in the custom PS.updateFunction, maybe it will work better.  *shrug*

With me?  Sorry for all the words, but I have not been able to clearly communicate the issue, yet.

Link to comment
Share on other sites

*Nod*  that works.  Thanks!  Kind of a crappy solution, but thanks.  :)

Want to try to solve the OTHER issue?  (thx)

http://playground.babylonjs.com/#206JUO

manualEmitCount = 150,000.   Max particle count 200,000

Watch console.  Actual particles generated are < 3000.

Problem there?

I think... in this line... https://github.com/BabylonJS/Babylon.js/blob/master/src/Particles/babylon.particleSystem.js#L223 ... this._scaledUpdateSpeed is a fraction.  So I think that multiply... kills the amount of particles... MUCH.  :)  I think MAYBE...  we shouldn't multiply by this._scaledUpdateSpeed  when using manualEmitCount.  Maybe.

For the curious, >> 0 ...  binary right-shifts the number zero places, which causes rounding, and ensures the number maintains its sign and is now a 32-bit INT.  (Huh?  What the hell did Wingnut just say?)  Always remember... Wingy maintains a continuous 84% chance of being wrong.  :)

I can start a new thread for THIS subject, if wanted.  *shrug*

Link to comment
Share on other sites

Hey Davy/forum-folk... did you notice that statement Deltakosh made? 

 

"ManualEmitCount can be reset at any time"

 

THAT is a weird thought, eh?  But think about a volcano that erupts particles... based on a 2 minute timer.  The particle system(s) at the top of the volcano... never need to be stopped or disposed.  Just set their .manualEmitCount to some value... and poof, they explode.  Two minutes later, set the .manualEmitCount again, and poof again. 

 

No need to re-start() them.  No need to dispose or re-create... for that type of application.

 

INTERESTING!  The .manualEmitCount becomes the particleSystem GO AGAIN button!  Sometimes a little explosion (small value).  Sometimes a massive explosion (large value).  Maybe even change particle colors and sizes before each poof!   (maybe - untested.  Might need to swap-out a section of a custom UpdateFunction.) 

 

Cool!  (at least it is cool to me)  :)  I might need to see it in a demo, just for fun.

Link to comment
Share on other sites

http://playground.babylonjs.com/#206JUO#1

Initial... 100 particles via manualEmitCount.  Using Deltakosh's interval time... (placed in ps1.timer for portability)... in Line 87 - wait for the count to be 90 (meaning 10 particles have died).  Then lines 89-91 change some colors on the PS... and then line 92 dumps another load of "Purina ParticleSystem Chow" into the hopper, and POOF! 

A confetti machine!  Load more paper stock into .manualEmitCount, and FOOF - confetti sneeze!  :D

Too fun!  It seems that ANY particleSystem parameters can be set between "poofs"... including colors, sizes, emitbox sizes, directions, emitter themselves (rot/pos/scale), but gravity might get weird.  ;)

What's that?  You want another?   Ok.  http://playground.babylonjs.com/#206JUO#3  Here's a no-particle-counting 1/3-second poofer.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...