[SOLVED] Particle emitter possible bug

Hi, everyone! Looks like i found a bug.
I’ve tried to create kind of smoke effect by standart ParticleEmitter and discovered some unexpected behaviour.

The use case is

smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 1 * COUNT_FACTOR);
smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F)));
smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
smoketrail.setStartSize(.2f);
smoketrail.setEndSize(1f);

smoketrail.setSelectRandomImage(false);
smoketrail.setParticlesPerSec(0);
smoketrail.setLowLife(10.0f);
smoketrail.setHighLife(10.0f);
smoketrail.setImagesX(3);
smoketrail.setImagesY(4);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("Texture", assetManager.loadTexture("Textures/explosions/smoke-skull.png"));
smoketrail.setMaterial(mat);
explosionEffect.attachChild(smoketrail);

Pretty standart. Texture is

As u can see we have 3x4 simple animated texture. But when i run this i see animation in weird order
0-1-2-0-1-2-3-4-5-6…
The primery quiestion is WHY? Is it a bug or it is just me missed something?
The secondary quiestion is why if i change

smoketrail.setImagesY(4);

on

smoketrail.setImagesY(2);

i have right animation order? Ofc texture is stitched by 2, but order is fine:
0:3-1:4-2:5-6:9-7:10-8:11

And finally third quiestion. If i do

smoketrail.setImagesX(1);
smoketrail.setImagesY(4);

i have no animation. As i can see in https://wiki.jmonkeyengine.org/jme3/advanced/particle_emitters.html and in jme code
to have static(no animated particle) i have to set imageX and imageY both to 1. But my imageY was 4. What did i wrong?

1 Like

Providing I am understanding this right it seems to be a bug.

Lines 253 and 254

int imgX = p.imageIndex % imagesX;
int imgY = (p.imageIndex - imgX) / imagesY;

I printed out imageIndex for a 3x4 emitter with 1 particle, and as it goes from 0-11 the imgY is not giving what I expect it needs.

The imgX is correct, but when p.imageIndex goes to 3, imgY is (3 - 0) / 4 = 0, I assume this is why it’s repeating the bottom row.

If you have an 8x2 image imgY ends up at 4, at tile(0,1) , imageIndex 8

Changing line 254 to:

imgY = p.imageIndex/imagesX);

Fixed it (he says). I printed out the UV coords it generates in the next few lines and I think its right.

3 Likes

Hey @JESTERRRRRR

Just a heads up in case you didn’t know, adding #L followed by the line number at the end of the url will link to the line in the file on GitHub.

Example:

3 Likes

Great! Please submit a pull request.

Thank u, @JESTERRRRRR! U helped a lot! Maybe i should go deeper into the jme code to find the cause by myselt, but i am bit lazy :slight_smile:.

No worries I had some free time. Figuring out github is my next task… already made a total mess of it.

1 Like

Free time? Nice! I am so lucky today :smile:.
Maybe u can give me one more advice? Why do i have no animated particle when imageX = 1 and imageY = 4?

Same problem I think, just slightly different result

int imgY = (p.imageIndex - imgX) / imagesY;

for width 1, height 4, the imageIndex value of the particle is always giving imgY = 0, and since imgX never changes it’s just stuck.

1 Like

U r right.
It happens because of

int imgX = p.imageIndex % 1;

always give us imgX = 0
and (p.imageIndex / imagexY) gives 0 cause p.imageIndex < imageY

Maybe this could be a fix

                int imgX = p.imageIndex % imagesX;
                int imgY = p.imageIndex / imagesX;
1 Like

What is this?

The effect texture can be one image, or contain a sprite animation – a series of slightly different pictures in equally spaced rows and columns.

Sorry to interject, maybe I am miss-reading this but it says equally spaced rows and columns.

3x4 is not equally spaced.

5x5
4x4
3x3
2x2
1x?

1 Like

Oh yeah it does, and that answers OPs question.

The effect texture can be one image, or contain a sprite animation – a series of slightly different pictures in equally spaced rows and columns. If you choose the sprite animation:

    Specify the number of rows and columns using setImagesX(2) and setImagesY().

    Specify whether you want to play the sprite series in order (animation), or at random (explosion, flame), by setting setSelectRandomImage() true or false.

I didn’t think this was the case without reading it because of being able to set X and Y - I assumed it would you let give different values.

That aside, I can’t see any reason why replacing

int imgY = (p.imageIndex - imgX) / imagesY;

With

imgY = p.imageIndex/imagesX);

Would break anything else, and then you can have any number of rows/columns you want.

COUNT_FACTOR = 1
Equally spaced IMHO means that each frame of aminated texture should have the same size, not square texture.
And here https://wiki.jmonkeyengine.org/jme3/advanced/particle_emitters.html we can see smoke not square texture.

Thx for reply, @JESTERRRRRR! Nice to meet u again! Let me just try to argue a bit.
I think size of texture should not affect on animation(if we have animated texture ofc), cause emitter have everything we need to configure. ImageY, ImageX, selectRandomImage, FaceNormal, etc.
Why should we rely on equality on rows and colums? If we have 3x4(my example) or 1x15(smoke.png example) equally spaced rows and columns textures, why we should edit them instead of just configure emitter?

During this, if we have texture like this

[3]
[2]
[1]

what prevent us from animate it in 1-2-3 order?
I think this

int imgY = (p.imageIndex - imgX) / imagesY;

cause it always gives 0 for any 1xX texture.

But this

imgY = p.imageIndex/imagesX

will give ok results.
Even if we take another texture like

[5][6][7][8]
[1][2][3][4]

Right?

About breaking anything else, ofc we must run tests, like we always do after changed something.
Locally i changed

int imgY = (p.imageIndex - imgX) / imagesY;

with

imgY = p.imageIndex/imagesX;

and run TestExplosionEffect and everything looks fine.

But, ofc, u r the contributor and u make final decision :slight_smile:
Best regards.

Note: I read it that he was agreeing with your changes… not disagreeing.

imgY = p.imageIndex/imagesX seems right to me, too.

Hi! What? :hushed:

Maybe i misuderstood smth. Sry for that. English is not my native language.

== changing won’t break anything else.

1 Like

Oh! Now i understood what is exactly means. Shame on me…:sweat_smile:
@pspeed thank u for ur lesson.
@JESTERRRRRR i apologize.

The fix is committed to the master branch. Someone please test it.
@Dmitry Thanks for raising this issue.

2 Likes