From 873268709d40952ff79b0cb75e48bceec21482bd Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Thu, 9 Jan 2025 01:33:45 +0900 Subject: [PATCH] =?UTF-8?q?=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82=20EffectLiq?= =?UTF-8?q?uidLamp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - переработаны контролы - перевёрнута ось Y - фон не заливается цветом из палитры при значениях фильтра Шарра 0 и 1 --- data/eff/controls.json | 10 +++ resources/html/js/ui_lamp.json | 122 +++++++++++++++++++++++++++++++++ src/effects.cpp | 74 ++++++++++++++------ src/effects.h | 17 +++-- src/effects_types.h | 3 +- src/effectworker.cpp | 4 ++ 6 files changed, 199 insertions(+), 31 deletions(-) diff --git a/data/eff/controls.json b/data/eff/controls.json index 62859989..7a72a4ab 100644 --- a/data/eff/controls.json +++ b/data/eff/controls.json @@ -32,6 +32,16 @@ {"label":"nsmooth", "smin":100, "smax":255} ] }, + "liquidlamp":{ + "ctrls":[ + {"label":"speed", "smin":20, "smax":250}, + {"label":"scale", "min":5, "max":50}, + {"label":"pallete", "min":0, "max":16}, + {"label":"hue", "min":0, "max":255}, + {"label":"sharr", "min":0, "max":3}, + {"label":"physics", "min":0, "max":1} + ] + }, "magma":{ "ctrls":[ {"label":"speed"}, diff --git a/resources/html/js/ui_lamp.json b/resources/html/js/ui_lamp.json index 68808701..fecb8c3e 100644 --- a/resources/html/js/ui_lamp.json +++ b/resources/html/js/ui_lamp.json @@ -3477,6 +3477,128 @@ } ] }, + "liquidlamp":{ + "section":"eff_ctrls", + "replace":true, + "block":[ + { + "section":"uidata", + "block":[ + { + "action":"pick", + "key":"lampui.effCommon.speed" + }, + { + "action":"pick", + "key":"lampui.effCommon.scale" + } + ] + }, + { + "id":"eff_control_2", + "html":"select", + "label":"Палитры", + "onChange": true, + "value":0, + "section":"options", + "block":[ + { + "value":0, + "label":"Custom - MBViolet" + }, + { + "value":1, + "label":"Jul" + }, + { + "value":2, + "label":"Sunset Real" + }, + { + "value":3, + "label":"Pink Splash" + }, + { + "value":4, + "label":"Landscape 1" + }, + { + "value":5, + "label":"Landscape 2" + }, + { + "value":6, + "label":"Landscape 3" + }, + { + "value":7, + "label":"Landscape 4" + }, + { + "value":8, + "label":"Ocean Breeze" + }, + { + "value":9, + "label":"GMT drywet 1" + }, + { + "value":10, + "label":"GMT drywet 2" + }, + { + "value":11, + "label":"GMT drywet 3" + }, + { + "value":12, + "label":"Fire" + }, + { + "value":13, + "label":"Pink Purple 1" + }, + { + "value":14, + "label":"Pink Purple 2" + }, + { + "value":15, + "label":"Sunset real" + }, + { + "value":16, + "label":"Black Magenta Red" + } + ] + }, + { + "html": "input", + "id": "eff_control_3", + "type": "range", + "label": "Оттенок для спец палитры", + "min": 0, + "max": 255, + "onChange": true + }, + { + "html": "input", + "id": "eff_control_4", + "type": "number", + "label": "Фильтр Шарра", + "min": 0, + "max": 2, + "onChange": true + }, + { + "id":"eff_control_5", + "html":"input", + "label":"Физика", + "type":"checkbox", + "onChange": true + } + ] + }, "magma":{ "section":"eff_ctrls", "replace":true, diff --git a/src/effects.cpp b/src/effects.cpp index d0fe9b4a..8d9b55aa 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -2603,20 +2603,21 @@ void EffectPicassoMetaBalls::_dyn_palette_generator(uint8_t hue){ */ -#if !defined (OBSOLETE_CODE) // ----------- Эффекты "Лавовая лампа" (c) obliterator EffectLiquidLamp::EffectLiquidLamp(LedFB *framebuffer) : EffectCalc(framebuffer) { + scale = LIQLAMP_MIN_PARTICLES; +#define LIQLAMP_PALLETE_MAX_IDX 16 // эта палитра создана под эффект palettes.add(MBVioletColors_gp, 0, 16); // палитры частично подогнаные под эффект palettes.add(ib_jul01_gp, 60, 16, 200); palettes.add(Sunset_Real_gp, 25, 0, 200); - palettes.add(es_landscape_33_gp, 50, 50); palettes.add(es_pinksplash_08_gp, 125, 16); + palettes.add(es_landscape_33_gp, 50, 50); palettes.add(es_landscape_64_gp, 175, 50, 220); palettes.add(es_landscape_64_gp, 25, 16, 250); - palettes.add(es_ocean_breeze_036_gp, 0); palettes.add(es_landscape_33_gp, 0); + palettes.add(es_ocean_breeze_036_gp, 0); palettes.add(GMT_drywet_gp, 0); palettes.add(GMT_drywet_gp, 75); palettes.add(GMT_drywet_gp, 150, 0, 200); @@ -2628,10 +2629,8 @@ EffectLiquidLamp::EffectLiquidLamp(LedFB *framebuffer) : EffectCalc(frameb } void EffectLiquidLamp::generate(bool reset){ - unsigned num = map(scale, 0U, 255, LIQLAMP_MIN_PARTICLES, LIQLAMP_MAX_PARTICLES); - - if (num != particles.size()) - particles.assign(num, Particle()); + if (scale != particles.size()) + particles.assign(scale, Particle()); else if (!reset) return; for (auto &curr : particles){ @@ -2661,7 +2660,7 @@ void EffectLiquidLamp::position(){ if (curr.speed_y) curr.speed_y *= 0.85; curr.position_y += curr.speed_y * speedFactor; - if (physic_on) { + if (_physics) { curr.speed_x *= 0.7; curr.position_x += curr.speed_x * speedFactor; } @@ -2702,12 +2701,47 @@ void EffectLiquidLamp::physic(){ } } -// !++ void EffectLiquidLamp::setControl(size_t idx, int32_t value) { - if(_val->getId()==1) speedFactor = ((float)EffectCalc::setDynCtrl(_val).toInt() / 127.0 + 0.1)*getBaseSpeedFactor(); - else if(_val->getId()==3) pidx = EffectCalc::setDynCtrl(_val).toInt(); - else if(_val->getId()==4) { - byte hue = EffectCalc::setDynCtrl(_val).toInt(); + switch (idx){ + // 0 - speed - range 0-255 + case 0: + speedFactor = value / 128.0; //EffectMath::fmap(value, 1, 10, 0.01, 0.4); + break; + // 1 scale - num of particles, as-is value clamped to 1-width/4 + case 1: + scale = clamp(value, static_cast(LIQLAMP_MIN_PARTICLES), static_cast(LIQLAMP_MAX_PARTICLES)); + break; + + // custom palletes + case 2: + _pallete_id = clamp(value, static_cast(0), static_cast(LIQLAMP_PALLETE_MAX_IDX)); + break; + + // 3 - hue for custom pallete - range 1-255 + case 3: { + _dynamic_pallete(value); + _pallete_id = 0; + break; + } + + // 4 - shar's filter - raw, range 0-2 + case 4: { + filter = clamp(value, static_cast(0), static_cast(2)); + break; + } + + // 5 - physics + case 5: { + _physics = value; + break; + } + + default: + EffectCalc::setControl(idx, value); + } +} + +void EffectLiquidLamp::_dynamic_pallete(uint8_t hue){ TDynamicRGBGradientPalette_byte dynpal[20] = { 0, 0, 0, 0, 1, 0, 0, 0, @@ -2723,17 +2757,13 @@ void EffectLiquidLamp::setControl(size_t idx, int32_t value) { *color = CHSV(hue + 255, 255U, 255U); CRGBPalette32 pal; pal.loadDynamicGradientPalette(dynpal); palettes.add(0, pal, 0, 16); - } - else if(_val->getId()==5) { filter = EffectCalc::setDynCtrl(_val).toInt(); } // enable filtering } - else if(_val->getId()==6) physic_on = EffectCalc::setDynCtrl(_val).toInt(); - else EffectCalc::setDynCtrl(_val).toInt(); // для всех других не перечисленных контролов просто дергаем функцию базового класса (если это контролы палитр, микрофона и т.д.) - return String(); } bool EffectLiquidLamp::routine(){ generate(); position(); - if (physic_on) physic(); + fb->clear(); + if (_physics) physic(); uint8_t f = filter; // local scope copy to provide thread-safety @@ -2760,7 +2790,8 @@ bool EffectLiquidLamp::routine(){ } if (f < 2) { - fb->at(x, y) = palettes[pidx].GetColor(sum, filter? sum : 255); + if ( sum > 5) // do not fill the background with palette color + fb->at(x, fb->h() - y) = palettes[_pallete_id].GetColor(sum, filter? sum : 255); } else { buff->at(x,y) = sum; } @@ -2796,13 +2827,14 @@ bool EffectLiquidLamp::routine(){ val = 1 - (val - min) / (max - min); unsigned step = f - 1; while (step) { val *= val; --step; } // почему-то это быстрее чем pow - fb->at(x, y) = palettes[pidx].GetColor(buff->at(x,y), val * 255); + fb->at(x, fb->h() - y) = palettes[_pallete_id].GetColor(buff->at(x,y), val * 255); } } return true; } +#if !defined (OBSOLETE_CODE) // ------- Эффект "Вихри" // Based on Aurora : https://github.com/pixelmatix/aurora/blob/master/PatternFlowField.h // Copyright(c) 2014 Jason Coon diff --git a/src/effects.h b/src/effects.h index edfc0ecc..ac3244c0 100644 --- a/src/effects.h +++ b/src/effects.h @@ -572,19 +572,16 @@ class EffectPicassoMetaBalls : public EffectPicassoBase { void setControl(size_t idx, int32_t value) override; }; -#ifdef DISABLED_CODE // ------ Эффект "Лавовая Лампа" // (c) obliterator #define LIQLAMP_MASS_MIN 10 #define LIQLAMP_MASS_MAX 50 -#define LIQLAMP_MIN_PARTICLES 10 -#define LIQLAMP_MAX_PARTICLES 20 +#define LIQLAMP_MIN_PARTICLES 5 +#define LIQLAMP_MAX_PARTICLES 100 class EffectLiquidLamp : public EffectCalc { struct Particle{ - float position_x = 0; - float position_y = 0; - float speed_x = 0; - float speed_y = 0; + float position_x{0}, position_y{0}; + float speed_x{0}, speed_y{0}; float rad = 0; float hot = 0; float spf = 0; @@ -594,8 +591,8 @@ class EffectLiquidLamp : public EffectCalc { unsigned tr = 0; }; - uint8_t pidx = 0; - bool physic_on = 1; + uint8_t _pallete_id = 0; + bool _physics = 1; uint8_t filter = 0; GradientPaletteList palettes; @@ -603,6 +600,7 @@ class EffectLiquidLamp : public EffectCalc { std::unique_ptr< Vector2D > buff; std::unique_ptr< Vector2D > buff2; + void _dynamic_pallete(uint8_t hue); void generate(bool reset = false); void position(); void physic(); @@ -615,6 +613,7 @@ class EffectLiquidLamp : public EffectCalc { void setControl(size_t idx, int32_t value) override; }; +#ifdef DISABLED_CODE // ------- Эффект "Вихри" // Based on Aurora : https://github.com/pixelmatix/aurora/blob/master/PatternFlowField.h // Copyright(c) 2014 Jason Coon diff --git a/src/effects_types.h b/src/effects_types.h index 3449bae9..3fe043d8 100644 --- a/src/effects_types.h +++ b/src/effects_types.h @@ -178,11 +178,12 @@ static constexpr const char* T_whitelight = "whitelight"; // firmware defined static index names for each of available effects -static constexpr std::array fw_effects_index = { +static constexpr std::array fw_effects_index = { effect_t::empty, effect_t::bouncingballs, effect_t::fireveil, effect_t::fire2012, + effect_t::liquidlamp, effect_t::magma, effect_t::metaballs, effect_t::nexus, diff --git a/src/effectworker.cpp b/src/effectworker.cpp index e13fc317..1908db06 100644 --- a/src/effectworker.cpp +++ b/src/effectworker.cpp @@ -491,6 +491,10 @@ void EffectWorker::_spawn(effect_t eid){ worker = std::make_unique(canvas); break; + case effect_t::liquidlamp : + worker = std::make_unique(canvas); + break; + case effect_t::magma : worker = std::make_unique(canvas); break;