From 81280c5001581e3bbc95c208f0d75f1ef8b93e12 Mon Sep 17 00:00:00 2001 From: Ewoud Date: Wed, 19 Jun 2024 16:42:45 +0200 Subject: [PATCH] Create projection classes LedModEffects: - add projections vector and init - pro.uiFun: use projections vector for names - pro.chFun: call projection.controls Add LedProjections - One class for each projection - move ui variables to class.controls --- src/App/LedEffects.h | 2 +- src/App/LedLeds.h | 4 +- src/App/LedModEffects.h | 113 ++++++---------------- src/App/LedProjections.h | 204 +++++++++++++++++++++++++++++++++++++++ src/main.cpp | 2 +- 5 files changed, 240 insertions(+), 85 deletions(-) create mode 100644 src/App/LedProjections.h diff --git a/src/App/LedEffects.h b/src/App/LedEffects.h index e8dbbbc0..4f0a4feb 100644 --- a/src/App/LedEffects.h +++ b/src/App/LedEffects.h @@ -1263,7 +1263,7 @@ class ScrollingText: public Effect { // tbd: this should be removed and fx.changeFUn (setEffect) must make sure this cannot happen!! if (text && strlen(text)>0) { leds.fadeToBlackBy(); - leds.drawText(text, 0, 0, font, CRGB::Red, - (sys->now/25*speed/256)); + leds.drawText(text, 0, 0, font, CRGB::Red, - (sys->now/25*speed/256)); //instead of call } } diff --git a/src/App/LedLeds.h b/src/App/LedLeds.h index cb3cfd7a..01518cfb 100644 --- a/src/App/LedLeds.h +++ b/src/App/LedLeds.h @@ -140,6 +140,7 @@ class SharedData { index = 0; } + //sets the sharedData pointer back to 0 so loop effect can go through it void loop() { index = 0; } @@ -240,10 +241,9 @@ struct PhysMap { if (!isMultipleIndexes()) //check if pointer is not setting the type[3] value ppf("dev new PhysMap type:%d t3:%d b:%d p:%p\n", type, type[3], type[3] & 0x80, indexes); - if (isMultipleIndexes()) { + else { indexes->push_back(oldIndex); //add the old to the indexes vector } - } if (isMultipleIndexes()) { diff --git a/src/App/LedModEffects.h b/src/App/LedModEffects.h index 1b16cd56..f8435b3e 100644 --- a/src/App/LedModEffects.h +++ b/src/App/LedModEffects.h @@ -13,6 +13,7 @@ #include "LedFixture.h" #include "LedEffects.h" +#include "LedProjections.h" // #define FASTLED_RGBW @@ -35,12 +36,16 @@ class LedModEffects:public SysModule { unsigned long lastMappingMillis = 0; std::vector effects; + std::vector projections; Fixture fixture = Fixture(); bool fShow = true; LedModEffects() :SysModule("Effects") { + + //load effects + //1D Basis effects.push_back(new SolidEffect); // 1D FastLed @@ -90,6 +95,18 @@ class LedModEffects:public SysModule { //3D effects.push_back(new RipplesEffect); effects.push_back(new SphereMoveEffect); + + //load projections + projections.push_back(new DefaultProjection); + projections.push_back(new MultiplyProjection); + projections.push_back(new TiltPanRollProjection); + projections.push_back(new DistanceFromPointProjection); + projections.push_back(new Preset1Projection); + projections.push_back(new NoneProjection); + projections.push_back(new RandomProjection); + projections.push_back(new ReverseProjection); + projections.push_back(new MirrorProjection); + projections.push_back(new KaleidoscopeProjection); }; void setup() { @@ -178,8 +195,8 @@ class LedModEffects:public SysModule { print->printVar(var); ppf("\n"); - if (effects[leds->fx]->dim() != leds->effectDimension) { - leds->effectDimension = effects[leds->fx]->dim(); + if (effect->dim() != leds->effectDimension) { + leds->effectDimension = effect->dim(); leds->doMap = true; leds->fixture->doMap = true; } @@ -199,17 +216,16 @@ class LedModEffects:public SysModule { case f_UIFun: { ui->setLabel(var, "Projection"); ui->setComment(var, "How to project fx"); - JsonArray options = ui->setOptions(var); // see enum Projections in LedFixture.h and keep the same order ! - options.add("Default"); - options.add("Multiply"); - options.add("TiltPanRoll"); - options.add("Distance ⌛"); - options.add("Preset 1"); - options.add("None"); - options.add("Random"); - options.add("Mirror WIP"); - options.add("Reverse WIP"); - // options.add("Kaleidoscope WIP"); + + JsonArray options = ui->setOptions(var); + for (Projection *projection:projections) { + char buf[32] = ""; + strcat(buf, projection->name()); + strcat(buf, projection->dim()==_1D?" ┊":projection->dim()==_2D?" ▦":" 🧊"); + strcat(buf, " "); + strcat(buf, projection->tags()); + options.add(JsonString(buf, JsonString::Copied)); //copy! + } return true; } case f_ChangeFun: @@ -221,75 +237,10 @@ class LedModEffects:public SysModule { stackUnsigned8 proValue = mdl->getValue(var, rowNr); fixture.listOfLeds[rowNr]->projectionNr = proValue; + Projection* projection = projections[proValue]; + mdl->varPreDetails(var, rowNr); //set all positive var N orders to negative - if (proValue == p_DistanceFromPoint || proValue == p_Preset1) { - ui->initCoord3D(var, "proCenter", Coord3D{8,8,8}, 0, NUM_LEDS_Max, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Center"); - return true; - case f_ChangeFun: - //initiate projectAndMap - ppf("proCenter %d %d\n", rowNr, fixture.listOfLeds.size()); - if (rowNr < fixture.listOfLeds.size()) { - fixture.listOfLeds[rowNr]->doMap = true; //Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled. - fixture.doMap = true; - } - // ui->setLabel(var, "Size"); - return true; - default: return false; - }}); - } - if (proValue == p_Multiply || proValue == p_Preset1) { - ui->initCoord3D(var, "proMulti", Coord3D{2,2,1}, 0, 10, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Multiply"); - return true; - case f_ChangeFun: - ui->initCheckBox(var, "mirror", false, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ChangeFun: - if (rowNr < fixture.listOfLeds.size()) { - fixture.listOfLeds[rowNr]->doMap = true; - fixture.doMap = true; - } - return true; - default: return false; - }}); - if (rowNr < fixture.listOfLeds.size()) { - fixture.listOfLeds[rowNr]->doMap = true; - fixture.doMap = true; - } - return true; - default: return false; - }}); - } - if (proValue == p_TiltPanRoll || proValue == p_Preset1) { - ui->initSlider(var, "proTilt", 128, 0, 254, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ChangeFun: - if (rowNr < fixture.listOfLeds.size()) - fixture.listOfLeds[rowNr]->proTiltSpeed = mdl->getValue(var, rowNr); - return true; - default: return false; - }}); - ui->initSlider(var, "proPan", 128, 0, 254, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_ChangeFun: - if (rowNr < fixture.listOfLeds.size()) - fixture.listOfLeds[rowNr]->proPanSpeed = mdl->getValue(var, rowNr); - return true; - default: return false; - }}); - } - if (proValue == p_Preset1 || proValue == p_TiltPanRoll) { - ui->initSlider(var, "proRoll", 128, 0, 254, false, [this](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun - case f_UIFun: - ui->setLabel(var, "Roll speed"); - return true; - case f_ChangeFun: - if (rowNr < fixture.listOfLeds.size()) - fixture.listOfLeds[rowNr]->proRollSpeed = mdl->getValue(var, rowNr); - return true; - default: return false; - }}); - } + projection->controls(*fixture.listOfLeds[rowNr], var); mdl->varPostDetails(var, rowNr); // ppf("chFun pro[%d] <- %d (%d)\n", rowNr, proValue, fixture.listOfLeds.size()); diff --git a/src/App/LedProjections.h b/src/App/LedProjections.h new file mode 100644 index 00000000..aa73397b --- /dev/null +++ b/src/App/LedProjections.h @@ -0,0 +1,204 @@ +/* + @title StarLeds + @file LedProjections.h + @date 20240228 + @repo https://github.com/MoonModules/StarLeds + @Authors https://github.com/MoonModules/StarLeds/commits/main + @Copyright © 2024 Github StarLeds Commit Authors + @license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + @license For non GPL-v3 usage, commercial licenses must be purchased. Contact moonmodules@icloud.com +*/ + +//should not contain variables/bytes to keep mem as small as possible!! +class Projection { +public: + virtual const char * name() {return "noname";} + virtual const char * tags() {return "";} + virtual uint8_t dim() {return _1D;}; + + virtual void step1(Fixture &fixture) {} + + virtual void controls(Leds &leds, JsonObject parentVar) {} + +}; + +class DefaultProjection: public Projection { + const char * name() {return "Default";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void step1(Leds &leds) { + } + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //DefaultProjection + +class MultiplyProjection: public Projection { + const char * name() {return "Multiply";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void adjustSizeAndPixel(Coord3D &sizeAdjusted, Coord3D &pixelAdjusted) { + Coord3D proMulti; + // proMulti = mdl->getValue("proMulti", rowNr); + // //promultu can be 0,0,0 but /= protects from /div0 + // sizeAdjusted /= proMulti; sizeAdjusted = sizeAdjusted.maximum(Coord3D{1,1,1}); //size min 1,1,1 + // proCenter /= proMulti; + // mirrors = pixelAdjusted / sizeAdjusted; //place the pixel in the right quadrant + // pixelAdjusted = pixelAdjusted%sizeAdjusted; // pixel % size + } + + public: //to use in Preset1Projection + void controls(Leds &leds, JsonObject parentVar) { + ui->initCoord3D(parentVar, "proMulti", Coord3D{3,3,1}, 0, 10, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_UIFun: + ui->setLabel(var, "MultiplyX"); + return true; + case f_ChangeFun: + ui->initCheckBox(var, "mirror", false, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_ChangeFun: + if (rowNr < leds.fixture->listOfLeds.size()) { + leds.fixture->listOfLeds[rowNr]->doMap = true; + leds.fixture->doMap = true; + } + return true; + default: return false; + }}); + if (rowNr < leds.fixture->listOfLeds.size()) { + leds.fixture->listOfLeds[rowNr]->doMap = true; + leds.fixture->doMap = true; + } + return true; + default: return false; + }}); + } +}; //MultiplyProjection + +class TiltPanRollProjection: public Projection { + const char * name() {return "TiltPanRoll";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + public: //to use in Preset1Projection + void controls(Leds &leds, JsonObject parentVar) { + ui->initSlider(parentVar, "proTilt", 128, 0, 254, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_ChangeFun: + if (rowNr < leds.fixture->listOfLeds.size()) + leds.fixture->listOfLeds[rowNr]->proTiltSpeed = mdl->getValue(var, rowNr); + return true; + default: return false; + }}); + ui->initSlider(parentVar, "proPan", 128, 0, 254, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_ChangeFun: + if (rowNr < leds.fixture->listOfLeds.size()) + leds.fixture->listOfLeds[rowNr]->proPanSpeed = mdl->getValue(var, rowNr); + return true; + default: return false; + }}); + ui->initSlider(parentVar, "proRoll", 128, 0, 254, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_UIFun: + ui->setLabel(var, "Roll speed"); + return true; + case f_ChangeFun: + if (rowNr < leds.fixture->listOfLeds.size()) + leds.fixture->listOfLeds[rowNr]->proRollSpeed = mdl->getValue(var, rowNr); + return true; + default: return false; + }}); + } +}; //TiltPanRollProjection + +class DistanceFromPointProjection: public Projection { + const char * name() {return "Distance ⌛";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + public: //to use in Preset1Projection + void controls(Leds &leds, JsonObject parentVar) { + ui->initCoord3D(parentVar, "proCenter", Coord3D{8,8,8}, 0, NUM_LEDS_Max, false, [leds](JsonObject var, unsigned8 rowNr, unsigned8 funType) { switch (funType) { //varFun + case f_UIFun: + ui->setLabel(var, "Center"); + return true; + case f_ChangeFun: + //initiate projectAndMap + ppf("proCenter %d %d\n", rowNr, leds.fixture->listOfLeds.size()); + if (rowNr < leds.fixture->listOfLeds.size()) { + leds.fixture->listOfLeds[rowNr]->doMap = true; //Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled. + leds.fixture->doMap = true; + } + // ui->setLabel(var, "Size"); + return true; + default: return false; + }}); + } +}; //DistanceFromPointProjection + +class Preset1Projection: public Projection { + const char * name() {return "Preset1";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + DistanceFromPointProjection dp; + dp.controls(leds, parentVar); + MultiplyProjection mp; + mp.controls(leds, parentVar); + TiltPanRollProjection tp; + tp.controls(leds, parentVar); + } +}; //Preset1Projection + +class NoneProjection: public Projection { + const char * name() {return "None";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //NoneProjection + +class RandomProjection: public Projection { + const char * name() {return "Random";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //RandomProjection + +class ReverseProjection: public Projection { + const char * name() {return "Reverse WIP";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //ReverseProjection + +class MirrorProjection: public Projection { + const char * name() {return "Mirror WIP";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //MirrorProjection + +class KaleidoscopeProjection: public Projection { + const char * name() {return "Kaleidoscope WIP";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //KaleidoscopeProjection + +class TestProjection: public Projection { + const char * name() {return "Test";} + uint8_t dim() {return _1D;} + const char * tags() {return "💡";} + + void controls(Leds &leds, JsonObject parentVar) { + } +}; //TestProjection \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8c2ac810..ba1d891b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,7 +76,7 @@ void setup() { instances = new SysModInstances(); mdns = new UserModMDNS(); #ifdef STARLEDS - eff= new LedModEffects(); + eff = new LedModEffects(); fix = new LedModFixture(); lfg = new LedModFixtureGen(); #ifdef STARLEDS_USERMOD_ARTNET