From bc35ad5f2a2965cf60937cca95e1fdb7a227160b Mon Sep 17 00:00:00 2001 From: Ewoud Date: Sun, 18 Feb 2024 23:17:37 +0100 Subject: [PATCH] Fixture ProjectAndMap only per changed leds Object (doMap) AppEffects: setEffect: - void result, fixture.doMap and leds.doMap AppFixture && AppModFixture: projectAndMap - check on leds->doMap SysModModel: - add operator+, absx, *, / --- platformio.ini | 57 +++++++++++++++++++++++++++++++++++ src/App/AppEffects.h | 67 +++++++++++++++++++++-------------------- src/App/AppFixture.cpp | 16 ++++++---- src/App/AppFixture.h | 2 ++ src/App/AppLeds.h | 2 ++ src/App/AppModFixture.h | 7 ++++- src/App/AppModLeds.h | 23 +++++++------- src/Sys/SysModModel.h | 34 ++++++++++++++++----- 8 files changed, 149 insertions(+), 59 deletions(-) diff --git a/platformio.ini b/platformio.ini index 4d3dbd4b..e1a6e353 100644 --- a/platformio.ini +++ b/platformio.ini @@ -250,3 +250,60 @@ build_flags = ; .pio/libdeps/esp32dev/home-assistant-integration/src/device-types/../utils/HANumeric.h:232:18: warning: class 'HANumeric' is implicitly friends with itself ; friend class HANumeric; + + + + +;AsyncJson.h + + +; In file included from src/Sys/SysModWeb.cpp:22: +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h:86:25: warning: 'DynamicJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations] +; DynamicJsonDocument _jsonBuffer; +; ^~~~~~~~~~~ +; In file included from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.hpp:53, +; from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.h:9, +; from src/SysModule.h:23, +; from src/Sys/SysModWeb.h:13, +; from src/Sys/SysModWeb.cpp:12: +; .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson/compatibility.hpp:125:58: note: declared here +; class ARDUINOJSON_DEPRECATED("use JsonDocument instead") DynamicJsonDocument +; ^~~~~~~~~~~~~~~~~~~ +; In file included from src/Sys/SysModWeb.cpp:22: +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h: In constructor 'AsyncJsonResponse::AsyncJsonResponse(bool, size_t)': +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h:108:47: warning: 'ArduinoJson::V703PB2::JsonArray ArduinoJson::V703PB2::JsonDocument::createNestedArray()' is deprecated: use add() instead [-Wdeprecated-declarations] +; _root = _jsonBuffer.createNestedArray(); +; ^ +; In file included from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.hpp:33, +; from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.h:9, +; from src/SysModule.h:23, +; from src/Sys/SysModWeb.h:13, +; from src/Sys/SysModWeb.cpp:12: +; .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp:298:13: note: declared here +; JsonArray createNestedArray() { +; ^~~~~~~~~~~~~~~~~ +; In file included from src/Sys/SysModWeb.cpp:22: +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h:110:48: warning: 'ArduinoJson::V703PB2::JsonObject ArduinoJson::V703PB2::JsonDocument::createNestedObject()' is deprecated: use add() instead [-Wdeprecated-declarations] +; _root = _jsonBuffer.createNestedObject(); +; ^ +; In file included from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.hpp:33, +; from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.h:9, +; from src/SysModule.h:23, +; from src/Sys/SysModWeb.h:13, +; from src/Sys/SysModWeb.cpp:12: +; .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp:318:14: note: declared here +; JsonObject createNestedObject() { +; ^~~~~~~~~~~~~~~~~~ +; In file included from src/Sys/SysModWeb.cpp:22: +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h: In member function 'virtual void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest*)': +; .pio/libdeps/lolin_d32/ESPAsyncWebServerAircoookie/src/AsyncJson.h:218:39: warning: 'DynamicJsonDocument' is deprecated: use JsonDocument instead [-Wdeprecated-declarations] +; DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); +; ^ +; In file included from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.hpp:53, +; from .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson.h:9, +; from src/SysModule.h:23, +; from src/Sys/SysModWeb.h:13, +; from src/Sys/SysModWeb.cpp:12: +; .pio/libdeps/lolin_d32/ArduinoJson/src/ArduinoJson/compatibility.hpp:125:58: note: declared here +; class ARDUINOJSON_DEPRECATED("use JsonDocument instead") DynamicJsonDocument +; ^~~~~~~~~~~~~~~~~~~ diff --git a/src/App/AppEffects.h b/src/App/AppEffects.h index 129b18a4..e03a83d1 100644 --- a/src/App/AppEffects.h +++ b/src/App/AppEffects.h @@ -396,7 +396,7 @@ class DistortionWaves2D: public Effect { void loop(Leds &leds) { - uint8_t speed = mdl->getValue("Speed", leds.rowNr).as()/32; + uint8_t speed = mdl->getValue("speed", leds.rowNr).as()/32; uint8_t scale = mdl->getValue("scale", leds.rowNr).as()/32; uint8_t w = 2; @@ -438,7 +438,7 @@ class DistortionWaves2D: public Effect { } } void controls(JsonObject parentVar, Leds &leds) { - ui->initSlider(parentVar, "Speed", 128); + ui->initSlider(parentVar, "speed", 128); ui->initSlider(parentVar, "scale", 128); } }; // DistortionWaves2D @@ -460,7 +460,7 @@ class Octopus2D: public Effect { const uint8_t mapp = 180 / max(leds.size.x,leds.size.y); - uint8_t speed = mdl->getValue("Speed", leds.rowNr); + uint8_t speed = mdl->getValue("speed", leds.rowNr); uint8_t offsetX = mdl->getValue("Offset X", leds.rowNr); uint8_t offsetY = mdl->getValue("Offset Y", leds.rowNr); uint8_t legs = mdl->getValue("Legs", leds.rowNr); @@ -510,7 +510,7 @@ class Octopus2D: public Effect { } void controls(JsonObject parentVar, Leds &leds) { addPalette(parentVar, 4); - ui->initSlider(parentVar, "Speed", 128, 1, 255); //start with speed 1 + ui->initSlider(parentVar, "speed", 128, 1, 255); //start with speed 1 ui->initSlider(parentVar, "Offset X", 128); ui->initSlider(parentVar, "Offset Y", 128); ui->initSlider(parentVar, "Legs", 4, 1, 8); @@ -528,7 +528,7 @@ class Lissajous2D: public Effect { uint8_t freqX = mdl->getValue("X frequency", leds.rowNr); uint8_t fadeRate = mdl->getValue("Fade rate", leds.rowNr); - uint8_t speed = mdl->getValue("Speed", leds.rowNr); + uint8_t speed = mdl->getValue("speed", leds.rowNr); bool smooth = mdl->getValue("Smooth", leds.rowNr); CRGBPalette16 pal = getPalette(leds.rowNr); @@ -563,7 +563,7 @@ class Lissajous2D: public Effect { addPalette(parentVar, 4); ui->initSlider(parentVar, "X frequency", 64); ui->initSlider(parentVar, "Fade rate", 128); - ui->initSlider(parentVar, "Speed", 128); + ui->initSlider(parentVar, "speed", 128); ui->initCheckBox(parentVar, "Smooth", false); } }; // Lissajous2D @@ -689,7 +689,7 @@ class ScrollingText2D: public Effect { } void loop(Leds &leds) { - uint8_t speed = mdl->getValue("Speed", leds.rowNr); + uint8_t speed = mdl->getValue("speed", leds.rowNr); uint8_t font = mdl->getValue("font", leds.rowNr); const char * text = mdl->getValue("text", leds.rowNr); @@ -703,7 +703,7 @@ class ScrollingText2D: public Effect { } void controls(JsonObject parentVar, Leds &leds) { ui->initText(parentVar, "text", "StarMod"); - ui->initSlider(parentVar, "Speed", 128); + ui->initSlider(parentVar, "speed", 128); ui->initSelect(parentVar, "font", 0, false, [](JsonObject var, uint8_t rowNr, uint8_t funType) { switch (funType) { //varFun case f_UIFun: { JsonArray options = ui->setOptions(var); @@ -1033,7 +1033,7 @@ class FreqMatrix:public Effect { uint8_t *aux0 = sharedData.bind(); if (!sharedData.allocated()) return; - uint8_t speed = mdl->getValue("Speed", leds.rowNr); + uint8_t speed = mdl->getValue("speed", leds.rowNr); uint8_t fx = mdl->getValue("Sound effect", leds.rowNr); uint8_t lowBin = mdl->getValue("Low bin", leds.rowNr); uint8_t highBin = mdl->getValue("High bin", leds.rowNr); @@ -1073,7 +1073,7 @@ class FreqMatrix:public Effect { } void controls(JsonObject parentVar, Leds &leds) { - ui->initSlider(parentVar, "Speed", 255); + ui->initSlider(parentVar, "speed", 255); ui->initSlider(parentVar, "Sound effect", 128); ui->initSlider(parentVar, "Low bin", 18); ui->initSlider(parentVar, "High bin", 48); @@ -1163,8 +1163,7 @@ class Effects { EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow } - bool setEffect(Leds &leds, JsonObject var, uint8_t rowNr) { - bool doMap = false; + void setEffect(Leds &leds, JsonObject var, uint8_t rowNr) { leds.fx = mdl->getValue(var, rowNr); @@ -1172,26 +1171,6 @@ class Effects { if (leds.fx < effects.size()) { - //tbd: make property of effects - if (strstr(effects[leds.fx]->name(), "2D")) { - if (leds.effectDimension != 2) { - leds.effectDimension = 2; - doMap = true; - } - } - else if (strstr(effects[leds.fx]->name(), "3D")) { - if (leds.effectDimension != 3) { - leds.effectDimension = 3; - doMap = true; - } - } - else { - if (leds.effectDimension != 1) { - leds.effectDimension = 1; - doMap = true; - } - } - sharedData.clear(); //make sure all values are 0 for (JsonObject var: var["n"].as()) { //for all controls @@ -1258,9 +1237,31 @@ class Effects { // } //remove vars with all values -99 + //tbd: make property of effects + if (strstr(effects[leds.fx]->name(), "2D")) { + if (leds.effectDimension != 2) { + leds.effectDimension = 2; + leds.doMap = true; + leds.fixture->doMap = true; + } + } + else if (strstr(effects[leds.fx]->name(), "3D")) { + if (leds.effectDimension != 3) { + leds.effectDimension = 3; + leds.doMap = true; + leds.fixture->doMap = true; + } + } + else { + if (leds.effectDimension != 1) { + leds.effectDimension = 1; + leds.doMap = true; + leds.fixture->doMap = true; + } + } + } // fx < size - return doMap; } }; \ No newline at end of file diff --git a/src/App/AppFixture.cpp b/src/App/AppFixture.cpp index 0e4613b7..ab7dc802 100644 --- a/src/App/AppFixture.cpp +++ b/src/App/AppFixture.cpp @@ -23,7 +23,7 @@ if (files->seqNrToName(fileName, fixtureNr)) { JsonRDWS jrdws(fileName); //open fileName for deserialize - for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end(); ++leds) { + for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end() && leds->doMap; ++leds) { //vectors really gone now? for (std::vector> ::iterator physMap=leds->mappingTable.begin(); physMap!=leds->mappingTable.end(); ++physMap) physMap->clear(); @@ -73,7 +73,7 @@ // for (Leds leds:ledsList) { //vector iterator needed to get the pointer to leds as we need to update leds, also vector iteration on classes is faster!!! //search: ^(?=.*\bfor\b)(?=.*\b:\b).*$ - for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end(); ++leds) { + for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end() && leds->doMap; ++leds) { Coord3D startPosAdjusted = (leds->startPos).minimum(size - Coord3D{1,1,1}) ; Coord3D endPosAdjusted = (leds->endPos).minimum(size - Coord3D{1,1,1}) ; @@ -230,7 +230,7 @@ if (indexV != UINT16_MAX) { //can be nulled by inverse mapping //add physical tables if not present if (indexV >= NUM_LEDS_Max / 2) { - USER_PRINTF("dev mapping add physMap %d>=%d (%d) too big %d\n", indexV, NUM_LEDS_Max, leds->mappingTable.size(), UINT16_MAX); + USER_PRINTF("dev mapping add physMap %d>=%d/2 (V:%d) too big\n", indexV, NUM_LEDS_Max, leds->mappingTable.size()); } else { //create new physMaps if needed @@ -288,14 +288,15 @@ if (jrdws.deserialize(false)) { //this will call above function parameter for each led uint8_t rowNr = 0; - for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end(); ++leds) { + for (std::vector::iterator leds=ledsList.begin(); leds!=ledsList.end() && leds->doMap; ++leds) { + USER_PRINTF("leds loop %d %d\n", leds->rowNr, leds->fx); if (leds->projectionNr <= p_Random) { //defaults leds->size = size; leds->nrOfLeds = nrOfLeds; } - if (leds->projectionNr > p_Random) { + else if (leds->projectionNr > p_Random) { if (leds->mappingTable.size() < leds->size.x * leds->size.y * leds->size.z) USER_PRINTF("mapping add extra physMap %d of %d %d,%d,%d\n", leds->mappingTable.size(), leds->size.x * leds->size.y * leds->size.z, leds->size.x, leds->size.y, leds->size.z); @@ -326,11 +327,12 @@ USER_PRINTF("projectAndMap V:%dx%dx%d = %d\n", leds->size.x, leds->size.y, leds->size.z, leds->nrOfLeds); - mdl->setValueV("fxSize", rowNr, "%d x %d x %d = %d", leds->size.x, leds->size.y, leds->size.z, leds->nrOfLeds); + mdl->setValueV("fxSize", leds->rowNr, "%d x %d x %d = %d", leds->size.x, leds->size.y, leds->size.z, leds->nrOfLeds); USER_PRINTF("leds[%d].size = %d + %d\n", leds->rowNr, sizeof(Leds), leds->mappingTable.size()); //44 rowNr++; + leds->doMap = false; } // leds USER_PRINTF("projectAndMap P:%dx%dx%d = %d\n", size.x, size.y, size.z, nrOfLeds); @@ -342,4 +344,6 @@ } //if fileName else USER_PRINTF("projectAndMap: Filename for fixture %d not found\n", fixtureNr); + + doMap = false; } \ No newline at end of file diff --git a/src/App/AppFixture.h b/src/App/AppFixture.h index 6eda9281..6320a61b 100644 --- a/src/App/AppFixture.h +++ b/src/App/AppFixture.h @@ -65,6 +65,8 @@ class Fixture { //variables for json Scan // uint16_t prevIndexP; //track pins and leds + + bool doMap = false; //load fixture json file, parse it and depending on the projection, create a mapping for it void projectAndMap(); diff --git a/src/App/AppLeds.h b/src/App/AppLeds.h index 4c9decdb..52665c71 100644 --- a/src/App/AppLeds.h +++ b/src/App/AppLeds.h @@ -62,6 +62,8 @@ class Leds { uint16_t indexVLocal = 0; //set in operator[], used by operator= + bool doMap = false; + Leds(uint8_t rowNr, Fixture &fixture) { USER_PRINTF("Leds[%d] constructor\n", rowNr); this->rowNr = rowNr; diff --git a/src/App/AppModFixture.h b/src/App/AppModFixture.h index 44f55eea..d9146925 100644 --- a/src/App/AppModFixture.h +++ b/src/App/AppModFixture.h @@ -99,7 +99,12 @@ class AppModFixture:public SysModule { case f_ChangeFun: { lds->fixture.fixtureNr = var["value"]; - lds->doMap = true; + lds->fixture.doMap = true; + + //remap all leds + for (std::vector::iterator leds=lds->fixture.ledsList.begin(); leds!=lds->fixture.ledsList.end(); ++leds) { + leds->doMap = true; + } char fileName[32] = ""; if (files->seqNrToName(fileName, lds->fixture.fixtureNr)) { diff --git a/src/App/AppModLeds.h b/src/App/AppModLeds.h index 3cda06f2..fddc25c9 100644 --- a/src/App/AppModLeds.h +++ b/src/App/AppModLeds.h @@ -47,7 +47,6 @@ class AppModLeds:public SysModule { uint16_t fps = 60; unsigned long lastMappingMillis = 0; - bool doMap = false; Effects effects; Fixture fixture = Fixture(); @@ -108,11 +107,10 @@ class AppModLeds:public SysModule { } case f_ChangeFun: if (rowNr < fixture.ledsList.size()) { - doMap = effects.setEffect(fixture.ledsList[rowNr], var, rowNr); + effects.setEffect(fixture.ledsList[rowNr], var, rowNr); web->addResponse("details", "var", var); web->addResponse("details", "rowNr", rowNr); - } return true; default: return false; @@ -144,7 +142,8 @@ class AppModLeds:public SysModule { fixture.ledsList[rowNr].projectionNr = mdl->getValue(var, rowNr); USER_PRINTF("chFun pro[%d] <- %d (%d)\n", rowNr, fixture.ledsList[rowNr].projectionNr, fixture.ledsList.size()); - doMap = true; + fixture.ledsList[rowNr].doMap = true; + fixture.doMap = true; } return true; default: return false; @@ -167,12 +166,12 @@ class AppModLeds:public SysModule { USER_PRINTF("fxStart[%d] chFun %d,%d,%d\n", rowNr, fixture.ledsList[rowNr].startPos.x, fixture.ledsList[rowNr].startPos.y, fixture.ledsList[rowNr].startPos.z); fixture.ledsList[rowNr].fadeToBlackBy(); + fixture.ledsList[rowNr].doMap = true; + fixture.doMap = true; } else { USER_PRINTF("fxStart[%d] chfun rownr not in range > %d\n", rowNr, fixture.ledsList.size()); } - - doMap = true; return true; default: return false; }}); @@ -193,12 +192,12 @@ class AppModLeds:public SysModule { USER_PRINTF("fxEnd[%d] chFun %d,%d,%d\n", rowNr, fixture.ledsList[rowNr].endPos.x, fixture.ledsList[rowNr].endPos.y, fixture.ledsList[rowNr].endPos.z); fixture.ledsList[rowNr].fadeToBlackBy(); + fixture.ledsList[rowNr].doMap = true; + fixture.doMap = true; } else { USER_PRINTF("fxEnd[%d] chfun rownr not in range > %d\n", rowNr, fixture.ledsList.size()); } - - doMap = true; return true; default: return false; }}); @@ -289,6 +288,8 @@ class AppModLeds:public SysModule { const char * canvasData = var["canvasData"]; //0 - 494 - 140,150,0 USER_PRINTF("AppModLeds loop canvasData %s\n", canvasData); + //currently only leds[0] supported + fixture.ledsList[0].fadeToBlackBy(); char * token = strtok((char *)canvasData, ":"); @@ -306,13 +307,13 @@ class AppModLeds:public SysModule { mdl->setValue(isStart?"fxStart":"fxEnd", *startOrEndPos, 0); //assuming row 0 for the moment var.remove("canvasData"); //convasdata has been processed - doMap = true; //recalc projection + fixture.ledsList[0].doMap = true; //recalc projection + fixture.doMap = true; } //update projection - if (millis() - lastMappingMillis >= 1000 && doMap) { //not more then once per second (for E131) + if (millis() - lastMappingMillis >= 1000 && fixture.doMap) { //not more then once per second (for E131) lastMappingMillis = millis(); - doMap = false; fixture.projectAndMap(); //https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples diff --git a/src/Sys/SysModModel.h b/src/Sys/SysModModel.h index b095215e..87df11bd 100644 --- a/src/Sys/SysModModel.h +++ b/src/Sys/SysModModel.h @@ -51,23 +51,41 @@ struct Coord3D { //assignments Coord3D operator=(Coord3D rhs) { - USER_PRINTF("Coord3D assign %d,%d,%d\n", rhs.x, rhs.y, rhs.z); - this->x = rhs.x; - this->y = rhs.y; - this->z = rhs.z; + // USER_PRINTF("Coord3D assign %d,%d,%d\n", rhs.x, rhs.y, rhs.z); + x = rhs.x; + y = rhs.y; + z = rhs.z; return *this; } Coord3D operator-=(Coord3D rhs) { - this->x -= rhs.x; - this->y -= rhs.y; - this->z -= rhs.z; + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; return *this; } Coord3D operator-(Coord3D rhs) { return Coord3D{uint16_t(x - rhs.x), uint16_t(y - rhs.y), uint16_t(z - rhs.z)}; } + Coord3D operator+(Coord3D rhs) { + return Coord3D{uint16_t(x + rhs.x), uint16_t(y + rhs.y), uint16_t(z + rhs.z)}; + // return Coord3D{x + rhs.x, y + rhs.y, z + rhs.z}; + } Coord3D minimum(Coord3D rhs) { - return Coord3D{min(x, rhs.x), min(y, rhs.y), min(this->z, rhs.z)}; + return Coord3D{min(x, rhs.x), min(y, rhs.y), min(z, rhs.z)}; + } + Coord3D absx() { + x = abs(x); + y = abs(y); + z = abs(z); + return *this; + } + Coord3D operator*(uint8_t rhs) { + return Coord3D{uint16_t(x * rhs), uint16_t(y * rhs), uint16_t(z * rhs)}; + // return Coord3D{x + rhs.x, y + rhs.y, z + rhs.z}; + } + Coord3D operator/(uint8_t rhs) { + return Coord3D{uint16_t(x / rhs), uint16_t(y / rhs), uint16_t(z / rhs)}; + // return Coord3D{x + rhs.x, y + rhs.y, z + rhs.z}; } };