From 94b367dd6fe78fa4c6a36a484f50472322588397 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 25 May 2022 00:24:35 -0700 Subject: modules/shapes: introduce pinch setting This is kind of experimental, not sure how I feel about it. pinch=0..1 with a bunch of fractions, 0 disables it. pinch_spin=-1..1 same as spin= pinches=1..10 number of pinches, which come in pairs This applies to all the current shapes, for a tour: --module=rtv,channels=shapes,duration=2,context_duration=2,snow_module=none --defaults I think the speeds might go to high atm, I kind of liked the slower spins before all this more. --- src/modules/shapes/shapes.c | 130 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 14 deletions(-) diff --git a/src/modules/shapes/shapes.c b/src/modules/shapes/shapes.c index f601feb..3726599 100644 --- a/src/modules/shapes/shapes.c +++ b/src/modules/shapes/shapes.c @@ -64,10 +64,13 @@ #include "til.h" #include "til_fb.h" -#define SHAPES_DEFAULT_TYPE SHAPES_TYPE_PINWHEEL -#define SHAPES_DEFAULT_SCALE 1 -#define SHAPES_DEFAULT_POINTS 5 -#define SHAPES_DEFAULT_SPIN .1 +#define SHAPES_DEFAULT_TYPE SHAPES_TYPE_PINWHEEL +#define SHAPES_DEFAULT_SCALE 1 +#define SHAPES_DEFAULT_POINTS 5 +#define SHAPES_DEFAULT_SPIN .1 +#define SHAPES_DEFAULT_PINCH 0 +#define SHAPES_DEFAULT_PINCH_SPIN .5 +#define SHAPES_DEFAULT_PINCHES 2 typedef enum shapes_type_t { SHAPES_TYPE_CIRCLE, @@ -80,6 +83,9 @@ typedef struct shapes_setup_t { til_setup_t til_setup; shapes_type_t type; float scale; + float pinch; + float pinch_spin; + unsigned n_pinches; unsigned n_points; float spin; } shapes_setup_t; @@ -154,12 +160,18 @@ static void shapes_render_fragment(void *context, unsigned ticks, unsigned cpu, switch (ctxt->setup.type) { case SHAPES_TYPE_CIRCLE: { int r_sq = (size >> 1); + float s = 2.f / (float)size; + float XX, YY; r_sq *= r_sq; - for (int y = yoff, Y = -(size >> 1); y < yoff + size; y++, Y++) { - for (int x = xoff, X = -(size >> 1); x < xoff + size; x++, X++) { - if (Y*Y+X*X < r_sq) + YY = -1.f; + for (int y = yoff, Y = -(size >> 1); y < yoff + size; y++, Y++, YY += s) { + XX = -1.f; + for (int x = xoff, X = -(size >> 1); x < xoff + size; x++, X++, XX += s) { + float rad = atan2f(YY, XX); + + if (Y*Y+X*X < r_sq * (1.f - fabsf(cosf(ctxt->setup.n_pinches * rad + (float)ticks * ctxt->setup.pinch_spin * .01f)) * ctxt->setup.pinch)) til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x, fragment->y + y, 0xffffffff); else if (!fragment->cleared) til_fb_fragment_put_pixel_unchecked(fragment, 0, fragment->x + x, fragment->y + y, 0x0); @@ -177,8 +189,10 @@ static void shapes_render_fragment(void *context, unsigned ticks, unsigned cpu, for (unsigned y = yoff; y < yoff + size; y++, Y += s) { X = -1.f; for (unsigned x = xoff; x < xoff + size; x++, X += s) { - float rad = atan2f(Y, X) + (float)ticks * ctxt->setup.spin * .01f; - float r = cosf((float)ctxt->setup.n_points * rad) * .5f + .5f; + float rad = atan2f(Y, X); + float r = cosf((float)ctxt->setup.n_points * (rad + (float)ticks * ctxt->setup.spin * .01f)) * .5f + .5f; + + r *= 1.f - fabsf(cosf(ctxt->setup.n_pinches * rad + (float)ticks * ctxt->setup.pinch_spin * .01f)) * ctxt->setup.pinch; if (X * X + Y * Y < r * r) til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x, fragment->y + y, 0xffffffff); @@ -192,13 +206,19 @@ static void shapes_render_fragment(void *context, unsigned ticks, unsigned cpu, case SHAPES_TYPE_RHOMBUS: { int r = (size >> 1); + float s = 2.f / (float)size; + float XX, YY; int X, Y; + YY = -1.f; Y = -(size >> 1); - for (unsigned y = yoff; y < yoff + size; y++, Y++) { + for (unsigned y = yoff; y < yoff + size; y++, Y++, YY += s) { + XX = -1.f; X = -(size >> 1); - for (unsigned x = xoff; x < xoff + size; x++, X++) { - if (abs(Y) + abs(X) < r) + for (unsigned x = xoff; x < xoff + size; x++, X++, XX += s) { + float rad = atan2f(YY, XX); + + if (abs(Y) + abs(X) < r * (1.f - fabsf(cosf(ctxt->setup.n_pinches * rad + (float)ticks * ctxt->setup.pinch_spin * .01f)) * ctxt->setup.pinch)) til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x, fragment->y + y, 0xffffffff); else if (!fragment->cleared) til_fb_fragment_put_pixel_unchecked(fragment, 0, fragment->x + x, fragment->y + y, 0x0); @@ -216,10 +236,12 @@ static void shapes_render_fragment(void *context, unsigned ticks, unsigned cpu, for (unsigned y = yoff; y < yoff + size; y++, Y += s) { X = -1.f; for (unsigned x = xoff; x < xoff + size; x++, X += s) { - float rad = atan2f(Y, X) + (float)ticks * ctxt->setup.spin * .01f; - float r = (M_2_PI * asinf(sinf((float)ctxt->setup.n_points * rad) * .5f + .5f)) * .5f + .5f; + float rad = atan2f(Y, X); + float r = (M_2_PI * asinf(sinf((float)ctxt->setup.n_points * (rad + (float)ticks * ctxt->setup.spin * .01f)) * .5f + .5f)) * .5f + .5f; /* ^^^^^^^^^^^^^^^^^^^ approximates a triangle wave */ + r *= 1.f - fabsf(cosf(ctxt->setup.n_pinches * rad + (float)ticks * ctxt->setup.pinch_spin * .01f)) * ctxt->setup.pinch; + if (X * X + Y * Y < r * r) til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x, fragment->y + y, 0xffffffff); else if (!fragment->cleared) @@ -238,6 +260,9 @@ static int shapes_setup(const til_settings_t *settings, til_setting_t **res_sett const char *points; const char *spin; const char *scale; + const char *pinch; + const char *pinch_spin; + const char *pinches; const char *type_values[] = { "circle", "pinwheel", @@ -296,6 +321,31 @@ static int shapes_setup(const til_settings_t *settings, til_setting_t **res_sett "1", NULL }; + const char *pinch_values[] = { + "0", + ".1", + ".25", + ".33", + ".5", + ".66", + ".75", + ".9", + "1", + NULL + }; + const char *pinches_values[] = { + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + NULL + }; int r; r = til_settings_get_and_describe_value(settings, @@ -328,6 +378,53 @@ static int shapes_setup(const til_settings_t *settings, til_setting_t **res_sett if (r) return r; + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Pinch factor", + .key = "pinch", + .regex = "(1|0?\\.[0-9]{1,2})", + .preferred = TIL_SETTINGS_STR(SHAPES_DEFAULT_PINCH), + .values = pinch_values, + .annotations = NULL + }, + &pinch, + res_setting, + res_desc); + if (r) + return r; + + if (strcmp(pinch, "0")) { + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Pinch spin factor", + .key = "pinch_spin", + .regex = "-?(0|1|0?\\.[0-9]{1,2})", + .preferred = TIL_SETTINGS_STR(SHAPES_DEFAULT_PINCH_SPIN), + .values = spin_values, + .annotations = NULL + }, + &pinch_spin, + res_setting, + res_desc); + if (r) + return r; + + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Number of pinches", + .key = "pinches", + .regex = "[0-9]+", + .preferred = TIL_SETTINGS_STR(SHAPES_DEFAULT_PINCHES), + .values = pinches_values, + .annotations = NULL + }, + &pinches, + res_setting, + res_desc); + if (r) + return r; + } + if (!strcasecmp(type, "star") || !strcasecmp(type, "pinwheel")) { r = til_settings_get_and_describe_value(settings, &(til_setting_desc_t){ @@ -382,6 +479,11 @@ static int shapes_setup(const til_settings_t *settings, til_setting_t **res_sett } sscanf(scale, "%f", &setup->scale); /* TODO: -EINVAL parse errors */ + sscanf(pinch, "%f", &setup->pinch); /* TODO: -EINVAL parse errors */ + if (setup->pinch != 0) { + sscanf(pinch_spin, "%f", &setup->pinch_spin); /* TODO: -EINVAL parse errors */ + sscanf(pinches, "%u", &setup->n_pinches); /* TODO: -EINVAL parse errors */ + } if (setup->type == SHAPES_TYPE_STAR || setup->type == SHAPES_TYPE_PINWHEEL) { sscanf(points, "%u", &setup->n_points); /* TODO: -EINVAL parse errors */ -- cgit v1.2.1