mirror of
https://github.com/scottdraves/flam3.git
synced 2025-01-21 05:20:05 -05:00
Merge pull request #8 from scottdraves/erik_dev
hsv_rgb_palette_blend implementation
This commit is contained in:
commit
035ab3d4e9
@ -39,6 +39,7 @@ void test_cp(flam3_genome *cp) {
|
||||
cp->time = 0.0;
|
||||
cp->interpolation = flam3_interpolation_linear;
|
||||
cp->palette_interpolation = flam3_palette_interpolation_hsv;
|
||||
cp->hsv_rgb_palette_blend = 0.0;
|
||||
cp->background[0] = 0.0;
|
||||
cp->background[1] = 0.0;
|
||||
cp->background[2] = 0.0;
|
||||
@ -248,7 +249,8 @@ void spin(int frame, double blend, flam3_genome *parent, flam3_genome *templ)
|
||||
/* Set genome parameters accordingly */
|
||||
result->time = (double)frame;
|
||||
result->interpolation = flam3_interpolation_linear;
|
||||
result->palette_interpolation = flam3_palette_interpolation_hsv;
|
||||
result->palette_interpolation = flam3_palette_interpolation_hsv_circular;
|
||||
result->hsv_rgb_palette_blend = 0.0;
|
||||
|
||||
/* Force linear interpolation - unsure if this is still necessary */
|
||||
/* I believe we put this in so that older clients could render frames */
|
||||
|
16
flam3.c
16
flam3.c
@ -785,7 +785,8 @@ void flam3_interpolate(flam3_genome cps[], int ncps,
|
||||
result->time = time;
|
||||
result->interpolation = flam3_interpolation_linear;
|
||||
result->interpolation_type = cpi[0].interpolation_type;
|
||||
result->palette_interpolation = flam3_palette_interpolation_hsv;
|
||||
result->palette_interpolation = flam3_palette_interpolation_hsv_circular;
|
||||
result->hsv_rgb_palette_blend = 0.0;
|
||||
|
||||
if (!smoothflag) {
|
||||
flam3_interpolate_n(result, 2, cpi, c, stagger);
|
||||
@ -1282,6 +1283,7 @@ void clear_cp(flam3_genome *cp, int default_flag) {
|
||||
cp->pixels_per_unit = 50;
|
||||
cp->interpolation = flam3_interpolation_linear;
|
||||
cp->palette_interpolation = flam3_palette_interpolation_hsv_circular;
|
||||
cp->hsv_rgb_palette_blend = 0.0;
|
||||
|
||||
cp->genome_index = 0;
|
||||
memset(cp->parent_fname,0,flam3_parent_fn_len);
|
||||
@ -1618,6 +1620,8 @@ void flam3_apply_template(flam3_genome *cp, flam3_genome *templ) {
|
||||
cp->palette_mode = templ->palette_mode;
|
||||
if (templ->palette_interpolation >= 0)
|
||||
cp->palette_interpolation = templ->palette_interpolation;
|
||||
if (templ->hsv_rgb_palette_blend >= 0)
|
||||
cp->hsv_rgb_palette_blend = templ->hsv_rgb_palette_blend;
|
||||
|
||||
}
|
||||
|
||||
@ -1785,8 +1789,13 @@ void flam3_print(FILE *f, flam3_genome *cp, char *extra_attributes, int print_ed
|
||||
fprintf(f, " palette_interpolation=\"sweep\"");
|
||||
else if (flam3_palette_interpolation_rgb == cp->palette_interpolation)
|
||||
fprintf(f, " palette_interpolation=\"rgb\"");
|
||||
else if (flam3_palette_interpolation_hsv_circular == cp->palette_interpolation)
|
||||
else if (flam3_palette_interpolation_hsv == cp->palette_interpolation)
|
||||
fprintf(f, " palette_interpolation=\"hsv\"");
|
||||
else if (flam3_palette_interpolation_hsv_circular == cp->palette_interpolation) {
|
||||
fprintf(f, " palette_interpolation=\"hsv_circular\"");
|
||||
if (cp->hsv_rgb_palette_blend > 0.0)
|
||||
fprintf(f, " hsv_rgb_palette_blend=\"%g\"", cp->hsv_rgb_palette_blend);
|
||||
}
|
||||
|
||||
if (extra_attributes)
|
||||
fprintf(f, " %s", extra_attributes);
|
||||
@ -3087,7 +3096,8 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
|
||||
fprintf(stderr,"error getting palette from xml file, setting to all white\n");
|
||||
cp->time = 0.0;
|
||||
cp->interpolation = flam3_interpolation_linear;
|
||||
cp->palette_interpolation = flam3_palette_interpolation_hsv;
|
||||
cp->palette_interpolation = flam3_palette_interpolation_hsv_circular;
|
||||
cp->hsv_rgb_palette_blend = 0.0;
|
||||
|
||||
/* Choose the number of xforms */
|
||||
if (spec_xforms>0) {
|
||||
|
1
flam3.h
1
flam3.h
@ -453,6 +453,7 @@ typedef struct {
|
||||
int interpolation;
|
||||
int interpolation_type;
|
||||
int palette_interpolation;
|
||||
double hsv_rgb_palette_blend;
|
||||
int num_xforms;
|
||||
int final_xform_index;
|
||||
int final_xform_enable;
|
||||
|
@ -372,83 +372,75 @@ double get_stagger_coef(double t, double stagger_prc, int num_xforms, int this_x
|
||||
and have final xform in the same slot) */
|
||||
void flam3_interpolate_n(flam3_genome *result, int ncp,
|
||||
flam3_genome *cpi, double *c, double stagger) {
|
||||
int i, j, k, numstd;
|
||||
|
||||
// fprintf(stderr, "xxx pi=%d\n", cpi[0].palette_interpolation);
|
||||
int i, j, k, l, numstd;
|
||||
|
||||
if (flam3_palette_interpolation_sweep != cpi[0].palette_interpolation) {
|
||||
|
||||
/* rgb, hsv or hsv_circular modes. */
|
||||
double rgb_fraction = 0.0; /* Assume that we are in plain hsv mode */
|
||||
if (flam3_palette_interpolation_rgb == cpi[0].palette_interpolation)
|
||||
rgb_fraction = 1.0; /* All RGB output */
|
||||
else if (flam3_palette_interpolation_hsv_circular == cpi[0].palette_interpolation)
|
||||
rgb_fraction = cpi[0].hsv_rgb_palette_blend;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
double t[3], s[5];
|
||||
double col_rgb[3], col_hsv[3];
|
||||
double new_rgb[3] = {0, 0, 0};
|
||||
double new_hsv[3] = {0, 0, 0};
|
||||
double new_count = 0, new_index = 0;
|
||||
int alpha1 = 1;
|
||||
|
||||
s[0] = s[1] = s[2] = s[3] = s[4] = 0.0;
|
||||
|
||||
/* Loop over each control point's color at this index */
|
||||
for (k = 0; k < ncp; k++) {
|
||||
if (i == 0) {
|
||||
// fprintf(stderr, "ncp=%d, k=%d\n", ncp, k);
|
||||
// fprintf(stderr, "rgb=%g %g %g\n", cpi[k].palette[i].color[0], cpi[k].palette[i].color[1], cpi[k].palette[i].color[2]);
|
||||
}
|
||||
if (flam3_palette_interpolation_rgb != cpi[0].palette_interpolation)
|
||||
rgb2hsv(cpi[k].palette[i].color, t);
|
||||
else {
|
||||
int l;
|
||||
|
||||
/* Convert to hsv */
|
||||
rgb2hsv(cpi[k].palette[i].color, col_hsv);
|
||||
|
||||
/* Store the rgb */
|
||||
for (l = 0; l < 3; l++)
|
||||
t[l] = cpi[k].palette[i].color[l];
|
||||
}
|
||||
// if (i == 0) {
|
||||
// fprintf(stderr, "hsv=%g %g %g\n", t[0], t[1], t[2]);
|
||||
// }
|
||||
col_rgb[l] = cpi[k].palette[i].color[l];
|
||||
|
||||
if (2 == ncp && k == 0 && cpi[0].palette_interpolation == flam3_palette_interpolation_hsv_circular) {
|
||||
/* should also support blending between rgb and hsv,
|
||||
and change the color of the cut, so we can keep
|
||||
a dominant color but control what it is. */
|
||||
|
||||
/* only adjust the first coordinate based on the other control point's hue */
|
||||
double second_color[3];
|
||||
rgb2hsv(cpi[1].palette[i].color, second_color);
|
||||
|
||||
/* Adjust the hue so that we go the shorter direction around the circle */
|
||||
if ((second_color[0] - t[0]) > 3.0) {
|
||||
t[0] += 6.0;
|
||||
} else if ((second_color[0] - t[0]) < -3.0) {
|
||||
t[0] -= 6.0;
|
||||
if ((second_color[0] - col_hsv[0]) > 3.0) {
|
||||
col_hsv[0] += 6.0;
|
||||
} else if ((second_color[0] - col_hsv[0]) < -3.0) {
|
||||
col_hsv[0] -= 6.0;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
s[j] += c[k] * t[j];
|
||||
for (j = 0; j < 3; j++) {
|
||||
new_rgb[j] += c[k] * col_rgb[j];
|
||||
new_hsv[j] += c[k] * col_hsv[j];
|
||||
}
|
||||
|
||||
s[3] += c[k] * cpi[k].palette[i].color[3];
|
||||
/* Compute the other two components of the color (count and index) */
|
||||
new_count += c[k] * cpi[k].palette[i].color[3];
|
||||
if (cpi[k].palette[i].color[3] != 1.0)
|
||||
alpha1 = 0;
|
||||
s[4] += c[k] * cpi[k].palette[i].index;
|
||||
new_index += c[k] * cpi[k].palette[i].index;
|
||||
|
||||
}
|
||||
|
||||
if (alpha1 == 1)
|
||||
s[3] = 1.0;
|
||||
new_count = 1.0;
|
||||
|
||||
// if (i == 0)
|
||||
// fprintf(stderr, "s0=%g\n", s[0]);
|
||||
/* Convert the new hsv coord to back rgb */
|
||||
double new_hsv_rgb[3];
|
||||
hsv2rgb(new_hsv, new_hsv_rgb);
|
||||
|
||||
if (flam3_palette_interpolation_rgb != cpi[0].palette_interpolation)
|
||||
hsv2rgb(s, result->palette[i].color);
|
||||
else {
|
||||
int l;
|
||||
/* Store the interpolated color in the new palette */
|
||||
for (l = 0; l < 3; l++)
|
||||
result->palette[i].color[l] = s[l];
|
||||
}
|
||||
result->palette[i].color[3] = s[3];
|
||||
result->palette[i].index = s[4];
|
||||
result->palette[i].color[l] = rgb_fraction * new_rgb[l] + (1.0-rgb_fraction) * new_hsv_rgb[l];
|
||||
|
||||
// if (i == 0)
|
||||
// fprintf(stderr, "result rgb=%g %g %g\n",
|
||||
// result->palette[0].color[0],
|
||||
// result->palette[0].color[1],
|
||||
// result->palette[0].color[2]);
|
||||
result->palette[i].color[3] = new_count;
|
||||
result->palette[i].index = new_index;
|
||||
|
||||
/* Clip the new color appropriately */
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (result->palette[i].color[j] < 0.0)
|
||||
result->palette[i].color[j] = 0.0;
|
||||
@ -477,6 +469,7 @@ void flam3_interpolate_n(flam3_genome *result, int ncp,
|
||||
|
||||
result->interpolation_type = cpi[0].interpolation_type;
|
||||
result->palette_interpolation = cpi[0].palette_interpolation;
|
||||
result->hsv_rgb_palette_blend = cpi[0].hsv_rgb_palette_blend;
|
||||
INTERP(brightness);
|
||||
INTERP(contrast);
|
||||
INTERP(highlight_power);
|
||||
|
2
parser.c
2
parser.c
@ -332,6 +332,8 @@ int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp) {
|
||||
/* Compare attribute names */
|
||||
if (!xmlStrcmp(cur_att->name, (const xmlChar *)"time")) {
|
||||
cp->time = flam3_atof(att_str);
|
||||
} else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"hsv_rgb_palette_blend")) {
|
||||
cp->hsv_rgb_palette_blend = flam3_atof(att_str);
|
||||
} else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"interpolation")) {
|
||||
if (!strcmp("linear", att_str)) {
|
||||
cp->interpolation = flam3_interpolation_linear;
|
||||
|
Loading…
Reference in New Issue
Block a user