Apel is a library that brings particle animations to the table with flexible behaviour and a clean developer interface. It promises also lots of predefined shapes & paths to help the developer on their particle scene
This is still a draft (though it does work correctly, as far as I know, see the end of the comment), but wanted to share the approach I'm thinking on the rendering and instructions.
I've refactored a bit in ApelClient, since it was doing everything on the client side, and that's not ideal.
I moved the instructions up to ApelRenderer because I think they make sense to use on both client and server rendering.
I refactored the Bezier Curve instruction because I had to choose which specific curve to construct in multiple places. (NB: this is why I wanted a single BezierCurve object instead of specialized subclasses.)
I realized that instructions know everything they need to generate the original points for a ParticleObject, so computePoints is added to Instruction and implemented.
Once computePoints exists, the renderers can cache them, which I've done on the client side.
My plan from here:
Do similar caching in the DefaultApelRenderer. This probably creates an abstract class BaseApelRenderer to hold the caches and common implementations. The default methods in the ApelRenderer likely go away in favor of those in BaseApelRenderer.
See what it looks like to have the ParticleObject subclasses generate the Instruction implementations. This is probably in ParticleObject (similar to how the renderer calls are now). This means that the renderer could wind up with only a draw(ParticleEffect pe, int step, Instruction instruction) method since the implementations would handle everything else!
This also means ParticleLine would finally get the ability to rotate.
Document all the new things clearly.
I can see this working, but it's possible the refactor train will continue further. What I don't want to do right now is have the ParticleObjects and ApelRenderers get more tied together. ParticleObjects should still be telling ApelRenderers what and where to draw, but the renderers handle the mechanism by which drawing actually becomes visible to the player.
Also note that my eventual plan for (I think) significant performance gains is to evolve the client rendering to maintain its own Particles instead of letting the ParticleManager do it all. This will mean the particle trails go away; they happen because we keep spewing new particles on every frame. This means ParticleObjects will need some sort of grouping of instructions and an internal label to collect those Particle instances.
Testing thus far is using the following snippet, which lets me compare server/client easily:
This is still a draft (though it does work correctly, as far as I know, see the end of the comment), but wanted to share the approach I'm thinking on the rendering and instructions.
ApelClient
, since it was doing everything on the client side, and that's not ideal.ApelRenderer
because I think they make sense to use on both client and server rendering.computePoints
is added toInstruction
and implemented.computePoints
exists, the renderers can cache them, which I've done on the client side.My plan from here:
DefaultApelRenderer
. This probably creates anabstract class BaseApelRenderer
to hold the caches and common implementations. The default methods in theApelRenderer
likely go away in favor of those inBaseApelRenderer
.ParticleObject
subclasses generate theInstruction
implementations. This is probably inParticleObject
(similar to how the renderer calls are now). This means that the renderer could wind up with only adraw(ParticleEffect pe, int step, Instruction instruction)
method since the implementations would handle everything else!ParticleLine
would finally get the ability to rotate.I can see this working, but it's possible the refactor train will continue further. What I don't want to do right now is have the
ParticleObject
s andApelRenderer
s get more tied together.ParticleObject
s should still be tellingApelRenderer
s what and where to draw, but the renderers handle the mechanism by which drawing actually becomes visible to the player.Also note that my eventual plan for (I think) significant performance gains is to evolve the client rendering to maintain its own
Particle
s instead of letting theParticleManager
do it all. This will mean the particle trails go away; they happen because we keep spewing new particles on every frame. This means ParticleObjects will need some sort of grouping of instructions and an internal label to collect thoseParticle
instances.Testing thus far is using the following snippet, which lets me compare server/client easily: