Menu

#2568 Locally attached particle get stuck

2020.4
New
nobody
None
Low
2021-03-22
2021-03-22
No

Particles with <attach>local</attach> cause the particle system to get 'stuck', seemingly at random. By stuck, I mean that the existing particles stop moving relative to the aircraft model (and are not destroyed), and no new particles are created. This generally comes together with a FPS drop which persists as long as the particles are stuck.
This is a relatively recent issue, which I assume is related to particle changes in February.

Here's the example I have used for testing: (on the JA37, hopefully the aircraft does not matter...)

<particlesystem>
  <name>wingtip-condensation-trail</name>
  <texture>puff.png</texture>
  <emissive type="bool">false</emissive>
  <lighting type="bool">false</lighting>

  <attach>local</attach>

  <counter>
    <particles-per-sec>
      <value>60</value>
    </particles-per-sec>
  </counter>

  <align>billboard</align>

  <particle>
    <life-sec>
      <value>0.001</value>
    </life-sec>
  </particle>

  <program>
    <fluid>               air  </fluid>
    <gravity type="bool"> false </gravity>
    <wind typ="bool">     false </wind>
  </program>
</particlesystem>

When replacing local with global, the problem does not exist.

I can reproduce the problem with SG 059285ed and FG d57bc674, but not with their predecessors, so I assume this is what introduced the issue.

Various observation which might be relevant:

  • It seems I can not reproduce the problem while on the ground. It does however occur very reliably and quickly when in the air.
  • The particles also sometimes get unstuck, also seemingly randomly.
  • Increasing the rate at which particles are created makes the problem worse. (in particular it takes far longer for particles to get unstuck).
  • Setting the particle condition to false, or even disabling particles altogether in rendering settings does not unstuck the particles.
  • As long as a globally attached particle system is active, the local particle systems work without issue.

Discussion

  • James Turner

    James Turner - 2021-03-22

    Thanks for the detailed report. This suggests we are missing the update call on local particle systems for some reason. The fact it works when at leats one global particle system exists, suggests it's something about how local ones are registered with the new updater code.

    I don't get why air-vs-ground makes a difference to it, that's strange.

     
  • James Turner

    James Turner - 2021-03-22

    Also slightly bad luck to discover this just after realsing 2020.3.7 which includes the same change, oh well.

     
  • Colin Geniet

    Colin Geniet - 2021-03-22

    Forgot to mention: there is no relevant log message when the issue occurs.
    At debug log level, I noticed that when particles are registered, the message

        7.18 [DBUG]:particles  Setting up particle system user data and callback.
    

    is present for global particles but not local ones. No idea if this is relevant at all.

     

    Last edit: Colin Geniet 2021-03-22
  • James Turner

    James Turner - 2021-03-22

    That message is based on if the particles have a callback or not : this depends on how the particles are updated, it's (mostly) orthognal to if they are local or global attachment.

    Howevber, it might be signficiant that global particles always have a callback, whereas in local ones, it's optional.

    For reference my test case for local particles was the F-16: which has them for tire and engine- smoke, and variosu atmospheric effects. For me they seemed to work ok, I didn't trigger the issues you're describing here but I also don't know the ways particles are used very well.

     
    • Colin Geniet

      Colin Geniet - 2021-03-22

      I can test the F-16, but a quick grep shows only <attach>world</attach> particles in it (or are they inherited from generic models?).

       
  • James Turner

    James Turner - 2021-03-22

    Colin, are you running with any particular OSG threading model?

    If you have a way to trigger the bug (I know you said it's seemingly at random), it would be helpful to check, wehn it's 'frozen', how many active particle systems are found ('activeSystems' in updateParticleSystemsFromCullCallback) and how many are actually updated (i.e which ps->update() calls are actually made)

    My guess is one or the other of these is somehow excluding local systems when no global particle systems exist, although of course I don't get why: none of this code should care if the systme is local vs global.

     
    • Colin Geniet

      Colin Geniet - 2021-03-22

      are you running with any particular OSG threading model?

      Just tested, I can also reproduce it with SingleThreaded. The previous tests were with CullDrawThreadPerContext.

       
  • James Turner

    James Turner - 2021-03-22

    Okay, great, that eliminates ma bunch of things from consideration.

     
  • James Turner

    James Turner - 2021-03-22

    Okay, I think I can reproduce this with the Viggen : it's the effect on the top of the wing surface when doing a steep turn?

     
    • Colin Geniet

      Colin Geniet - 2021-03-22

      This, and also the one at the canard tips. Corresponding files are JA37/Models/Effects/{vapour.xml,wingtip-vapour.xml}.

       
  • James Turner

    James Turner - 2021-03-22

    I thnik I've got it: I suspect cull callbacks are not invoked for nodes with zero children. Hmmm. Need to find a way to run during the callback, regardless of whether or not there are children of the particle root. (Global systems are children)

     
  • James Turner

    James Turner - 2021-03-22

    Does this fix it for you?

    diff --git a/simgear/scene/model/particles.cxx b/simgear/scene/model/particles.cxx
    index 9af72b13..7189e2bf 100644
    --- a/simgear/scene/model/particles.cxx
    +++ b/simgear/scene/model/particles.cxx
    @@ -186,6 +186,7 @@ void ParticlesGlobalManager::initFromMainThread()
    std::lock_guard<std::mutex> g(d->_lock);
    d->internalGetCommonRoot();
    d->_commonRoot->addUpdateCallback(d.get());
    + d->_commonRoot->setCullingActive(false);
    d->_commonRoot->addCullCallback(d->_cullCallback);
    }</std::mutex>

     
  • Colin Geniet

    Colin Geniet - 2021-03-22

    Looks like it does. With the change the issue did not occur over 5 minutes of testing.

     

Log in to post a comment.