Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for non-relative 2D particles #441

Merged
merged 6 commits into from
Oct 16, 2018

Conversation

Yanrishatum
Copy link
Contributor

Feature requested in this topic.
Adds support to make particles non-relative.
Implementation details:
I apply position difference between initial global position of particle and new global position of particles objects. Calculations are done once per particle init and once per frame per group (multiple particle groups would invoke Object.localToGlobal multiple times and initialization of object would call it nparts time per group).
There also an issue with some particles "twitching" while in this mode, most likely due to conversion local->global->local->global and I'm not sure if I'll be able to solve this issue.

@ncannasse
Copy link
Member

That seems more complex than it should be.

What about instead setting the particle position as relative to parent when emit, then upon draw overwrite the Particles matrix before write and restore it after write?

@Yanrishatum
Copy link
Contributor Author

It would require reworking how SpriteBatch rendering works. Right now particle code have no way of affecting it's matrix directly, as it's done asynchronously. (It first updates the BatchElement and only then does flush which in turn applies the matrix) Hence the complicated implementation - SpriteBatch internally does not support non-relative elements.

@ncannasse
Copy link
Member

@Yanrishatum if you look at Particles class, it uses drawWith(batch,this) which means it's the Particles matrix that gets used, and it could be swapped at this time before calling drawWith, the restored back afterwards

@Yanrishatum
Copy link
Contributor Author

@ncannasse Ah, I see. Then the implementation is indeed extremely straightforward. Thanks!

@ncannasse
Copy link
Member

@Yanrishatum about about scale/rotation ? :)

@Yanrishatum
Copy link
Contributor Author

Hm. I thought about it a bit and now I see other issue. Do we reset matrix to identity (hence ignore Particles scale/rotation) or apply only local Particles matrix transformation as global disregarding parent? Maybe it worth moving the isRelative to Particles instead of ParticleGroup?

@ncannasse
Copy link
Member

I think we should reset to identity, it can be kept per group. Also, we might want to apply the full matrix to the particle direction at emit time when !isRelative

@Yanrishatum
Copy link
Contributor Author

Done and done.

h2d/Particles.hx Outdated
// called during sync() call which calls this function if required before any of this happens.
//parts.syncPos();

p.x += p.x * parts.matA + p.y * parts.matC + parts.absX;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be += but simply =

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, didn't noticed it after inlining matrix calculation instead of calling localToGlobal.

h2d/Particles.hx Outdated
p.y = p.x * parts.matB + p.y * parts.matD + parts.absY;
p.scaleX = Math.sqrt((parts.matA * parts.matA) + (parts.matC * parts.matC)) * size;
p.scaleY = Math.sqrt((parts.matB * parts.matB) + (parts.matD * parts.matD)) * size;
p.rotation += Math.acos(parts.matA / p.scaleX);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still a bit unsure about that Math.acos here. I think an Math.atan2(matB / scaleY, matA / scaleX) would be better but I haven't tested it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right (it does back-and-forth movement which I couldn't notice at first), also noticed another bug with px/py calcualation. Due to p.x being assigned first, it's new value affects p.y, while it supposed to use old one. Plus I overlooked the need to rotate movement velocity as well.

@ncannasse
Copy link
Member

Thanks!

@ncannasse ncannasse merged commit a2c4202 into HeapsIO:master Oct 16, 2018
@Yanrishatum Yanrishatum deleted the feature_rel2dparts branch October 16, 2018 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants