// Common, group Output
// Copyright Alexander Liss
#ifndef __COLOR_H__
#define __COLOR_H__
#include "array.h"
// Tint
struct Stain;
struct Color;
struct Tint
{
float x1,x2,x3; // RGB
float level()const{return x1+x2+x3;}
void set_white(float level){if(level>0){x1=x2=x3=level/3;}}
void set(const Stain& s, float level);
void set(const Color& s);
Tint& operator *=(float c){x1*=c;x2*=c;x3*=c;return *this;}
Tint& operator +=(const Tint& z){x1+=z.x1;x2+=z.x2;x3+=z.x3;return *this;}
};
// Color
struct Color: public Tint
{
float x4;
void set_zero(){x1=x2=x3=x4=0;}
void set(const Tint& s){Tint::operator=(s);}
Color& operator *=(float c){Tint::operator*=(c);x4*=c;return *this;}
Color& operator +=(const Color& z){Tint::operator+=(z);x4+=z.x4;return *this;}
};
// Stain
struct Stain
{
float x1,x2,x3; // x1+x2+x3=1
void set(const Tint& s);
};
// ColorMixer
class ColorMixer
{
ColorMixer(const ColorMixer&);
ColorMixer& operator=(const ColorMixer&);
public:
void reset(){mix.set_zero();}
int add(const Color& z,float vigor)
{if(vigor<=0) return 1; Color t(z); t*=vigor; mix+=t; return 0;}
int get(Color& z){ z=mix; return 0;}
private:
Color mix;
};
// RandomColor
class RandomColor
{
friend int pack(CommBuffer& d, const RandomColor& z);
friend int unpack(RandomColor& z,const CommBuffer& s,ReadControl& c);
public:
RandomColor():sum(0){}
RandomColor(const RandomColor& z){copy(z);}
RandomColor& operator=(const RandomColor& z)
{if(&z != this){clear(); copy(z);} return *this;}
int add(const Color& z,float weight);
int get_next(Color& d);
private:
struct Unit
{
Color c; float p;
Unit():p(0){}
Unit(const Color& ca,float pa):c(ca),p(pa){}
};
float sum;
SimpleArray<Unit> units;
void clear();
void copy(const RandomColor&);
};
// FUNCTIONS
int mix(Color& d,const Color& s1,const Color& s2,float ratio12);
#endif