diff --git a/include/effects.h b/include/effects.h index 9342368f2..ed31cafc6 100644 --- a/include/effects.h +++ b/include/effects.h @@ -174,9 +174,13 @@ #define EFFECT_MATRIX_SMNOISE_SHIKON 198 #define EFFECT_MATRIX_SMNOISE_COLORCUBE 199 +#define EFFECT_MATRIX_SMPICASSO_1 200 +#define EFFECT_MATRIX_SMPICASSO_2 201 +#define EFFECT_MATRIX_SMPICASSO_3 202 +//TODO: Talk to Rutger about impact of changing this. // Hexagon Effects -#define EFFECT_HEXAGON_OUTER_RING 201 +#define EFFECT_HEXAGON_OUTER_RING 301 // Starry Night star variations #define EFFECT_STAR 1 diff --git a/include/effects/matrix/PatternSMFPicasso3in1.h b/include/effects/matrix/PatternSMFPicasso3in1.h index dab486338..21c403bfb 100644 --- a/include/effects/matrix/PatternSMFPicasso3in1.h +++ b/include/effects/matrix/PatternSMFPicasso3in1.h @@ -18,142 +18,26 @@ class PatternSMPicasso3in1 : public LEDStripEffect static constexpr int trackingOBJECT_MAX_COUNT = 100U; // максимальное количество отслеживаемых объектов (очень влияет на // расход памяти) - float trackingObjectPosX[trackingOBJECT_MAX_COUNT]; - float trackingObjectPosY[trackingOBJECT_MAX_COUNT]; - float trackingObjectSpeedX[trackingOBJECT_MAX_COUNT]; - float trackingObjectSpeedY[trackingOBJECT_MAX_COUNT]; - float trackingObjectShift[trackingOBJECT_MAX_COUNT]; - uint8_t trackingObjectHue[trackingOBJECT_MAX_COUNT]; - uint8_t trackingObjectState[trackingOBJECT_MAX_COUNT]; - bool trackingObjectIsShift[trackingOBJECT_MAX_COUNT]; + float trackingObjectPosX[trackingOBJECT_MAX_COUNT] {0}; + float trackingObjectPosY[trackingOBJECT_MAX_COUNT] {0}; + float trackingObjectSpeedX[trackingOBJECT_MAX_COUNT] {0}; + float trackingObjectSpeedY[trackingOBJECT_MAX_COUNT] {0}; + float trackingObjectShift[trackingOBJECT_MAX_COUNT] {0}; + uint8_t trackingObjectHue[trackingOBJECT_MAX_COUNT] {0}; + uint8_t trackingObjectState[trackingOBJECT_MAX_COUNT] {0}; + bool trackingObjectIsShift[trackingOBJECT_MAX_COUNT] {0}; static constexpr int enlargedOBJECT_MAX_COUNT = (MATRIX_WIDTH * 2); // максимальное количество сложных отслеживаемых объектов // (меньше, чем trackingOBJECT_MAX_COUNT) uint8_t enlargedObjectNUM; // используемое в эффекте количество объектов - long enlargedObjectTime[enlargedOBJECT_MAX_COUNT]; - - // функция отрисовки точки по координатам X Y - void drawPixelXYF(float x, float y, CRGB color) const - { - y = MATRIX_HEIGHT - 1 - y; - if (!g()->isValidPixel(x,y)) - return; - // uint32_t thisPixel = XY((uint8_t)x, (uint8_t)y); - // NightDriver's coordinate system is dfferent. Invert height and this all - // works! - uint32_t thisPixel = XY((uint8_t)x, (uint8_t)y); - g()->leds[thisPixel] = color; - } - - // функция отрисовки точки по координатам X Y - void drawPixelXY(int x, int y, CRGB color) const - { - y = MATRIX_HEIGHT - 1 - y; - if (!g()->isValidPixel(x,y)) - return; - uint32_t thisPixel = XY(x, y); - g()->leds[thisPixel] = color; - } - - // ------------------------------ Дополнительные функции рисования - // ---------------------- - void DrawLine(int x1, int y1, int x2, int y2, CRGB color) const - { - int deltaX = std::abs(x2 - x1); - int deltaY = std::abs(y2 - y1); - int signX = x1 < x2 ? 1 : -1; - int signY = y1 < y2 ? 1 : -1; - int error = deltaX - deltaY; - - drawPixelXY(x2, y2, color); - while (x1 != x2 || y1 != y2) - { - drawPixelXY(x1, y1, color); - int error2 = error * 2; - if (error2 > -deltaY) - { - error -= deltaY; - x1 += signX; - } - if (error2 < deltaX) - { - error += deltaX; - y1 += signY; - } - } - } - - void DrawLineF(float x1, float y1, float x2, float y2, CRGB color) const - { - float deltaX = fabs(x2 - x1); - float deltaY = fabs(y2 - y1); - float error = deltaX - deltaY; - - float signX = x1 < x2 ? 0.5 : -0.5; - float signY = y1 < y2 ? 0.5 : -0.5; - - while (x1 != x2 || y1 != y2) - { // (true) - а я то думаю - "почему функция часто вызывает - // вылет по вачдогу?" А оно вон оно чё, Михалычь! - if ((signX > 0 && x1 > x2 + signX) || (signX < 0 && x1 < x2 + signX)) - break; - if ((signY > 0 && y1 > y2 + signY) || (signY < 0 && y1 < y2 + signY)) - break; - drawPixelXYF(x1, y1, - color); // интересно, почему тут было обычное drawPixelXY() ??? - float error2 = error; - if (error2 > -deltaY) - { - error -= deltaY; - x1 += signX; - } - if (error2 < deltaX) - { - error += deltaX; - y1 += signY; - } - } - } - - // We use our own drawCircle() and drawPixel() because we KNOW we're going to - // draw near edges and the system versions scribble on memory when we do. Ours - // clamp. - void drawCircle(uint x0, uint y0, int radius, const CRGB &color) const - { - int a = radius, b = 0; - int radiusError = 1 - a; - - if (radius == 0) - { - drawPixelXY(x0, y0, color); - return; - } - - while (a >= b) - { - drawPixelXY(a + x0, b + y0, color); - drawPixelXY(b + x0, a + y0, color); - drawPixelXY(-a + x0, b + y0, color); - drawPixelXY(-b + x0, a + y0, color); - drawPixelXY(-a + x0, -b + y0, color); - drawPixelXY(-b + x0, -a + y0, color); - drawPixelXY(a + x0, -b + y0, color); - drawPixelXY(b + x0, -a + y0, color); - b++; - if (radiusError < 0) - radiusError += 2 * b + 1; - else - { - a--; - radiusError += 2 * (b - a + 1); - } - } - } + long enlargedObjectTime[enlargedOBJECT_MAX_COUNT] {0}; + int _scale{-1}; + const String _name; void PicassoGenerate(bool reset) { static int loadingFlag = true; - if (loadingFlag) + if (reset || loadingFlag) { loadingFlag = false; if (enlargedObjectNUM > enlargedOBJECT_MAX_COUNT) @@ -222,7 +106,7 @@ class PatternSMPicasso3in1 : public LEDStripEffect for (uint8_t i = 0; i < enlargedObjectNUM - 2U; i += 2) { - DrawLine(trackingObjectPosX[i], trackingObjectPosY[i], trackingObjectPosX[i + 1U], + g()->drawLine(trackingObjectPosX[i], trackingObjectPosY[i], trackingObjectPosX[i + 1U], trackingObjectPosY[i + 1U], CHSV(trackingObjectHue[i], 255U, 255U)); // DrawLine(trackingObjectPosX[i], trackingObjectPosY[i], // trackingObjectPosX[i+1U], trackingObjectPosY[i+1U], @@ -240,7 +124,7 @@ class PatternSMPicasso3in1 : public LEDStripEffect g()->DimAll(180); for (uint8_t i = 0; i < enlargedObjectNUM - 1U; i++) - DrawLineF(trackingObjectPosX[i], trackingObjectPosY[i], trackingObjectPosX[i + 1U], + g()->drawLine(trackingObjectPosX[i], trackingObjectPosY[i], trackingObjectPosX[i + 1U], trackingObjectPosY[i + 1U], CHSV(trackingObjectHue[i], 255U, 255U)); EVERY_N_MILLIS(20000) @@ -257,7 +141,7 @@ class PatternSMPicasso3in1 : public LEDStripEffect g()->DimAll(180); for (uint8_t i = 0; i < enlargedObjectNUM - 2U; i += 2) - drawCircle(fabs(trackingObjectPosX[i] - trackingObjectPosX[i + 1U]), + g()->DrawSafeCircle(fabs(trackingObjectPosX[i] - trackingObjectPosX[i + 1U]), fabs(trackingObjectPosY[i] - trackingObjectPosX[i + 1U]), fabs(trackingObjectPosX[i] - trackingObjectPosY[i]), CHSV(trackingObjectHue[i], 255U, 255U)); @@ -269,18 +153,37 @@ class PatternSMPicasso3in1 : public LEDStripEffect } public: - PatternSMPicasso3in1() : LEDStripEffect(EFFECT_MATRIX_SMPICASSO3IN1, "Picasso") + PatternSMPicasso3in1() : LEDStripEffect(EFFECT_MATRIX_SMPICASSO3IN1, "Picasso"), _scale(-1) { } - PatternSMPicasso3in1(const JsonObjectConst &jsonObject) : LEDStripEffect(jsonObject) + PatternSMPicasso3in1(const String& name, int scale) : LEDStripEffect(EFFECT_MATRIX_SMPICASSO3IN1, name), _name(name), _scale(scale) { } - // This has atomicity issues. It looks at a global (boooo) that may change the - // contents of the underlying enlarge/trackingFOO arrays while they're being - // traversed. It's just a bad diea to modify Scale while these are running, - // but there's too much cool code in this effect to just let it go to waste. + + PatternSMPicasso3in1(const JsonObjectConst &jsonObject) : LEDStripEffect(jsonObject), _scale(jsonObject["scale"]) + { + } + + virtual bool SerializeToJSON(JsonObject& jsonObject) override + { + StaticJsonDocument<128> jsonDoc; + + JsonObject root = jsonDoc.to(); + LEDStripEffect::SerializeToJSON(root); + + jsonDoc["scale"] = _scale; + + return jsonObject.set(jsonDoc.as()); + } + + + // This has atomicity issues. It looks at a global (boooo) that + // may change the contents of the underlying enlarge/trackingFOO + // arrays while they're being traversed. It's just a bad diea + // to modify Scale while these are running, so we try to do it + // only when Scale changes. void RecalibrateDrawnObjects() { @@ -295,34 +198,23 @@ class PatternSMPicasso3in1 : public LEDStripEffect void Start() override { g()->Clear(); + Scale = _scale; RecalibrateDrawnObjects(); } void Draw() override { - // Mesmerizer/NightDriver demo: just pick some preset and skip through them. - // Good way to demo off this module, but it's a bit much visually! - // robert - // An entry of 6 does so much work it trips the watchdog! - // An entry of 45 does so much work it trips the watchdog! - static int demo_values[] = {3, 35, 68}; - static int demo_idx = 0; - - // BUGBUG(robertl): Just eyeballing this, I think the clock is running about - // double time... - EVERY_N_MILLIS(10000) - { - if (demo_idx++ == sizeof(demo_values) / sizeof(demo_values[0])) - demo_idx = 0; - Scale = demo_values[demo_idx]; - // RecalibrateDrawnObjects(); - debugI("Index %d Scale %d", demo_idx, Scale); - // delay(10); - } - // end robert + static int last_scale = _scale; + + // Force a recalibration on effect change. + if (last_scale != Scale) { + debugA("Recalibrating from %d to %d", last_scale, Scale); + PicassoGenerate(true); + last_scale = Scale; + } + + Scale = _scale; - // Don't just let the renderer freewheel. - // Unfortunately, this is a terrible way to implement usage governors. if (Scale < 34U) // если масштаб до 34 PicassoRoutine1(); else if (Scale > 67U) // если масштаб больше 67 diff --git a/src/effects.cpp b/src/effects.cpp index ac01d14b3..3507b34ca 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -450,7 +450,11 @@ void LoadEffectFactories() ADD_EFFECT(EFFECT_MATRIX_SMNOISE, PatternSMNoise); ADD_EFFECT(EFFECT_MATRIX_SM2DDPR, PatternSM2DDPR); - ADD_EFFECT(EFFECT_MATRIX_SMPICASSO3IN1, PatternSMPicasso3in1); + // ADD_EFFECT(EFFECT_MATRIX_SMPICASSO3IN1, PatternSMPicasso3in1); + ADD_EFFECT(EFFECT_MATRIX_SMPICASSO_1, PatternSMPicasso3in1, "Picasso 1", 12); + ADD_EFFECT(EFFECT_MATRIX_SMPICASSO_2, PatternSMPicasso3in1, "Picasso 2", 38); + ADD_EFFECT(EFFECT_MATRIX_SMPICASSO_3, PatternSMPicasso3in1, "Picasso 3", 73); + ADD_EFFECT(EFFECT_MATRIX_SMAMBERRAIN, PatternSMAmberRain); ADD_EFFECT(EFFECT_MATRIX_SMSTROBE_DIFFUSION,PatternSMStrobeDiffusion); ADD_EFFECT(EFFECT_MATRIX_SMRAINBOW_TUNNEL, PatternSMRainbowTunnel);