umlaeute / Gem

Graphics Environment for Multimedia (official repository)
https://gem.iem.at
Other
103 stars 29 forks source link

Unexpected interaction between separate particle chains #388

Closed meschi closed 9 months ago

meschi commented 9 months ago

I'm trying to use several particle chains in the same visual patch. When I parametrize the newer particle chains, these new properties get applied to the existing particle chains. Adding [separator] objects in the beginning/end does not help. I've constructed three files based on the examples provided with gem to illustrate this. screenshot When I open the first file (vertical_down.pd) the particles go down in a vertical straight line. Opening up the second file (orbit.pd) renders the particles flying around an orbit correctly, too. Loading the third file (color.pd) changes the particle behavior of all three patches, such that none of those particle systems show the same behavior as when they are running alone. Also, turning the color on in the third patch colors all particles, not only the particles in the third chain.

I think the particle chains should apply these features locally, as to match the graph metaphor provided by the pure data programming environment.

I've attached a zip file with the three patches and a short text file, again with instructions to reproduce this.

chain_interaction.zip

umlaeute commented 9 months ago

indeed.

both [part_color] and [part_velocity] bleed into other domains.

for simplicity's sake, i've merged your test patches into one.

i had hoped that i would never need to touch the particle code again...

meschi commented 9 months ago

I've started debugging this issue. The particle information is basically stored in the _ParticleState &_ps = _GetPState(); struct. The code is correct as far as I can tell, the issue stems from this phenomenon: In the beginning of the particle chain the specific particle group gets set _ps.pgrp = _ps.GetGroupPtr(p_group_num);. Each particle group has their own struct. The velocity and color informations aren't set to the individual _ps.pgrp struct however, but are saved in _ps.Vel and _ps.Color structs. These values are global and only get reset when there are specific objects changing them in the chain. For chains without color/velocity objects the values that were previously set are applied. In fact, the [particle_source] needs to come after the [part_velocity] object in the chain, since it's accessing the _ps.Vel field set by [part_velocity] for velocity calculation. These fields aren't flushed to a default value by [part_head], however, so they're affecting other particle chains. I think resetting the public fields in [part_head] should fix the color problem and combined with a modified object order in the patch, the issue would be solved for the velocity, too.

Changing this will certainly change the behavior of some existing patches with multiple particle chains, however. I think the change is worth it anyways, since the old behavior is a very strange artifact from the implementation under the hoods.

I would be willing to create a pull request with a code change to reset those public fields in [part_head]. From there on only the correct order of the objects in the Pd graph has to be considered. We can take the discussion to the mailing list, if you want.

umlaeute commented 9 months ago

Yes indeed. In the meantime I've come to the same conclusion and have some (unpushed) commits that ensure that each [part_head] uses their own _ParticleState.

I've then started to wonder what should happen when chaining up multiple [part_head]s... (And whether it is worth to spend time wondering).

I'll probably let it rest until tomorrow and then push my changes...

meschi commented 9 months ago

I've created a pull request with my changes for reference.

meschi commented 9 months ago

Also, the help files might have to be restructured. As velocity and color are only applied by [part_source] this object has to be last when resetting the state in [part_head]. My solution will probably change the behavior of most patches. If each [part_head] has its own _ParticleState the changes would be applied as usual from the second render cycle on. I think your solution is probably better as it doesn't break old patches. Technically the [part_head] object should come after all velocity and color changes have been made, so the values are applied from the first cycle on, so this should be reflected in the help files.