diff --git a/wled00/FX.h b/wled00/FX.h index 9fd3a04d8a..ac25ec4795 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -409,7 +409,8 @@ typedef enum mapping1D2D { M12_pBar = 1, M12_pArc = 2, M12_pCorner = 3, - M12_sPinwheel = 4 + M12_sPinwheel = 4, + M12_Cube = 5 } mapping1D2D_t; class WS2812FX; @@ -546,6 +547,7 @@ class Segment { // transition functions void stopTransition(); // ends transition mode by destroying transition structure (does nothing if not in transition) void updateTransitionProgress() const; // sets transition progress (0-65535) based on time passed since transition start + void applyCubeWrapping(int &x, int &y) const; inline void handleTransition() { updateTransitionProgress(); if (isInTransition() && progress() == 0xFFFFU) stopTransition(); @@ -826,6 +828,7 @@ class WS2812FX { now(millis()), timebase(0), isMatrix(false), + isCube(false), #ifdef WLED_AUTOSEGMENTS autoSegments(true), #else @@ -1007,6 +1010,7 @@ class WS2812FX { bool autoSegments : 1; bool correctWB : 1; bool cctFromRgb : 1; + bool isCube : 1; }; Segment *_currentSegment; diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index a0cc3c4461..ff5f2300bf 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -185,9 +185,47 @@ bool Segment::isPixelXYClipped(int x, int y) const { return false; } +void Segment::applyCubeWrapping(int &x, int &y) const +{ + // AI: below section was generated by an AI + if (!strip.isCube || map1D2D != M12_Cube) return; + const uint16_t vH = vHeight(); + const uint16_t vW = vWidth(); + if (vH % 3 != 0 || vW != (vH / 3) * 4) return; + + int n = vH / 3; + int fx = (x >= 0) ? (x / n) : -1; + int fy = (y >= 0) ? (y / n) : -1; + int u = (x % n + n) % n; + int v = (y % n + n) % n; + + if (fy < 0 || fy > 2) { // Above Top or Below Bottom + x = 4 * n - 1 - u; + y = 2 * n - 1 - v; + } else if (fy == 0) { + if (fx == 0) { // Top-Left gap -> maps to Top face left edge + x = n + (n - 1 - v); y = u; + } else if (fx == 2) { // Top-Right gap -> maps to Top face right edge + x = n + v; y = n - 1 - u; + } else if (fx != 1) { // fx == 3 (Top-Back gap) -> maps to Top face top edge + x = 2 * n - 1 - u; y = n - 1 - v; + } + } else if (fy == 2) { + if (fx == 0) { // Bottom-Left gap -> maps to Bottom face left edge + x = n + v; y = 3 * n - 1 - u; + } else if (fx == 2) { // Bottom-Right gap -> maps to Bottom face right edge + x = 2 * n - 1 - v; y = 2 * n + u; + } else if (fx != 1) { // fx == 3 (Bottom-Back gap) -> maps to Bottom face bottom edge + x = 2 * n - 1 - u; y = 3 * n - 1 - v; + } + } + // AI: end +} + void IRAM_ATTR_YN Segment::setPixelColorXY(int x, int y, uint32_t col) const { if (!isActive()) return; // not active + if (strip.isCube && map1D2D == M12_Cube) applyCubeWrapping(x, y); if ((unsigned)x >= vWidth() || (unsigned)y >= vHeight()) return; // if pixel would fall out of virtual segment just exit setPixelColorXYRaw(x, y, col); } @@ -238,6 +276,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) const // returns RGBW values of pixel uint32_t IRAM_ATTR_YN Segment::getPixelColorXY(int x, int y) const { if (!isActive()) return 0; // not active + if (strip.isCube && map1D2D == M12_Cube) applyCubeWrapping(x, y); if ((unsigned)x >= vWidth() || (unsigned)y >= vHeight()) return 0; // if pixel would fall out of virtual segment just exit return getPixelColorXYRaw(x,y); } diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 2e458e7da9..b72ef3dc63 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -186,6 +186,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonObject matrix = hw_led[F("matrix")]; if (!matrix.isNull()) { strip.isMatrix = true; + CJSON(strip.isCube, matrix["isCube"]); unsigned numPanels = matrix[F("mpc")] | 1; numPanels = constrain(numPanels, 1, WLED_MAX_PANELS); strip.panel.clear(); @@ -954,6 +955,7 @@ void serializeConfig(JsonObject root) { // 2D Matrix Settings if (strip.isMatrix) { JsonObject matrix = hw_led.createNestedObject(F("matrix")); + matrix["isCube"] = strip.isCube; matrix[F("mpc")] = strip.panel.size(); JsonArray panels = matrix.createNestedArray(F("panels")); for (size_t i = 0; i < strip.panel.size(); i++) { diff --git a/wled00/data/index.js b/wled00/data/index.js index ee5126973c..cd4e4971df 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -796,6 +796,7 @@ function populateSegments(s) ``+ ``+ ``+ + ``+ ``+ ``; let blend = `