diwi/PixelFlow

a good way to customize colors

jenil opened this issue · 6 comments

jenil commented

hey!

First, amazing stuff here! I was experimenting with the project and got stuck at customizing the colors of a ParticleSystem. What is a good way to do that?
I did see the PALLETTE variable here

diwi commented

Hi,

There are several possible ways to achieve this. Basically you want to extend DwParticle2D or DwParticle3D and override fields or methods, and/or add new functionallity.

For example, have a look at the example SoftBody2D_ParticleCollisionSystem.
At the beginning of the ParticleSystem, you will find the extended DwParticle2D which is probably doing what you are searching for:

  static class CustomVerletParticle2D extends DwParticle2D{
    public CustomVerletParticle2D(int idx) {
      super(idx);
    }
    
    @Override
    public void updateShapeColor(){
      setColor(0xFF020100);
//      super.updateShapeColor();
    }    
  }

CustomVerletParticle2D is then used for creating new instances etc...

You can also override the PALETTE variable which you already found and leave updateShapeColor unchanged.

overriding updateShapeColor gives you a bit more control, e.g. you can shade the particles depending on certain properties, e.g. size, velocity, position etc....

jenil commented

Thanks for the reply @diwi

The PALETTE is static final can you show me how to override it?

diwi commented

you are right.
I'd just go with overriding "updateShapeColor()" as in the example above.

jenil commented

I wanted to customize the colors of this OpticalFlow_CaptureVerletParticles example.

diwi commented

yes, and you can just (as shown in the example above) extend DwParticle2D and override the stuff you need, for example updateShapeColor().

theese two examples are very similar and basically use the same ParticleSystem structure.

jenil commented

Cool got it! Thanks @diwi .

Here is how the custom class looks like:

static class CustomVerletParticle2D extends DwParticle2D {
  public CustomVerletParticle2D(int idx) {
    super(idx);
  }

  protected final float[][] PALLETTE =
    {
    {  50, 80, 130},
    { 100, 178, 255},
    { 255, 120, 50},
  };

  protected void getShade(float val, float[] rgb) {
    if (val < 0.0) val = 0.0f;
    else if (val >= 1.0) val = 0.99999f;
    float lum_steps = val * (PALLETTE.length-1);
    int   idx = (int)(Math.floor(lum_steps));
    float fract = lum_steps - idx;

    rgb[0] = PALLETTE[idx][0] * (1-fract) +  PALLETTE[idx+1][0] * fract;
    rgb[1] = PALLETTE[idx][1] * (1-fract) +  PALLETTE[idx+1][1] * fract;
    rgb[2] = PALLETTE[idx][2] * (1-fract) +  PALLETTE[idx+1][2] * fract;
  }


  protected int clamp(float v) {
    if ( v <   0 ) return 0;
    if ( v > 255 ) return 255;
    return (int)v;
  }

  private final float[] rgb = new float[3];

  public void updateShapeColor() {
    float vel  = getVelocity();
    float radn = 1.1f * rad / MAX_RAD;

    getShade(vel, rgb);
    int a = 255;
    int r = clamp(rgb[0] * radn) & 0xFF;
    int g = clamp(rgb[1] * radn) & 0xFF;
    int b = clamp(rgb[2] * radn) & 0xFF;

    int col = a << 24 | r << 16 | g << 8 | b;
    setColor(col);
  }
}