diff --git a/animation_collection.ino b/ANIMartRIX.h similarity index 86% rename from animation_collection.ino rename to ANIMartRIX.h index e90240d..707ab5a 100644 --- a/animation_collection.ino +++ b/ANIMartRIX.h @@ -1,8 +1,455 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ + +#include +#include + +#define num_oscillators 10 + + +struct render_parameters { + + // TODO float center_x = (num_x / 2) - 0.5; // center of the matrix + // TODO float center_y = (num_y / 2) - 0.5; + float center_x = (999 / 2) - 0.5; // center of the matrix + float center_y = (999 / 2) - 0.5; + float dist, angle; + float scale_x = 0.1; // smaller values = zoom in + float scale_y = 0.1; + float scale_z = 0.1; + float offset_x, offset_y, offset_z; + float z; + float low_limit = 0; // getting contrast by highering the black point + float high_limit = 1; +}; + +render_parameters animation; // all animation parameters in one place +struct oscillators { + + float master_speed; // global transition speed + float offset[num_oscillators]; // oscillators can be shifted by a time offset + float ratio[num_oscillators]; // speed ratios for the individual oscillators +}; + +oscillators timings; // all speed settings in one place + +struct modulators { + + float linear[num_oscillators]; // returns 0 to FLT_MAX + float radial[num_oscillators]; // returns 0 to 2*PI + float directional[num_oscillators]; // returns -1 to 1 + float noise_angle[num_oscillators]; // returns 0 to 2*PI +}; + +modulators move; // all oscillator based movers and shifters at one place + +struct rgb { + + float red, green, blue; +}; + +rgb pixel; + +static const byte pNoise[] = { 151,160,137,91,90, 15,131, 13,201,95,96, +53,194,233, 7,225,140,36,103,30,69,142, 8,99,37,240,21,10,23,190, 6, +148,247,120,234,75, 0,26,197,62,94,252,219,203,117, 35,11,32,57,177, +33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139, +48,27,166, 77,146,158,231,83,111,229,122, 60,211,133,230,220,105,92, +41,55,46,245,40,244,102,143,54,65,25,63,161, 1,216,80,73,209,76,132, +187,208, 89, 18,169,200,196,135,130,116,188,159, 86,164,100,109,198, +173,186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85, +212,207,206, 59,227, 47,16,58,17,182,189, 28,42,223,183,170,213,119, +248,152,2,44,154,163,70,221,153,101,155,167,43,172, 9,129,22,39,253, +19,98,108,110,79,113,224,232,178,185,112,104,218,246, 97,228,251,34, +242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107, +49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4, +150,254,138,236,205, 93,222,114, 67,29,24, 72,243,141,128,195,78,66, +215,61,156,180 +}; + + + +class ANIMartRIX { + +public: + +int num_x; // how many LEDs are in one row? +int num_y; // how many rows? + +float speed_factor = 1; // 0.1 to 10 + +float radial_filter_radius = 23.0; // on 32x32, use 11 for 16x16 + +bool serpentine; + +std::vector> polar_theta; // look-up table for polar angles +std::vector> distance; // look-up table for polar distances + +unsigned long a, b, c; // for time measurements + + + + +float show1, show2, show3, show4, show5, show6, show7, show8, show9, show0; + +ANIMartRIX() {} + +ANIMartRIX(int w, int h, bool serpentine) { + this->init(w, h, serpentine); +} + +void init(int w, int h, bool serpentine) { + this->num_x = w; + this->num_y = h; + this->serpentine = serpentine; + if(w <= 16) { + this->radial_filter_radius = 11; + } + else { + this->radial_filter_radius = 23; // on 32x32, use 11 for 16x16 + } + render_polar_lookup_table((num_x / 2) - 0.5, (num_y / 2) - 0.5); // precalculate all polar coordinates + // polar origin is set to matrix centre + + timings.master_speed = 0.01; // set default speed ratio for the oscillators, not all effects set their own, so start from know state + +} + +/** + * @brief Set the Speed Factor 0.1 to 10 - 1 for original speed + * + * @param speed + */ +void setSpeedFactor(float speed) { + this->speed_factor = speed; +} + +// Dynamic darkening methods: + +float subtract(float &a, float&b) { + + return a - b; +} + + +float multiply(float &a, float&b) { + + return a * b / 255.f; +} + + +// makes low brightness darker +// sets the black point high = more contrast +// animation.low_limit should be 0 for best results +float colorburn(float &a, float&b) { + + return (1-((1-a/255.f) / (b/255.f)))*255.f; +} + + +// Dynamic brightening methods + +float add(float &a, float&b) { + + return a + b; +} + + +// makes bright even brighter +// reduces contrast +float screen(float &a, float&b) { + + return (1 - (1 - a/255.f) * (1 - b/255.f))*255.f; +} + + +float colordodge(float &a, float&b) { + + return (a/(255.f-b)) * 255.f; +} +/* + Ken Perlins improved noise - http://mrl.nyu.edu/~perlin/noise/ + C-port: http://www.fundza.com/c4serious/noise/perlin/perlin.html + by Malcolm Kesson; arduino port by Peter Chiochetti, Sep 2007 : + - make permutation constant byte, obsoletes init(), lookup % 256 +*/ + +float fade(float t){ return t * t * t * (t * (t * 6 - 15) + 10); } +float lerp(float t, float a, float b){ return a + t * (b - a); } +float grad(int hash, float x, float y, float z) +{ +int h = hash & 15; /* CONVERT LO 4 BITS OF HASH CODE */ +float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */ + v = h < 4 ? y : h==12||h==14 ? x : z; +return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); +} + +#define P(x) pNoise[(x) & 255] + +float pnoise(float x, float y, float z) { + +int X = (int)floorf(x) & 255, /* FIND UNIT CUBE THAT */ + Y = (int)floorf(y) & 255, /* CONTAINS POINT. */ + Z = (int)floorf(z) & 255; +x -= floorf(x); /* FIND RELATIVE X,Y,Z */ +y -= floorf(y); /* OF POINT IN CUBE. */ +z -= floorf(z); +float u = fade(x), /* COMPUTE FADE CURVES */ + v = fade(y), /* FOR EACH OF X,Y,Z. */ + w = fade(z); +int A = P(X)+Y, + AA = P(A)+Z, + AB = P(A+1)+Z, /* HASH COORDINATES OF */ + B = P(X+1)+Y, + BA = P(B)+Z, + BB = P(B+1)+Z; /* THE 8 CUBE CORNERS, */ + +return lerp(w,lerp(v,lerp(u, grad(P(AA ), x, y, z), /* AND ADD */ + grad(P(BA ), x-1, y, z)), /* BLENDED */ + lerp(u, grad(P(AB ), x, y-1, z), /* RESULTS */ + grad(P(BB ), x-1, y-1, z))), /* FROM 8 */ + lerp(v, lerp(u, grad(P(AA+1), x, y, z-1), /* CORNERS */ + grad(P(BA+1), x-1, y, z-1)), /* OF CUBE */ + lerp(u, grad(P(AB+1), x, y-1, z-1), + grad(P(BB+1), x-1, y-1, z-1)))); +} + + +void calculate_oscillators(oscillators &timings) { + + double runtime = millis() * timings.master_speed * speed_factor; // global anaimation speed + + for (int i = 0; i < num_oscillators; i++) { + + move.linear[i] = (runtime + timings.offset[i]) * timings.ratio[i]; // continously rising offsets, returns 0 to max_float + + move.radial[i] = fmodf(move.linear[i], 2 * PI); // angle offsets for continous rotation, returns 0 to 2 * PI + + move.directional[i] = sinf(move.radial[i]); // directional offsets or factors, returns -1 to 1 + + move.noise_angle[i] = PI * (1 + pnoise(move.linear[i], 0, 0)); // noise based angle offset, returns 0 to 2 * PI + + } +} + + +void run_default_oscillators(){ + + timings.ratio[0] = 1; // speed ratios for the oscillators, higher values = faster transitions + timings.ratio[1] = 2; + timings.ratio[2] = 3; + timings.ratio[3] = 4; + timings.ratio[4] = 5; + timings.ratio[5] = 6; + timings.ratio[6] = 7; + timings.ratio[7] = 8; + timings.ratio[8] = 9; + timings.ratio[9] = 10; + + + timings.offset[0] = 000; + timings.offset[1] = 100; + timings.offset[2] = 200; + timings.offset[3] = 300; + timings.offset[4] = 400; + timings.offset[5] = 500; + timings.offset[6] = 600; + timings.offset[7] = 700; + timings.offset[8] = 800; + timings.offset[9] = 900; + + calculate_oscillators(timings); +} + + +// Convert the 2 polar coordinates back to cartesian ones & also apply all 3d transitions. +// Calculate the noise value at this point based on the 5 dimensional manipulation of +// the underlaying coordinates. + +float render_value(render_parameters &animation) { + + // convert polar coordinates back to cartesian ones + + float newx = (animation.offset_x + animation.center_x - (cosf(animation.angle) * animation.dist)) * animation.scale_x; + float newy = (animation.offset_y + animation.center_y - (sinf(animation.angle) * animation.dist)) * animation.scale_y; + float newz = (animation.offset_z + animation.z) * animation.scale_z; + + // render noisevalue at this new cartesian point + + float raw_noise_field_value = pnoise(newx, newy, newz); + + // A) enhance histogram (improve contrast) by setting the black and white point (low & high_limit) + // B) scale the result to a 0-255 range (assuming you want 8 bit color depth per rgb chanel) + // Here happens the contrast boosting & the brightness mapping + + if (raw_noise_field_value < animation.low_limit) raw_noise_field_value = animation.low_limit; + if (raw_noise_field_value > animation.high_limit) raw_noise_field_value = animation.high_limit; + + float scaled_noise_value = map_float(raw_noise_field_value, animation.low_limit, animation.high_limit, 0, 255); + + return scaled_noise_value; +} + + +// given a static polar origin we can precalculate +// the polar coordinates + +void render_polar_lookup_table(float cx, float cy) { + + polar_theta.resize(num_x, std::vector(num_y, 0.0f)); + distance.resize(num_x, std::vector(num_y, 0.0f)); + + for (int xx = 0; xx < num_x; xx++) { + for (int yy = 0; yy < num_y; yy++) { + + float dx = xx - cx; + float dy = yy - cy; + + distance[xx][yy] = hypotf(dx, dy); + polar_theta[xx][yy] = atan2f(dy, dx); + } + } +} + + + +// float mapping maintaining 32 bit precision +// we keep values with high resolution for potential later usage + +float map_float(float x, float in_min, float in_max, float out_min, float out_max) { + + float result = (x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min; + if (result < out_min) result = out_min; + if( result > out_max) result = out_max; + + return result; +} + + +/* unnecessary bloat + +// check result after colormapping and store the newly rendered rgb data + +void write_pixel_to_framebuffer(int x, int y, rgb &pixel) { + + // assign the final color of this one pixel + CRGB finalcolor = CRGB(pixel.red, pixel.green, pixel.blue); + + // write the rendered pixel into the framebutter + leds[xy(x, y)] = finalcolor; +} +*/ + + +// Avoid any possible color flicker by forcing the raw RGB values to be 0-255. +// This enables to play freely with random equations for the colormapping +// without causing flicker by accidentally missing the valid target range. + +rgb rgb_sanity_check(rgb &pixel) { + + // rescue data if possible, return absolute value + //if (pixel.red < 0) pixel.red = fabsf(pixel.red); + //if (pixel.green < 0) pixel.green = fabsf(pixel.green); + //if (pixel.blue < 0) pixel.blue = fabsf(pixel.blue); + + // Can never be negative colour + if (pixel.red < 0) pixel.red = 0; + if (pixel.green < 0) pixel.green = 0; + if (pixel.blue < 0) pixel.blue = 0; + + + // discard everything above the valid 8 bit colordepth 0-255 range + if (pixel.red > 255) pixel.red = 255; + if (pixel.green > 255) pixel.green = 255; + if (pixel.blue > 255) pixel.blue = 255; + + return pixel; +} + + +// find the right led index according to you LED matrix wiring + +uint16_t xy(uint8_t x, uint8_t y) { + if (serpentine && y & 1) // check last bit + return (y + 1) * num_x - 1 - x; // reverse every second line for a serpentine lled layout + else + return y * num_x + x; // use this equation only for a line by line layout +} // remove the previous 3 lines of code in this case + + + +void get_ready() { // wait until new buffer is ready, measure time + a = micros(); + logOutput(); +} + +virtual void setPixelColor(int x, int y, rgb pixel) = 0; + +virtual void setPixelColor(int index, rgb pixel) = 0; + +void logOutput() { + b = micros(); +} + +void logFrame() { + c = micros(); +} + +// Show the current framerate, rendered pixels per second, +// rendering time & time spend to push the data to the leds. +// in the serial monitor. + +void report_performance() { + + float calc = b - a; // waiting time + float push = c - b; // rendering time + float total = c - a; // time per frame + int fps = 1000000 / total; // frames per second + int kpps = (fps * num_x * num_y) / 1000; // kilopixel per second + + Serial.print(fps); Serial.print(" fps "); + Serial.print(kpps); Serial.print(" kpps @"); + Serial.print(num_x*num_y); Serial.print(" LEDs "); + Serial.print(round(total)); Serial.print(" µs per frame waiting: "); + Serial.print(round((calc * 100) / total)); Serial.print("% rendering: "); + Serial.print(round((push * 100) / total)); Serial.print("% ("); + Serial.print(round(calc)); Serial.print(" + "); + Serial.print(round(push)); Serial.print(" µs) Core-temp: "); + // TODO Serial.print( tempmonGetTemp() ); + Serial.println(" °C"); + +} + +// Effects + void Rotating_Blob() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 0.1; // higher values = faster transitions @@ -55,7 +502,7 @@ void Rotating_Blob() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -67,7 +514,7 @@ void Rotating_Blob() { void Chasing_Spirals() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 0.1; // higher values = faster transitions @@ -115,7 +562,7 @@ void Chasing_Spirals() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -125,7 +572,7 @@ void Chasing_Spirals() { void Rings() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 1; // higher values = faster transitions @@ -172,7 +619,7 @@ void Rings() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -181,7 +628,7 @@ void Rings() { void Waves() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 2; // higher values = faster transitions @@ -221,7 +668,7 @@ void Waves() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -230,7 +677,7 @@ void Waves() { void Center_Field() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 1; // higher values = faster transitions @@ -277,7 +724,7 @@ void Center_Field() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -288,7 +735,7 @@ void Distance_Experiment() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.01; // speed ratios for the oscillators timings.ratio[0] = 0.2; // higher values = faster transitions @@ -334,7 +781,7 @@ void Distance_Experiment() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -345,7 +792,7 @@ void Distance_Experiment() { void Caleido1() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.003; // speed ratios for the oscillators timings.ratio[0] = 0.02; // higher values = faster transitions @@ -401,7 +848,7 @@ void Caleido1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -410,7 +857,7 @@ void Caleido1() { void Caleido2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.002; // speed ratios for the oscillators timings.ratio[0] = 0.02; // higher values = faster transitions @@ -466,7 +913,7 @@ void Caleido2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -475,7 +922,7 @@ void Caleido2() { void Caleido3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.004; // speed ratios for the oscillators timings.ratio[0] = 0.02; // higher values = faster transitions @@ -541,7 +988,7 @@ void Caleido3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -551,7 +998,7 @@ void Caleido3() { void Lava1() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); // for time measurement in report_performance() + timings.master_speed = 0.0015; // speed ratios for the oscillators timings.ratio[0] = 4; // higher values = faster transitions @@ -603,10 +1050,11 @@ void Lava1() { pixel.red = linear*show2; pixel.green = 0.1*linear*(show2-show3); + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -616,12 +1064,12 @@ void Lava1() { void Scaledemo1() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.00003; // speed ratios for the oscillators - timings.ratio[0] = 4; // higher values = faster transitions - timings.ratio[1] = 3.2; - timings.ratio[2] = 10; + timings.ratio[0] = 0.4; // higher values = faster transitions + timings.ratio[1] = 0.32; + timings.ratio[2] = 0.10; timings.ratio[3] = 0.05; timings.ratio[4] = 0.6; timings.offset[0] = 0; @@ -664,7 +1112,7 @@ void Scaledemo1() { pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -674,7 +1122,7 @@ void Scaledemo1() { void Yves() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + a = micros(); // for time measurement in report_performance() @@ -741,7 +1189,7 @@ void Yves() { pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -750,7 +1198,7 @@ void Yves() { void Spiralus() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.0011; // speed ratios for the oscillators timings.ratio[0] = 1.5; // higher values = faster transitions @@ -804,7 +1252,7 @@ void Spiralus() { pixel.blue = f*(show3-show1); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -813,7 +1261,7 @@ void Spiralus() { void Spiralus2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.0015; // speed ratios for the oscillators timings.ratio[0] = 1.5; // higher values = faster transitions @@ -869,7 +1317,7 @@ void Spiralus2() { pixel.blue = f*(show3-show1); pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -879,8 +1327,8 @@ void Spiralus2() { void Hot_Blob() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); - + + timings.master_speed = 0.001; // master speed run_default_oscillators(); for (int x = 0; x < num_x; x++) { @@ -920,9 +1368,10 @@ void Hot_Blob() { // nice one pixel.red = radial * show2; pixel.green = linear * radial* 0.3* (show2-show4); + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -932,11 +1381,10 @@ void Zoom() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + - run_default_oscillators(); timings.master_speed = 0.003; - calculate_oscillators(timings); + run_default_oscillators(); for (int x = 0; x < num_x; x++) { for (int y = 0; y < num_y; y++) { @@ -960,10 +1408,11 @@ void Zoom() { // nice one pixel.red = show1*linear; pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -976,11 +1425,10 @@ void Slow_Fade() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + - run_default_oscillators(); timings.master_speed = 0.00005; - calculate_oscillators(timings); + run_default_oscillators(); for (int x = 0; x < num_x; x++) { for (int y = 0; y < num_y; y++) { @@ -1021,7 +1469,7 @@ void Slow_Fade() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -1032,7 +1480,7 @@ void Polar_Waves() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1075,7 +1523,7 @@ void Polar_Waves() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -1085,7 +1533,7 @@ void Polar_Waves() { // nice one void RGB_Blobs() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.2; // master speed @@ -1131,7 +1579,7 @@ void RGB_Blobs() { // nice one pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -1141,7 +1589,7 @@ void RGB_Blobs() { // nice one void RGB_Blobs2() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.12; // master speed @@ -1184,7 +1632,7 @@ void RGB_Blobs2() { // nice one pixel.blue = radial * (show3-show2); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -1194,7 +1642,7 @@ void RGB_Blobs3() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.12; // master speed @@ -1237,7 +1685,7 @@ void RGB_Blobs3() { // nice one pixel.blue = radial * (show3+show2)*0.5 * x/15; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -1247,7 +1695,7 @@ void RGB_Blobs4() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1292,7 +1740,7 @@ void RGB_Blobs4() { // nice one pixel.blue = radial * (show3+show2)*0.5 * x/15; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -1302,7 +1750,7 @@ void RGB_Blobs5() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1348,7 +1796,7 @@ void RGB_Blobs5() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -1358,7 +1806,7 @@ void Big_Caleido() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1427,7 +1875,7 @@ void Big_Caleido() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } //show_frame(); @@ -1437,7 +1885,7 @@ void SM1() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1511,11 +1959,11 @@ void SM1() { // nice one pixel = rgb_sanity_check(pixel); //leds[xy(x, y)] = CRGB(pixel.red, pixel.green, pixel.blue); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); - buffer[xy(31-x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); - buffer[xy(31-x, 31-y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); - buffer[xy(x, 31-y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(xy((num_x -1)-x, y), pixel); + setPixelColor(xy((num_x -1)-x, (num_y -1)-y), pixel); + setPixelColor(xy(x, (num_y -1)-y), pixel); } } //show_frame(); @@ -1525,7 +1973,7 @@ void SM2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1579,7 +2027,7 @@ void SM2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } @@ -1591,7 +2039,7 @@ void SM3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1673,7 +2121,7 @@ void SM3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -1684,7 +2132,7 @@ void SM4() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1730,7 +2178,7 @@ void SM4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } @@ -1741,7 +2189,7 @@ void SM5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1826,7 +2274,7 @@ void SM5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -1836,7 +2284,7 @@ void SM6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1927,7 +2375,7 @@ void SM6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -1937,9 +2385,10 @@ void SM8() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + + + timings.master_speed = 0.005; // master speed - timings.master_speed = 0.06; // master speed timings.ratio[0] = 0.025; // speed ratios for the oscillators, higher values = faster transitions timings.ratio[1] = 0.027; @@ -2005,7 +2454,7 @@ void SM8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2015,7 +2464,7 @@ void SM9() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.005; // master speed @@ -2087,7 +2536,7 @@ void SM9() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2096,7 +2545,7 @@ void SM10() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.006; // 0.006 @@ -2170,7 +2619,7 @@ void SM10() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2181,7 +2630,7 @@ void Complex_Kaleido() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.009; // master speed @@ -2259,7 +2708,7 @@ void Complex_Kaleido() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2270,7 +2719,7 @@ void Complex_Kaleido_2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.009; // master speed @@ -2348,7 +2797,7 @@ void Complex_Kaleido_2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2360,7 +2809,7 @@ void Complex_Kaleido_3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.001; // master speed @@ -2398,7 +2847,7 @@ void Complex_Kaleido_3() { animation.scale_x = 0.07 * size * (move.directional[1]+1.1); animation.scale_y = 0.07 * size * (move.directional[2]+1.3);; animation.offset_z = -12 * move.linear[1];; - animation.offset_x = -31 * move.linear[1]; + animation.offset_x = -(num_x -1) * move.linear[1]; animation.offset_y = 0; animation.low_limit = 0; show2 = render_value(animation); @@ -2447,7 +2896,7 @@ void Complex_Kaleido_3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2456,7 +2905,7 @@ void Complex_Kaleido_4() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.01 in the video @@ -2554,7 +3003,7 @@ void Complex_Kaleido_4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2563,7 +3012,7 @@ void Complex_Kaleido_5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2602,10 +3051,12 @@ void Complex_Kaleido_5() { float radial = (radius-distance[x][y])/distance[x][y]; pixel.red = show1 * radial; + pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2614,7 +3065,7 @@ void Complex_Kaleido_6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2660,11 +3111,12 @@ void Complex_Kaleido_6() { //float radial = (radius-distance[x][y])/distance[x][y]; pixel.red = show1; + pixel.green = 0; pixel.blue = show2; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2673,7 +3125,7 @@ void Water() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.037; // master speed @@ -2745,6 +3197,7 @@ void Water() { pixel.blue = (0.7*show2+0.6*show3+0.5*show4); pixel.red = pixel.blue-40; + pixel.green = 0; //pixel.red = radial*show3; //pixel.green = 0.9*radial*show4; @@ -2752,7 +3205,7 @@ void Water() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2761,7 +3214,7 @@ void Parametric_Water() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.003; // master speed @@ -2838,15 +3291,16 @@ void Parametric_Water() { //pixel.red = show6; //pixel.blue = show7; - pixel.blue = (0.3*show6+0.7*show7)*radial; pixel.red = pixel.blue-40; + pixel.green = 0; + pixel.blue = (0.3*show6+0.7*show7)*radial; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2855,7 +3309,7 @@ void Module_Experiment1() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -2880,11 +3334,13 @@ void Module_Experiment1() { animation.low_limit = 0; show1 = render_value(animation); + pixel.red = 0; + pixel.green = 0; pixel.blue = show1; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2893,7 +3349,7 @@ void Module_Experiment2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -2924,7 +3380,7 @@ void Module_Experiment2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2933,7 +3389,7 @@ void Module_Experiment3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2964,7 +3420,7 @@ void Module_Experiment3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -2973,11 +3429,10 @@ void Zoom2() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + - run_default_oscillators(); timings.master_speed = 0.003; - calculate_oscillators(timings); + run_default_oscillators(); for (int x = 0; x < num_x; x++) { for (int y = 0; y < num_y; y++) { @@ -3000,11 +3455,12 @@ void Zoom2() { // nice one //float linear = 1;//(y+1)/(num_y-1.f); pixel.red = show1; + pixel.green = 0; pixel.blue = 40-show1; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor((num_x * y + x), pixel); } } @@ -3014,7 +3470,7 @@ void Module_Experiment4() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.031; // master speed @@ -3081,7 +3537,7 @@ void Module_Experiment4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3090,7 +3546,7 @@ void Module_Experiment5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.031; // master speed @@ -3121,11 +3577,13 @@ void Module_Experiment5() { pixel.red = show1; + pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3134,7 +3592,7 @@ void Module_Experiment6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3189,7 +3647,7 @@ void Module_Experiment6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3198,7 +3656,7 @@ void Module_Experiment7() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.005; // master speed 0.031 @@ -3254,7 +3712,7 @@ void Module_Experiment7() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3263,7 +3721,7 @@ void Module_Experiment8() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3346,7 +3804,7 @@ void Module_Experiment8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3355,7 +3813,7 @@ void Module_Experiment9() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed 0.031 @@ -3387,10 +3845,12 @@ void Module_Experiment9() { show1 = render_value(animation); pixel.red = 10*show1; + pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + setPixelColor(x, y, pixel); } } } @@ -3399,7 +3859,7 @@ void Module_Experiment10() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3482,8 +3942,16 @@ void Module_Experiment10() { pixel = rgb_sanity_check(pixel); byte a = millis()/100; - - buffer[xy(x, y)] = (rgb24)CRGB( CHSV(((a + show1 + show2) + show3), 255, 255)); + CRGB p = CRGB( CHSV(((a + show1 + show2) + show3), 255, 255)); + rgb pixel; + pixel.red = p.red; + pixel.green = p.green; + pixel.blue = p.blue; + setPixelColor(x, y, pixel); } } -} \ No newline at end of file +} + + +}; + diff --git a/AnimARTrix_SmartMatrix.ino b/AnimARTrix_SmartMatrix.ino deleted file mode 100644 index 6d20a1e..0000000 --- a/AnimARTrix_SmartMatrix.ino +++ /dev/null @@ -1,183 +0,0 @@ -/* - ___ _ ___ ______ _____ _ - / _ \ (_) / _ \ | ___ \_ _| (_) -/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ -| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / -| | | | | | | | | | | | | | | || |\ \ | | | | |> < -\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ - -by Stefan Petrick 2023. - -High quality LED animations for your next project. - -This is a Shader and 5D Coordinate Mapper made for realtime -rendering of generative animations & artistic dynamic visuals. - -This is also a modular animation synthesizer with waveform -generators, oscillators, filters, modulators, noise generators, -compressors... and much more. - -VO.42 beta version - -This code is licenced under a Creative Commons Attribution -License CC BY-NC 3.0 - -*/ - -#include // SmartLED Shield for Teensy 4 (V5) -#include -#include - -#define num_x 32 // how many LEDs are in one row? -#define num_y 32 // how many rows? -#define brightness 255 // please be aware that reducing brightness also reduces color resolution, use only in emergency - -#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 - -#define COLOR_DEPTH 24 // Choose the color depth used for storing pixels in the layers: 24 or 48 (24 is good for most sketches - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24) -const uint16_t kMatrixWidth = num_x; // Set to the width of your display, must be a multiple of 8 -const uint16_t kMatrixHeight = num_y; // Set to the height of your display -const uint8_t kRefreshDepth = 48; // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage. 36 is typically good, drop down to 24 if you need to. On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48. On ESP32: 24, 36, 48 -const uint8_t kDmaBufferRows = 4; // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate. (This isn't used on ESP32, leave as default) -const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https://github.com/pixelmatix/SmartMatrix/wiki -const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE); // see docs for options: https://github.com/pixelmatix/SmartMatrix/wiki -const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE); - -SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions); -SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions); - -//#define NUM_LEDS ((num_x) * (num_y)) -CRGB leds[num_x * num_y]; // framebuffer - -float polar_theta[num_x][num_y]; // look-up table for polar angles -float distance[num_x][num_y]; // look-up table for polar distances - -unsigned long a, b, c; // for time measurements - -struct render_parameters { - - float center_x = (num_x / 2) - 0.5; // center of the matrix - float center_y = (num_y / 2) - 0.5; - float dist, angle; - float scale_x = 0.1; // smaller values = zoom in - float scale_y = 0.1; - float scale_z = 0.1; - float offset_x, offset_y, offset_z; - float z; - float low_limit = 0; // getting contrast by highering the black point - float high_limit = 1; -}; - -render_parameters animation; // all animation parameters in one place - -#define num_oscillators 10 - -struct oscillators { - - float master_speed; // global transition speed - float offset[num_oscillators]; // oscillators can be shifted by a time offset - float ratio[num_oscillators]; // speed ratios for the individual oscillators -}; - -oscillators timings; // all speed settings in one place - -struct modulators { - - float linear[num_oscillators]; // returns 0 to FLT_MAX - float radial[num_oscillators]; // returns 0 to 2*PI - float directional[num_oscillators]; // returns -1 to 1 - float noise_angle[num_oscillators]; // returns 0 to 2*PI -}; - -modulators move; // all oscillator based movers and shifters at one place - -struct rgb { - - float red, green, blue; -}; - -rgb pixel; - -float show1, show2, show3, show4, show5, show6, show7, show8, show9, show0; - - -//****************************************************************************************************************** - - -void setup() { - - // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.addLeds(leds, NUM_LEDS); - // FastLED.setMaxPowerInVoltsAndMilliamps( 5, 2000); // optional current limiting [5V, 2000mA] - - Serial.begin(115200); // check serial monitor for current fps count - - render_polar_lookup_table((num_x / 2) - 0.5, (num_y / 2) - 0.5); // precalculate all polar coordinates - // polar origin is set to matrix centre - matrix.addLayer(&backgroundLayer); - matrix.setBrightness(brightness); - matrix.begin(); -} - -//******************************************************************************************************************* - -void loop() { - - - //Module_Experiment10(); // HSV scroll (bad palette resolution) - //Module_Experiment9(); // red stripes - //Module_Experiment8(); // another ambilight...very nice - //Module_Experiment7(); // slow ambilight ripples redish - //Module_Experiment6(); // slower ripples red-yellow - //Module_Experiment5(); // watery red ripples - //Module_Experiment4(); // slow RGB middle zoom dist^2 - //Zoom2(); - //Module_Experiment3(); // inside out zoomed in - //Module_Experiment2(); // stretched distance, fire colors - //Module_Experiment1(); // inside out demo - //Parametric_Water(); // slow blue ambientlight - //Water(); // nice water simulation - //Complex_Kaleido_6(); // red blue moire - //Complex_Kaleido_5(); // interference pattern - Complex_Kaleido_4(); // colorful slow mandala - //Complex_Kaleido_3(); - //Complex_Kaleido_2(); // hypnotic smooth - //Complex_Kaleido(); - //SM10(); // like 9 but fire colors - slow - //SM9(); // polar domain warping - //SM8(); // careful: flashy rings - //SM7(); // wild rings - //SM6(); // red + blue, pretty and beautiful one, my favourite so far - //SM5(); // nice colorful roto blobs - //SM4(); // layer merge test - //SM3(); // cartesian domain warping - //SM2(); // roro zoom - //SM1(); // copy caleido - //Big_Caleido(); // 5/6 Kaleido + rings - //RGB_Blobs5(); // sqrtf dist - //RGB_Blobs4(); - //RGB_Blobs3(); - //RGB_Blobs2(); - //RGB_Blobs(); // multi roto stuff - //Polar_Waves(); // spiral waves - //Slow_Fade(); // red big spiral - //Zoom(); // boring - //Hot_Blob(); // something firey, hot center - //Spiralus2(); // slow - //Spiralus(); // *2 - //Yves(); // red warpings - //Scaledemo1(); // *3 + ring red blue - //Lava1(); // slow ambilight - //Caleido3(); // roto - //Caleido2(); // roto *2 - //Caleido1(); // star like - //Distance_Experiment(); // big orange yellow smooth - //Center_Field(); // boring green yello red - //Waves(); // cool big red blue - //Chasing_Spirals(); // slim - //Rotating_Blob(); // - - show_frame(); - -} - diff --git a/README.md b/README.md index 0b22d19..72341ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # AnimARTrix -by Stefan Petrick 2023. +by Stefan Petrick 2023. +Object Oriented port by Will Tatam High quality LED animations for your next project. diff --git a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino new file mode 100644 index 0000000..ea85030 --- /dev/null +++ b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino @@ -0,0 +1,105 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ + +#include +#include + +#define num_x 30 // how many LEDs are in one row? +#define num_y 30 // how many rows? + +#define NUM_LED (num_x * num_y) +CRGB leds[NUM_LED]; // framebuffer + +bool serpentine = true; + +class FastLEDANIMartRIX : public ANIMartRIX { + CRGB* leds; + public: + FastLEDANIMartRIX(int x, int y, CRGB* leds, bool serpentine) { + this->init(x, y, serpentine); + this->leds = leds; + } + void setPixelColor(int x, int y, rgb pixel) { + leds[xy(x,y)] = CRGB(pixel.red, pixel.green, pixel.blue); + } + void setPixelColor(int index, rgb pixel) { + leds[index] = CRGB(pixel.red, pixel.green, pixel.blue); + } +}; +FastLEDANIMartRIX animatrix(num_x, num_y, leds, serpentine); + +//****************************************************************************************************************** + + +void setup() { + + // FastLED.addLeds(leds, NUM_LED); + + FastLED.addLeds(leds, NUM_LED); + + FastLED.setMaxPowerInVoltsAndMilliamps( 5, 2000); // optional current limiting [5V, 2000mA] + + Serial.begin(115200); // check serial monitor for current fps count + + // fill_rainbow(leds, NUM_LED, 0); + fill_solid(leds, NUM_LED, CRGB::Green); + FastLED.show(); +} + +//******************************************************************************************************************* + +void loop() { + //FastLED.clear(); + // art.RGB_Blobs5(); + // art.RGB_Blobs4(); + // art.RGB_Blobs3(); + // art.RGB_Blobs2(); + animatrix.RGB_Blobs(); + // art.Polar_Waves(); + // art.Slow_Fade(); + // art.Zoom2(); + // art.Zoom(); + // art.Hot_Blob(); + // art.Spiralus2(); + // art.Spiralus(); + // art.Yves(); + // art.Scaledemo1(); + // art. art.Lava1(); + // art.Caleido3(); + // art.Caleido2(); + // art.Caleido1(); + // art.Distance_Experiment(); + // art.Center_Field(); + // art.Waves(); + // art.Chasing_Spirals(); + // art.Rotating_Blob(); + // art.Rings(); + animatrix.logOutput(); + FastLED.show(); + animatrix.logFrame(); + EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report +} + diff --git a/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino new file mode 100644 index 0000000..00e8272 --- /dev/null +++ b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino @@ -0,0 +1,135 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ +#include +#include + +#include +#include + +#include + +namespace teensydmx = ::qindesign::teensydmx; + +#define num_x 30 // how many LEDs are in one row? +#define num_y 30 // how many rows? + +#define NUM_LED (num_x * num_y) +CRGB leds[NUM_LED]; // framebuffer + +bool serpentine = true; + +// Create the DMX receiver on Serial1. +teensydmx::Receiver dmxRx{ Serial1 }; + + +class FastLEDANIMartRIX : public ANIMartRIX { + CRGB* leds; +public: + FastLEDANIMartRIX(int x, int y, CRGB* leds, bool serpentine) { + this->init(x, y, serpentine); + this->leds = leds; + } + void setPixelColor(int x, int y, rgb pixel) { + leds[xy(x, y)] = CRGB(pixel.red, pixel.green, pixel.blue); + } + void setPixelColor(int index, rgb pixel) { + leds[index] = CRGB(pixel.red, pixel.green, pixel.blue); + } +}; +FastLEDANIMartRIX animatrix(num_x, num_y, leds, serpentine); + + +std::vector> gPatterns; + +int gPatternCount = 0; + +//****************************************************************************************************************** + + +void setup() { + + // FastLED.addLeds(leds, NUM_LED); + + FastLED.addLeds(leds, NUM_LED); + + FastLED.setMaxPowerInVoltsAndMilliamps(5, 2000); // optional current limiting [5V, 2000mA] + + Serial.begin(115200); // check serial monitor for current fps count + + // fill_rainbow(leds, NUM_LED, 0); + fill_solid(leds, NUM_LED, CRGB::Green); + FastLED.show(); + + // Start the receiver + dmxRx.begin(); + + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs5, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs5, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs4, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs3, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs2, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Polar_Waves, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Slow_Fade, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Zoom2, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Zoom, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Hot_Blob, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus2, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Yves, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Scaledemo1, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Lava1, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido3, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido2, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido1, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Distance_Experiment, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Center_Field, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Waves, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Chasing_Spirals, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Rotating_Blob, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Rings, animatrix)); + + + gPatternCount = gPatterns.size(); +} + +//******************************************************************************************************************* + +void loop() { + //FastLED.clear(); + int pattern = map(dmxRx.get(1), 0, 255, 0, (gPatternCount - 1)); // select pattern + gPatterns[pattern](); + + uint8_t v = dmxRx.get(2); // fetch speed + float speedFactor = (float)map(v, 0, 255, 10, 100) / 10.0f; + animatrix.setSpeedFactor(speedFactor); + + animatrix.logOutput(); + FastLED.show(); + animatrix.logFrame(); + EVERY_N_MILLIS(500) + animatrix.report_performance(); // check serial monitor for report +} diff --git a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino new file mode 100644 index 0000000..ce2cbcf --- /dev/null +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -0,0 +1,149 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ + +#include // SmartLED Shield for Teensy 4 (V5) +#include +#include + +#define num_x 64 // how many LEDs are in one row? +#define num_y 64 // how many rows? +#define brightness 255 // please be aware that reducing brightness also reduces color resolution, use only in emergency + +#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 + +#define COLOR_DEPTH 24 // Choose the color depth used for storing pixels in the layers: 24 or 48 (24 is good for most sketches - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24) +const uint16_t kMatrixWidth = num_x; // Set to the width of your display, must be a multiple of 8 +const uint16_t kMatrixHeight = num_y; // Set to the height of your display +const uint8_t kRefreshDepth = 48; // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage. 36 is typically good, drop down to 24 if you need to. On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48. On ESP32: 24, 36, 48 +const uint8_t kDmaBufferRows = 4; // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate. (This isn't used on ESP32, leave as default) +const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https://github.com/pixelmatix/SmartMatrix/wiki +const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE); // see docs for options: https://github.com/pixelmatix/SmartMatrix/wiki +const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE); + +SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions); +SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions); + +class SmartMatrixANIMartRIX : public ANIMartRIX { + rgb24* buffer; + public: + SmartMatrixANIMartRIX(int x, int y) { + this->init(x, y, false); + } + void setBuffer(rgb24 *buffer) { + this->buffer = buffer; + } + void setPixelColor(int x, int y, rgb pixel) { + buffer[xy(x,y)] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void setPixelColor(int index, rgb pixel) { + buffer[index] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void logOutput() { + while(backgroundLayer.isSwapPending()); + b = micros(); + } + +}; +SmartMatrixANIMartRIX animatrix(num_x, num_y); + +//****************************************************************************************************************** + + +void setup() { + + Serial.begin(115200); // check serial monitor for current fps count + // polar origin is set to matrix centre + matrix.addLayer(&backgroundLayer); + matrix.setBrightness(brightness); + matrix.begin(); + animatrix.setBuffer(backgroundLayer.backBuffer()); +} + +//******************************************************************************************************************* + +void loop() { + + + //animatrix.Module_Experiment10(); // HSV scroll (bad palette resolution) + //animatrix.Module_Experiment9(); // red stripes + //animatrix.Module_Experiment8(); // another ambilight...very nice + //animatrix.Module_Experiment7(); // slow ambilight ripples redish + //animatrix.Module_Experiment6(); // slower ripples red-yellow + //animatrix.Module_Experiment5(); // watery red ripples + //animatrix.Module_Experiment4(); // slow RGB middle zoom dist^2 + //animatrix.Zoom2(); + //animatrix.Module_Experiment3(); // inside out zoomed in + //animatrix.Module_Experiment2(); // stretched distance, fire colors + //animatrix.Module_Experiment1(); // inside out demo + //animatrix.Parametric_Water(); // slow blue ambientlight + //animatrix.Water(); // nice water simulation + //animatrix.Complex_Kaleido_6(); // red blue moire + //animatrix.Complex_Kaleido_5(); // interference pattern + animatrix.Complex_Kaleido_4(); // colorful slow mandala + //animatrix.Complex_Kaleido_3(); + //animatrix.Complex_Kaleido_2(); // hypnotic smooth + //animatrix.Complex_Kaleido(); + //animatrix.SM10(); // like 9 but fire colors - slow + //animatrix.SM9(); // polar domain warping + //animatrix.SM8(); // careful: flashy rings + //animatrix.SM7(); // wild rings + //animatrix.SM6(); // red + blue, pretty and beautiful one, my favourite so far + //animatrix.SM5(); // nice colorful roto blobs + //animatrix.SM4(); // layer merge test + //animatrix.SM3(); // cartesian domain warping + //animatrix.SM2(); // roro zoom + //animatrix.SM1(); // copy caleido + //animatrix.Big_Caleido(); // 5/6 Kaleido + rings + //animatrix.RGB_Blobs5(); // sqrtf dist + //animatrix.RGB_Blobs4(); + //animatrix.RGB_Blobs3(); + //animatrix.RGB_Blobs2(); + //animatrix.RGB_Blobs(); // multi roto stuff + //animatrix.Polar_Waves(); // spiral waves + //animatrix.Slow_Fade(); // red big spiral + //animatrix.Zoom(); // boring + //animatrix.Hot_Blob(); // something firey, hot center + //animatrix.Spiralus2(); // slow + //animatrix.Spiralus(); // *2 + //animatrix.Yves(); // red warpings + //animatrix.Scaledemo1(); // *3 + ring red blue + //animatrix.Lava1(); // slow ambilight + //animatrix.Caleido3(); // roto + //animatrix.Caleido2(); // roto *2 + //animatrix.Caleido1(); // star like + //animatrix.Distance_Experiment(); // big orange yellow smooth + //animatrix.Center_Field(); // boring green yello red + //animatrix.Waves(); // cool big red blue + //animatrix.Chasing_Spirals(); // slim + //animatrix.Rotating_Blob(); // + + + backgroundLayer.swapBuffers(true); + animatrix.logFrame(); + EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report + +} + diff --git a/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino new file mode 100644 index 0000000..a076424 --- /dev/null +++ b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino @@ -0,0 +1,179 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ + +#include +#include +#include // Teensy 4 Adapter attached to SmartLED Shield for Teensy 3 (V4) +//#include // SmartLED Shield for Teensy 4 (V5) +#include +#include + +#define num_x 64 // how many LEDs are in one row? +#define num_y 64 // how many rows? +#define brightness 255 // please be aware that reducing brightness also reduces color resolution, use only in emergency + +#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 + +#define COLOR_DEPTH 24 // Choose the color depth used for storing pixels in the layers: 24 or 48 (24 is good for most sketches - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24) +const uint16_t kMatrixWidth = num_x; // Set to the width of your display, must be a multiple of 8 +const uint16_t kMatrixHeight = num_y; // Set to the height of your display +const uint8_t kRefreshDepth = 48; // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage. 36 is typically good, drop down to 24 if you need to. On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48. On ESP32: 24, 36, 48 +const uint8_t kDmaBufferRows = 4; // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate. (This isn't used on ESP32, leave as default) +const uint8_t kPanelType = SM_PANELTYPE_HUB75_64ROW_MOD32SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https:github.com/pixelmatix/SmartMatrix/wiki +//const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https:github.com/pixelmatix/SmartMatrix/wiki +const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE); // see docs for options: https:github.com/pixelmatix/SmartMatrix/wiki +const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE); + +SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions); +SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions); + +class SmartMatrixANIMartRIX : public ANIMartRIX { + rgb24* buffer; + public: + SmartMatrixANIMartRIX(int x, int y) { + this->init(x, y, false); + } + void setBuffer(rgb24 *buffer) { + this->buffer = buffer; + } + void setPixelColor(int x, int y, rgb pixel) { + buffer[xy(x,y)] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void setPixelColor(int index, rgb pixel) { + buffer[index] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void logOutput() { + while(backgroundLayer.isSwapPending()); + b = micros(); + } + +}; +SmartMatrixANIMartRIX animatrix(num_x, num_y); + +std::vector> gPatterns; + +int gPatternCount = 0; + +//****************************************************************************************************************** + + +void setup() { + + Serial.begin(115200); // check serial monitor for current fps count + // polar origin is set to matrix centre + matrix.addLayer(&backgroundLayer); + matrix.setBrightness(brightness); + matrix.begin(); + animatrix.setBuffer(backgroundLayer.backBuffer()); + + Serial.println("Adding patterns to list"); + + // gPatterns.push_back(std::bind(&SmartMatrixANIMartRIX::Module_Experiment10, animatrix)); // HSV scroll (bad palette resolution) + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment9, animatrix)); // red stripes + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment8, animatrix)); // another ambilight...very nice + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment7, animatrix)); // slow ambilight ripples redish + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment6, animatrix)); // slower ripples red-yellow + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment5, animatrix)); // watery red ripples + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment4, animatrix)); // slow RGB middle zoom dist^2 + // gPatterns.push_back(std::bind(&ANIMartRIX::Zoom2, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment3, animatrix)); // inside out zoomed in + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment2, animatrix)); // stretched distance, fire colors + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment1, animatrix)); // inside out demo + // gPatterns.push_back(std::bind(&ANIMartRIX::Parametric_Water, animatrix)); // slow blue ambientlight + // gPatterns.push_back(std::bind(&ANIMartRIX::Water, animatrix)); // nice water simulation + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_6, animatrix)); // red blue moire + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_5, animatrix)); // interference pattern + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_4, animatrix)); // colorful slow mandala + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_3, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_2, animatrix)); // hypnotic smooth + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::SM10, animatrix)); // like 9 but fire colors - slow + // gPatterns.push_back(std::bind(&ANIMartRIX::SM9, animatrix)); // polar domain warping + // gPatterns.push_back(std::bind(&ANIMartRIX::SM8, animatrix)); // careful: flashy rings + // // gPatterns.push_back(std::bind(&ANIMartRIX::SM7, animatrix)); // wild rings + // gPatterns.push_back(std::bind(&ANIMartRIX::SM6, animatrix)); // red + blue, pretty and beautiful one, my favourite so far + // gPatterns.push_back(std::bind(&ANIMartRIX::SM5, animatrix)); // nice colorful roto blobs + // gPatterns.push_back(std::bind(&ANIMartRIX::SM4, animatrix)); // layer merge test + // gPatterns.push_back(std::bind(&ANIMartRIX::SM3, animatrix)); // cartesian domain warping + // gPatterns.push_back(std::bind(&ANIMartRIX::SM2, animatrix)); // roro zoom + gPatterns.push_back(std::bind(&ANIMartRIX::SM1, animatrix)); // copy caleido + // gPatterns.push_back(std::bind(&ANIMartRIX::Big_Caleido, animatrix)); // 5/6 Kaleido + rings + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs5, animatrix)); // sqrtf dist + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs4, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs3, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs2, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs, animatrix)); // multi roto stuff + // gPatterns.push_back(std::bind(&ANIMartRIX::Polar_Waves, animatrix)); // spiral waves + // gPatterns.push_back(std::bind(&ANIMartRIX::Slow_Fade, animatrix)); // red big spiral + // gPatterns.push_back(std::bind(&ANIMartRIX::Zoom, animatrix)); // boring + // gPatterns.push_back(std::bind(&ANIMartRIX::Hot_Blob, animatrix)); // something firey, hot center + // gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus2, animatrix)); // slow + // gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus, animatrix)); // *2 + // gPatterns.push_back(std::bind(&ANIMartRIX::Yves, animatrix)); // red warpings + // gPatterns.push_back(std::bind(&ANIMartRIX::Scaledemo1, animatrix)); // *3 + ring red blue + gPatterns.push_back(std::bind(&ANIMartRIX::Lava1, animatrix)); // slow ambilight + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido3, animatrix)); // roto + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido2, animatrix)); // roto *2 + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido1, animatrix)); // star like + // gPatterns.push_back(std::bind(&ANIMartRIX::Distance_Experiment, animatrix)); // big orange yellow smooth + // gPatterns.push_back(std::bind(&ANIMartRIX::Center_Field, animatrix)); // boring green yello red + gPatterns.push_back(std::bind(&ANIMartRIX::Waves, animatrix)); // cool big red blue + // gPatterns.push_back(std::bind(&ANIMartRIX::Chasing_Spirals, animatrix)); // slim + // gPatterns.push_back(std::bind(&ANIMartRIX::Rotating_Blob, animatrix)); // + + gPatternCount = gPatterns.size(); + + Serial.println("Setup complete"); + +} + +//******************************************************************************************************************* + +void loop() { + + + + // Automatic playback + static int pattern = 0; + gPatterns[pattern](); + + // animatrix.Lava1(); + + backgroundLayer.swapBuffers(true); + animatrix.logFrame(); + + EVERY_N_MILLIS(500) { + animatrix.report_performance(); // check serial monitor for report + } + + EVERY_N_SECONDS( 10 ) { + pattern++; + if(pattern >= gPatternCount) pattern = 0; + Serial.println("New pattern"); + } // change patterns periodically +} + + diff --git a/examples/ANIMartRIX_SmartMatrix_TeensyDMX/ANIMartRIX_SmartMatrix_TeensyDMX.ino b/examples/ANIMartRIX_SmartMatrix_TeensyDMX/ANIMartRIX_SmartMatrix_TeensyDMX.ino new file mode 100644 index 0000000..8458ce5 --- /dev/null +++ b/examples/ANIMartRIX_SmartMatrix_TeensyDMX/ANIMartRIX_SmartMatrix_TeensyDMX.ino @@ -0,0 +1,188 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +by Stefan Petrick 2023. + +High quality LED animations for your next project. + +This is a Shader and 5D Coordinate Mapper made for realtime +rendering of generative animations & artistic dynamic visuals. + +This is also a modular animation synthesizer with waveform +generators, oscillators, filters, modulators, noise generators, +compressors... and much more. + +VO.42 beta version + +This code is licenced under a Creative Commons Attribution +License CC BY-NC 3.0 + +*/ + +#include +#include +#include // Teensy 4 Adapter attached to SmartLED Shield for Teensy 3 (V4) +//#include // SmartLED Shield for Teensy 4 (V5) +#include +#include + +#include + +namespace teensydmx = ::qindesign::teensydmx; + +// Create the DMX receiver on Serial1. +teensydmx::Receiver dmxRx{ Serial1 }; + + +#define num_x 64 // how many LEDs are in one row? +#define num_y 64 // how many rows? +#define brightness 255 // please be aware that reducing brightness also reduces color resolution, use only in emergency + +#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 + +#define COLOR_DEPTH 24 // Choose the color depth used for storing pixels in the layers: 24 or 48 (24 is good for most sketches - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24) +const uint16_t kMatrixWidth = num_x; // Set to the width of your display, must be a multiple of 8 +const uint16_t kMatrixHeight = num_y; // Set to the height of your display +const uint8_t kRefreshDepth = 48; // Tradeoff of color quality vs refresh rate, max brightness, and RAM usage. 36 is typically good, drop down to 24 if you need to. On Teensy, multiples of 3, up to 48: 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48. On ESP32: 24, 36, 48 +const uint8_t kDmaBufferRows = 4; // known working: 2-4, use 2 to save RAM, more to keep from dropping frames and automatically lowering refresh rate. (This isn't used on ESP32, leave as default) +const uint8_t kPanelType = SM_PANELTYPE_HUB75_64ROW_MOD32SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https:github.com/pixelmatix/SmartMatrix/wiki +//const uint8_t kPanelType = SM_PANELTYPE_HUB75_32ROW_MOD16SCAN; // Choose the configuration that matches your panels. See more details in MatrixCommonHub75.h and the docs: https:github.com/pixelmatix/SmartMatrix/wiki +const uint32_t kMatrixOptions = (SM_HUB75_OPTIONS_NONE); // see docs for options: https:github.com/pixelmatix/SmartMatrix/wiki +const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE); + +SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions); +SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions); + +class SmartMatrixANIMartRIX : public ANIMartRIX { + rgb24* buffer; + public: + SmartMatrixANIMartRIX(int x, int y) { + this->init(x, y, false); + } + void setBuffer(rgb24 *buffer) { + this->buffer = buffer; + } + void setPixelColor(int x, int y, rgb pixel) { + buffer[xy(x,y)] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void setPixelColor(int index, rgb pixel) { + buffer[index] = rgb24(pixel.red, pixel.green, pixel.blue); + } + void logOutput() { + while(backgroundLayer.isSwapPending()); + b = micros(); + } + +}; +SmartMatrixANIMartRIX animatrix(num_x, num_y); + +std::vector> gPatterns; + +int gPatternCount = 0; + +//****************************************************************************************************************** + + +void setup() { + + Serial.begin(115200); // check serial monitor for current fps count + + gPatterns.reserve(50); + // polar origin is set to matrix centre + matrix.addLayer(&backgroundLayer); + matrix.setBrightness(brightness); + matrix.begin(); + animatrix.setBuffer(backgroundLayer.backBuffer()); + + // Start the receiver + dmxRx.begin(); + + Serial.println("Adding patterns to list"); + + // gPatterns.push_back(std::bind(&SmartMatrixANIMartRIX::Module_Experiment10, animatrix)); // HSV scroll (bad palette resolution) + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment9, animatrix)); // red stripes + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment8, animatrix)); // another ambilight...very nice + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment7, animatrix)); // slow ambilight ripples redish + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment6, animatrix)); // slower ripples red-yellow + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment5, animatrix)); // watery red ripples + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment4, animatrix)); // slow RGB middle zoom dist^2 + // gPatterns.push_back(std::bind(&ANIMartRIX::Zoom2, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment3, animatrix)); // inside out zoomed in + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment2, animatrix)); // stretched distance, fire colors + // gPatterns.push_back(std::bind(&ANIMartRIX::Module_Experiment1, animatrix)); // inside out demo + // gPatterns.push_back(std::bind(&ANIMartRIX::Parametric_Water, animatrix)); // slow blue ambientlight + // gPatterns.push_back(std::bind(&ANIMartRIX::Water, animatrix)); // nice water simulation + // gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_6, animatrix)); // red blue moire + // gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_5, animatrix)); // interference pattern + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_4, animatrix)); // colorful slow mandala + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_3, animatrix)); + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido_2, animatrix)); // hypnotic smooth + gPatterns.push_back(std::bind(&ANIMartRIX::Complex_Kaleido, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::SM10, animatrix)); // like 9 but fire colors - slow + // gPatterns.push_back(std::bind(&ANIMartRIX::SM9, animatrix)); // polar domain warping + // gPatterns.push_back(std::bind(&ANIMartRIX::SM8, animatrix)); // careful: flashy rings + // // gPatterns.push_back(std::bind(&ANIMartRIX::SM7, animatrix)); // wild rings + // gPatterns.push_back(std::bind(&ANIMartRIX::SM6, animatrix)); // red + blue, pretty and beautiful one, my favourite so far + // gPatterns.push_back(std::bind(&ANIMartRIX::SM5, animatrix)); // nice colorful roto blobs + gPatterns.push_back(std::bind(&ANIMartRIX::SM4, animatrix)); // layer merge test + gPatterns.push_back(std::bind(&ANIMartRIX::SM3, animatrix)); // cartesian domain warping + gPatterns.push_back(std::bind(&ANIMartRIX::SM2, animatrix)); // roro zoom + gPatterns.push_back(std::bind(&ANIMartRIX::SM1, animatrix)); // copy caleido + // gPatterns.push_back(std::bind(&ANIMartRIX::Big_Caleido, animatrix)); // 5/6 Kaleido + rings + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs5, animatrix)); // sqrtf dist + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs4, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs3, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs2, animatrix)); + // gPatterns.push_back(std::bind(&ANIMartRIX::RGB_Blobs, animatrix)); // multi roto stuff + // gPatterns.push_back(std::bind(&ANIMartRIX::Polar_Waves, animatrix)); // spiral waves + // gPatterns.push_back(std::bind(&ANIMartRIX::Slow_Fade, animatrix)); // red big spiral + // gPatterns.push_back(std::bind(&ANIMartRIX::Zoom, animatrix)); // boring + // gPatterns.push_back(std::bind(&ANIMartRIX::Hot_Blob, animatrix)); // something firey, hot center + // gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus2, animatrix)); // slow + // gPatterns.push_back(std::bind(&ANIMartRIX::Spiralus, animatrix)); // *2 + // gPatterns.push_back(std::bind(&ANIMartRIX::Yves, animatrix)); // red warpings + // gPatterns.push_back(std::bind(&ANIMartRIX::Scaledemo1, animatrix)); // *3 + ring red blue + gPatterns.push_back(std::bind(&ANIMartRIX::Lava1, animatrix)); // slow ambilight + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido3, animatrix)); // roto + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido2, animatrix)); // roto *2 + gPatterns.push_back(std::bind(&ANIMartRIX::Caleido1, animatrix)); // star like + // gPatterns.push_back(std::bind(&ANIMartRIX::Distance_Experiment, animatrix)); // big orange yellow smooth + // gPatterns.push_back(std::bind(&ANIMartRIX::Center_Field, animatrix)); // boring green yello red + gPatterns.push_back(std::bind(&ANIMartRIX::Waves, animatrix)); // cool big red blue + // gPatterns.push_back(std::bind(&ANIMartRIX::Chasing_Spirals, animatrix)); // slim + // gPatterns.push_back(std::bind(&ANIMartRIX::Rotating_Blob, animatrix)); // + + gPatternCount = gPatterns.size(); + + Serial.println("Setup complete"); + +} + +//******************************************************************************************************************* + +void loop() { + + int pattern = map(dmxRx.get(1), 0, 255, 0, (gPatternCount - 1)); // select pattern + gPatterns[pattern](); + + uint8_t v = dmxRx.get(2); // fetch speed + float speedFactor = (float)map(v, 0, 255, 10, 100) / 10.0f; + animatrix.setSpeedFactor(speedFactor); + + // animatrix.Lava1(); + + backgroundLayer.swapBuffers(true); + animatrix.logFrame(); + + EVERY_N_MILLIS(500) { + animatrix.report_performance(); // check serial monitor for report + } + +} + + diff --git a/merge_methods.ino b/merge_methods.ino deleted file mode 100644 index 4852920..0000000 --- a/merge_methods.ino +++ /dev/null @@ -1,43 +0,0 @@ -// Dynamic darkening methods: - -float subtract(float &a, float&b) { - - return a - b; -} - - -float multiply(float &a, float&b) { - - return a * b / 255.f; -} - - -// makes low brightness darker -// sets the black point high = more contrast -// animation.low_limit should be 0 for best results -float colorburn(float &a, float&b) { - - return (1-((1-a/255.f) / (b/255.f)))*255.f; -} - - -// Dynamic brightening methods - -float add(float &a, float&b) { - - return a + b; -} - - -// makes bright even brighter -// reduces contrast -float screen(float &a, float&b) { - - return (1 - (1 - a/255.f) * (1 - b/255.f))*255.f; -} - - -float colordodge(float &a, float&b) { - - return (a/(255.f-b)) * 255.f; -} \ No newline at end of file diff --git a/noise.ino b/noise.ino deleted file mode 100644 index 62661f6..0000000 --- a/noise.ino +++ /dev/null @@ -1,63 +0,0 @@ -/* - Ken Perlins improved noise - http://mrl.nyu.edu/~perlin/noise/ - C-port: http://www.fundza.com/c4serious/noise/perlin/perlin.html - by Malcolm Kesson; arduino port by Peter Chiochetti, Sep 2007 : - - make permutation constant byte, obsoletes init(), lookup % 256 -*/ - -static const byte p[] = { 151,160,137,91,90, 15,131, 13,201,95,96, -53,194,233, 7,225,140,36,103,30,69,142, 8,99,37,240,21,10,23,190, 6, -148,247,120,234,75, 0,26,197,62,94,252,219,203,117, 35,11,32,57,177, -33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139, -48,27,166, 77,146,158,231,83,111,229,122, 60,211,133,230,220,105,92, -41,55,46,245,40,244,102,143,54,65,25,63,161, 1,216,80,73,209,76,132, -187,208, 89, 18,169,200,196,135,130,116,188,159, 86,164,100,109,198, -173,186, 3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85, -212,207,206, 59,227, 47,16,58,17,182,189, 28,42,223,183,170,213,119, -248,152,2,44,154,163,70,221,153,101,155,167,43,172, 9,129,22,39,253, -19,98,108,110,79,113,224,232,178,185,112,104,218,246, 97,228,251,34, -242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107, -49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4, -150,254,138,236,205, 93,222,114, 67,29,24, 72,243,141,128,195,78,66, -215,61,156,180 -}; - -float fade(float t){ return t * t * t * (t * (t * 6 - 15) + 10); } -float lerp(float t, float a, float b){ return a + t * (b - a); } -float grad(int hash, float x, float y, float z) -{ -int h = hash & 15; /* CONVERT LO 4 BITS OF HASH CODE */ -float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */ - v = h < 4 ? y : h==12||h==14 ? x : z; -return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); -} - -#define P(x) p[(x) & 255] - -float pnoise(float x, float y, float z) { - -int X = (int)floorf(x) & 255, /* FIND UNIT CUBE THAT */ - Y = (int)floorf(y) & 255, /* CONTAINS POINT. */ - Z = (int)floorf(z) & 255; -x -= floorf(x); /* FIND RELATIVE X,Y,Z */ -y -= floorf(y); /* OF POINT IN CUBE. */ -z -= floorf(z); -float u = fade(x), /* COMPUTE FADE CURVES */ - v = fade(y), /* FOR EACH OF X,Y,Z. */ - w = fade(z); -int A = P(X)+Y, - AA = P(A)+Z, - AB = P(A+1)+Z, /* HASH COORDINATES OF */ - B = P(X+1)+Y, - BA = P(B)+Z, - BB = P(B+1)+Z; /* THE 8 CUBE CORNERS, */ - -return lerp(w,lerp(v,lerp(u, grad(P(AA ), x, y, z), /* AND ADD */ - grad(P(BA ), x-1, y, z)), /* BLENDED */ - lerp(u, grad(P(AB ), x, y-1, z), /* RESULTS */ - grad(P(BB ), x-1, y-1, z))), /* FROM 8 */ - lerp(v, lerp(u, grad(P(AA+1), x, y, z-1), /* CORNERS */ - grad(P(BA+1), x-1, y, z-1)), /* OF CUBE */ - lerp(u, grad(P(AB+1), x, y-1, z-1), - grad(P(BB+1), x-1, y-1, z-1)))); -} \ No newline at end of file diff --git a/oscillators.ino b/oscillators.ino deleted file mode 100644 index d17e527..0000000 --- a/oscillators.ino +++ /dev/null @@ -1,52 +0,0 @@ - -void calculate_oscillators(oscillators &timings) { - - double runtime = millis() * timings.master_speed; // global anaimation speed - - for (int i = 0; i < num_oscillators; i++) { - - move.linear[i] = (runtime + timings.offset[i]) * timings.ratio[i]; // continously rising offsets, returns 0 to max_float - - move.radial[i] = fmodf(move.linear[i], 2 * PI); // angle offsets for continous rotation, returns 0 to 2 * PI - - move.directional[i] = sinf(move.radial[i]); // directional offsets or factors, returns -1 to 1 - - move.noise_angle[i] = PI * (1 + pnoise(move.linear[i], 0, 0)); // noise based angle offset, returns 0 to 2 * PI - - } -} - - -void run_default_oscillators(){ - - timings.master_speed = 0.005; // master speed - - timings.ratio[0] = 1; // speed ratios for the oscillators, higher values = faster transitions - timings.ratio[1] = 2; - timings.ratio[2] = 3; - timings.ratio[3] = 4; - timings.ratio[4] = 5; - timings.ratio[5] = 6; - timings.ratio[6] = 7; - timings.ratio[7] = 8; - timings.ratio[8] = 9; - timings.ratio[9] = 10; - - - timings.offset[0] = 000; - timings.offset[1] = 100; - timings.offset[2] = 200; - timings.offset[3] = 300; - timings.offset[4] = 400; - timings.offset[5] = 500; - timings.offset[6] = 600; - timings.offset[7] = 700; - timings.offset[8] = 800; - timings.offset[9] = 900; - - calculate_oscillators(timings); -} - - - - diff --git a/rendering.ino b/rendering.ino deleted file mode 100644 index 367607b..0000000 --- a/rendering.ino +++ /dev/null @@ -1,109 +0,0 @@ -// Convert the 2 polar coordinates back to cartesian ones & also apply all 3d transitions. -// Calculate the noise value at this point based on the 5 dimensional manipulation of -// the underlaying coordinates. - -float render_value(render_parameters &animation) { - - // convert polar coordinates back to cartesian ones - - float newx = (animation.offset_x + animation.center_x - (cosf(animation.angle) * animation.dist)) * animation.scale_x; - float newy = (animation.offset_y + animation.center_y - (sinf(animation.angle) * animation.dist)) * animation.scale_y; - float newz = (animation.offset_z + animation.z) * animation.scale_z; - - // render noisevalue at this new cartesian point - - float raw_noise_field_value = pnoise(newx, newy, newz); - - // A) enhance histogram (improve contrast) by setting the black and white point (low & high_limit) - // B) scale the result to a 0-255 range (assuming you want 8 bit color depth per rgb chanel) - // Here happens the contrast boosting & the brightness mapping - - if (raw_noise_field_value < animation.low_limit) raw_noise_field_value = animation.low_limit; - if (raw_noise_field_value > animation.high_limit) raw_noise_field_value = animation.high_limit; - - float scaled_noise_value = map_float(raw_noise_field_value, animation.low_limit, animation.high_limit, 0, 255); - - return scaled_noise_value; -} - - -// given a static polar origin we can precalculate -// the polar coordinates - -void render_polar_lookup_table(float cx, float cy) { - - for (int xx = 0; xx < num_x; xx++) { - for (int yy = 0; yy < num_y; yy++) { - - float dx = xx - cx; - float dy = yy - cy; - - distance[xx][yy] = hypotf(dx, dy); - polar_theta[xx][yy] = atan2f(dy, dx); - } - } -} - - - -// float mapping maintaining 32 bit precision -// we keep values with high resolution for potential later usage - -float map_float(float x, float in_min, float in_max, float out_min, float out_max) { - - float result = (x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min; - if (result < out_min) result = out_min; - if( result > out_max) result = out_max; - - return result; -} - - -/* unnecessary bloat - -// check result after colormapping and store the newly rendered rgb data - -void write_pixel_to_framebuffer(int x, int y, rgb &pixel) { - - // assign the final color of this one pixel - CRGB finalcolor = CRGB(pixel.red, pixel.green, pixel.blue); - - // write the rendered pixel into the framebutter - leds[xy(x, y)] = finalcolor; -} -*/ - - -// Avoid any possible color flicker by forcing the raw RGB values to be 0-255. -// This enables to play freely with random equations for the colormapping -// without causing flicker by accidentally missing the valid target range. - -rgb rgb_sanity_check(rgb &pixel) { - - // rescue data if possible, return absolute value - //if (pixel.red < 0) pixel.red = fabsf(pixel.red); - //if (pixel.green < 0) pixel.green = fabsf(pixel.green); - //if (pixel.blue < 0) pixel.blue = fabsf(pixel.blue); - - // discard everything above the valid 8 bit colordepth 0-255 range - if (pixel.red > 255) pixel.red = 255; - if (pixel.green > 255) pixel.green = 255; - if (pixel.blue > 255) pixel.blue = 255; - - return pixel; -} - - -// find the right led index according to you LED matrix wiring - -uint16_t xy(uint8_t x, uint8_t y) { - /* - if (y & 1) // check last bit - return (y + 1) * num_x - 1 - x; // reverse every second line for a serpentine lled layout - else - */ - return y * num_x + x; // use this equation only for a line by line layout -} // remove the previous 3 lines of code in this case - - - diff --git a/smartmatrix.ino b/smartmatrix.ino deleted file mode 100644 index 3fbf20e..0000000 --- a/smartmatrix.ino +++ /dev/null @@ -1,38 +0,0 @@ -void get_ready() { // wait until new buffer is ready, measure time - - a = micros(); - while(backgroundLayer.isSwapPending()); - b = micros(); -} - -void show_frame(){ // swap buffers, measure time, output current performance - - backgroundLayer.swapBuffers(false); - c = micros(); // for time measurement in report_performance() - EVERY_N_MILLIS(500) report_performance(); // check serial monitor for report -} - - -// Show the current framerate, rendered pixels per second, -// rendering time & time spend to push the data to the leds. -// in the serial monitor. - -void report_performance() { - - float calc = b - a; // waiting time - float push = c - b; // rendering time - float total = c - a; // time per frame - int fps = 1000000 / total; // frames per second - int kpps = (fps * num_x * num_y) / 1000; // kilopixel per second - - Serial.print(fps); Serial.print(" fps "); - Serial.print(kpps); Serial.print(" kpps @"); - Serial.print(num_x*num_y); Serial.print(" LEDs "); - Serial.print(round(total)); Serial.print(" µs per frame waiting: "); - Serial.print(round((calc * 100) / total)); Serial.print("% rendering: "); - Serial.print(round((push * 100) / total)); Serial.print("% ("); - Serial.print(round(calc)); Serial.print(" + "); - Serial.print(round(push)); Serial.print(" µs) Core-temp: "); - Serial.print( tempmonGetTemp() ); Serial.println(" °C"); - -}