From 6b8ccdaa0cf0e79dbdc0de2bc3a9c2cf91f7e4ed Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Wed, 17 May 2023 17:33:06 +0100 Subject: [PATCH 01/32] Initial rough first pass at flipping ANIMartRIX to OO library --- animation_collection.ino => ANIMartRIX.h | 630 +++++++++++++++--- .../ANIMartRIX_SmartMatrix.ino | 59 +- merge_methods.ino | 43 -- noise.ino | 63 -- oscillators.ino | 52 -- rendering.ino | 109 --- smartmatrix.ino | 38 -- 7 files changed, 527 insertions(+), 467 deletions(-) rename animation_collection.ino => ANIMartRIX.h (86%) rename AnimARTrix_SmartMatrix.ino => examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino (76%) delete mode 100644 merge_methods.ino delete mode 100644 noise.ino delete mode 100644 oscillators.ino delete mode 100644 rendering.ino delete mode 100644 smartmatrix.ino diff --git a/animation_collection.ino b/ANIMartRIX.h similarity index 86% rename from animation_collection.ino rename to ANIMartRIX.h index e90240d..1dfec5a 100644 --- a/animation_collection.ino +++ b/ANIMartRIX.h @@ -1,8 +1,418 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +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 { + +int num_x; // how many LEDs are in one row? +int num_y; // how many rows? + +#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 + +//#define NUM_LEDS ((num_x) * (num_y)) +CRGB buffer[999]; // TODO // framebuffer + +float polar_theta[999][999]; // look-up table for polar angles +float distance[999][999]; // 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; + + +// 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; // 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); +} + + +// 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 + + + +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 + +// TODO: callback + // backgroundLayer.swapBuffers(false); + // c = micros(); // for time measurement in report_performance() + EVERY_N_MILLIS(500) report_performance(); // check serial monitor for report +} + +CRGB setPixelColor(rgb pixel) { + return CRGB(pixel.red, pixel.green, pixel.blue); +} + +// 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 +465,7 @@ void Rotating_Blob() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -67,7 +477,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 +525,7 @@ void Chasing_Spirals() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -125,7 +535,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 +582,7 @@ void Rings() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -181,7 +591,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 +631,7 @@ void Waves() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -230,7 +640,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 +687,7 @@ void Center_Field() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -288,7 +698,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 +744,7 @@ void Distance_Experiment() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -345,7 +755,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 +811,7 @@ void Caleido1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -410,7 +820,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 +876,7 @@ void Caleido2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -475,7 +885,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 +951,7 @@ void Caleido3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -551,7 +961,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 @@ -606,7 +1016,7 @@ void Lava1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -616,7 +1026,7 @@ 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 @@ -664,7 +1074,7 @@ void Scaledemo1() { pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -674,7 +1084,7 @@ void Scaledemo1() { void Yves() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + a = micros(); // for time measurement in report_performance() @@ -741,7 +1151,7 @@ void Yves() { pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -750,7 +1160,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 +1214,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)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -813,7 +1223,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 +1279,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)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -879,7 +1289,7 @@ void Spiralus2() { void Hot_Blob() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + run_default_oscillators(); @@ -922,7 +1332,7 @@ void Hot_Blob() { // nice one pixel.green = linear * radial* 0.3* (show2-show4); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -932,7 +1342,7 @@ void Zoom() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + run_default_oscillators(); timings.master_speed = 0.003; @@ -963,7 +1373,7 @@ void Zoom() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -976,7 +1386,7 @@ void Slow_Fade() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + run_default_oscillators(); timings.master_speed = 0.00005; @@ -1021,7 +1431,7 @@ void Slow_Fade() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -1032,7 +1442,7 @@ void Polar_Waves() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1075,7 +1485,7 @@ void Polar_Waves() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -1085,7 +1495,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 +1541,7 @@ void RGB_Blobs() { // nice one pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -1141,7 +1551,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 +1594,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)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -1194,7 +1604,7 @@ void RGB_Blobs3() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.12; // master speed @@ -1237,7 +1647,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)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -1247,7 +1657,7 @@ void RGB_Blobs4() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1292,7 +1702,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)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -1302,7 +1712,7 @@ void RGB_Blobs5() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + @@ -1348,7 +1758,7 @@ void RGB_Blobs5() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -1358,7 +1768,7 @@ void Big_Caleido() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1427,7 +1837,7 @@ void Big_Caleido() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } //show_frame(); @@ -1437,7 +1847,7 @@ void SM1() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1511,11 +1921,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)); + buffer[xy(x, y)] = setPixelColor(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)); + buffer[xy(31-x, y)] = setPixelColor(pixel); + buffer[xy(31-x, 31-y)] = setPixelColor(pixel); + buffer[xy(x, 31-y)] = setPixelColor(pixel); } } //show_frame(); @@ -1525,7 +1935,7 @@ void SM2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1579,7 +1989,7 @@ void SM2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } @@ -1591,7 +2001,7 @@ void SM3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1673,7 +2083,7 @@ void SM3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -1684,7 +2094,7 @@ void SM4() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -1730,7 +2140,7 @@ void SM4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } @@ -1741,7 +2151,7 @@ void SM5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1826,7 +2236,7 @@ void SM5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -1836,7 +2246,7 @@ void SM6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -1927,7 +2337,7 @@ void SM6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -1937,7 +2347,7 @@ void SM8() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.06; // master speed @@ -2005,7 +2415,7 @@ void SM8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2015,7 +2425,7 @@ void SM9() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.005; // master speed @@ -2087,7 +2497,7 @@ void SM9() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2096,7 +2506,7 @@ void SM10() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.006; // 0.006 @@ -2170,7 +2580,7 @@ void SM10() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2181,7 +2591,7 @@ void Complex_Kaleido() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.009; // master speed @@ -2259,7 +2669,7 @@ void Complex_Kaleido() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2270,7 +2680,7 @@ void Complex_Kaleido_2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.009; // master speed @@ -2348,7 +2758,7 @@ void Complex_Kaleido_2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2360,7 +2770,7 @@ void Complex_Kaleido_3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.001; // master speed @@ -2447,7 +2857,7 @@ void Complex_Kaleido_3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2456,7 +2866,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 +2964,7 @@ void Complex_Kaleido_4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2563,7 +2973,7 @@ void Complex_Kaleido_5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2605,7 +3015,7 @@ void Complex_Kaleido_5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2614,7 +3024,7 @@ void Complex_Kaleido_6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2664,7 +3074,7 @@ void Complex_Kaleido_6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2673,7 +3083,7 @@ void Water() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.037; // master speed @@ -2752,7 +3162,7 @@ void Water() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2761,7 +3171,7 @@ void Parametric_Water() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.003; // master speed @@ -2846,7 +3256,7 @@ void Parametric_Water() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2855,7 +3265,7 @@ void Module_Experiment1() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed @@ -2884,7 +3294,7 @@ void Module_Experiment1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2893,7 +3303,7 @@ void Module_Experiment2() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.02; // master speed @@ -2924,7 +3334,7 @@ void Module_Experiment2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2933,7 +3343,7 @@ void Module_Experiment3() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed @@ -2964,7 +3374,7 @@ void Module_Experiment3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -2973,7 +3383,7 @@ void Zoom2() { // nice one get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + run_default_oscillators(); timings.master_speed = 0.003; @@ -3004,7 +3414,7 @@ void Zoom2() { // nice one pixel = rgb_sanity_check(pixel); - buffer[kMatrixWidth * y + x] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[num_x * y + x] = setPixelColor(pixel); } } @@ -3014,7 +3424,7 @@ void Module_Experiment4() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.031; // master speed @@ -3081,7 +3491,7 @@ void Module_Experiment4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3090,7 +3500,7 @@ void Module_Experiment5() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.031; // master speed @@ -3125,7 +3535,7 @@ void Module_Experiment5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3134,7 +3544,7 @@ void Module_Experiment6() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3189,7 +3599,7 @@ void Module_Experiment6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3198,7 +3608,7 @@ void Module_Experiment7() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.005; // master speed 0.031 @@ -3254,7 +3664,7 @@ void Module_Experiment7() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3263,7 +3673,7 @@ void Module_Experiment8() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3346,7 +3756,7 @@ void Module_Experiment8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3355,7 +3765,7 @@ void Module_Experiment9() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.03; // master speed 0.031 @@ -3390,7 +3800,7 @@ void Module_Experiment9() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = (rgb24)CRGB(CRGB(pixel.red, pixel.green, pixel.blue)); + buffer[xy(x, y)] = setPixelColor(pixel); } } } @@ -3399,7 +3809,7 @@ void Module_Experiment10() { get_ready(); - rgb24 *buffer = backgroundLayer.backBuffer(); + timings.master_speed = 0.01; // master speed 0.031 @@ -3483,7 +3893,11 @@ void Module_Experiment10() { byte a = millis()/100; - buffer[xy(x, y)] = (rgb24)CRGB( CHSV(((a + show1 + show2) + show3), 255, 255)); + buffer[xy(x, y)] = CRGB( CHSV(((a + show1 + show2) + show3), 255, 255)); } } -} \ No newline at end of file +} + + +}; + diff --git a/AnimARTrix_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino similarity index 76% rename from AnimARTrix_SmartMatrix.ino rename to examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino index 6d20a1e..69c8ab7 100644 --- a/AnimARTrix_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -27,6 +27,7 @@ License CC BY-NC 3.0 #include // SmartLED Shield for Teensy 4 (V5) #include #include +#include #define num_x 32 // how many LEDs are in one row? #define num_y 32 // how many rows? @@ -49,57 +50,7 @@ SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeig //#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; - +ANIMartRIX art; //****************************************************************************************************************** @@ -112,7 +63,7 @@ void setup() { 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 + art.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); @@ -139,7 +90,7 @@ void loop() { //Water(); // nice water simulation //Complex_Kaleido_6(); // red blue moire //Complex_Kaleido_5(); // interference pattern - Complex_Kaleido_4(); // colorful slow mandala + art.Complex_Kaleido_4(); // colorful slow mandala //Complex_Kaleido_3(); //Complex_Kaleido_2(); // hypnotic smooth //Complex_Kaleido(); @@ -177,7 +128,7 @@ void loop() { //Chasing_Spirals(); // slim //Rotating_Blob(); // - show_frame(); + art.show_frame(); } 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"); - -} From 23fdfe6f3674156317864265d6a6156d6b3140c7 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Wed, 17 May 2023 17:43:40 +0100 Subject: [PATCH 02/32] Add ANIMartRIX_FastLED --- .../ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino diff --git a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino new file mode 100644 index 0000000..ee75d3c --- /dev/null +++ b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino @@ -0,0 +1,87 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +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 16 // how many LEDs are in one row? +#define num_y 16 // how many rows? + + +CRGB leds[num_x * num_y]; // framebuffer + +ANIMartRIX art(num_x, num_y, leds); + +//****************************************************************************************************************** + + +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 + + art->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 + +} + +//******************************************************************************************************************* + +void loop() { + + //RGB_Blobs5(); + //RGB_Blobs4(); + //RGB_Blobs3(); + //RGB_Blobs2(); + //RGB_Blobs(); + //Polar_Waves(); + //Slow_Fade(); + //Zoom2(); + //Zoom(); + //Hot_Blob(); + //Spiralus2(); + //Spiralus(); + //Yves(); + //Scaledemo1(); + art->Lava1(); + //Caleido3(); + //Caleido2(); + //Caleido1(); + //Distance_Experiment(); + //Center_Field(); + //Waves(); + //Chasing_Spirals(); + //Rotating_Blob(); + //Rings(); + FastLED.show(); + EVERY_N_MILLIS(500) report_performance(); // check serial monitor for report +} + From 424e4baf919f8ec848dbfe14aa941004523b254c Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Wed, 17 May 2023 19:30:43 +0100 Subject: [PATCH 03/32] First working draft of code as library --- ANIMartRIX.h | 32 ++++---- .../ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino | 74 ++++++++++--------- .../ANIMartRIX_SmartMatrix.ino | 29 ++++---- 3 files changed, 71 insertions(+), 64 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 1dfec5a..9dd17d1 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -94,16 +94,20 @@ static const byte pNoise[] = { 151,160,137,91,90, 15,131, 13,201,95,96, class ANIMartRIX { +public: + int num_x; // how many LEDs are in one row? int num_y; // how many rows? #define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 //#define NUM_LEDS ((num_x) * (num_y)) -CRGB buffer[999]; // TODO // framebuffer +CRGB* buffer; +bool serpentine; -float polar_theta[999][999]; // look-up table for polar angles -float distance[999][999]; // look-up table for polar distances +// TODO set sizes +float polar_theta[99][99]; // look-up table for polar angles +float distance[99][99]; // look-up table for polar distances unsigned long a, b, c; // for time measurements @@ -112,6 +116,14 @@ unsigned long a, b, c; // for time measurements float show1, show2, show3, show4, show5, show6, show7, show8, show9, show0; +ANIMartRIX(int w, int h, struct CRGB *data, bool serpentine) { + this->num_x = w; + this->num_y = h; + this->buffer = data; + this->serpentine = serpentine; + 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 +} // Dynamic darkening methods: @@ -352,31 +364,21 @@ rgb rgb_sanity_check(rgb &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 + 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 - + // TODO: make callback // a = micros(); // while(backgroundLayer.isSwapPending()); // b = micros(); } -void show_frame(){ // swap buffers, measure time, output current performance - -// TODO: callback - // backgroundLayer.swapBuffers(false); - // c = micros(); // for time measurement in report_performance() - EVERY_N_MILLIS(500) report_performance(); // check serial monitor for report -} - CRGB setPixelColor(rgb pixel) { return CRGB(pixel.red, pixel.green, pixel.blue); } diff --git a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino index ee75d3c..fba3726 100644 --- a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino +++ b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino @@ -27,61 +27,63 @@ License CC BY-NC 3.0 #include #include -#define num_x 16 // how many LEDs are in one row? -#define num_y 16 // how many rows? +#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 -CRGB leds[num_x * num_y]; // framebuffer +bool serpentine = true; -ANIMartRIX art(num_x, num_y, leds); +ANIMartRIX art(num_x, num_y, leds, serpentine); //****************************************************************************************************************** void setup() { - // FastLED.addLeds(leds, NUM_LEDS); + // FastLED.addLeds(leds, NUM_LED); - FastLED.addLeds(leds, NUM_LEDS); + FastLED.addLeds(leds, NUM_LED); - //FastLED.setMaxPowerInVoltsAndMilliamps( 5, 2000); // optional current limiting [5V, 2000mA] + FastLED.setMaxPowerInVoltsAndMilliamps( 5, 2000); // optional current limiting [5V, 2000mA] Serial.begin(115200); // check serial monitor for current fps count - art->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 - + // fill_rainbow(leds, NUM_LED, 0); + fill_solid(leds, NUM_LED, CRGB::Green); + FastLED.show(); } //******************************************************************************************************************* void loop() { - - //RGB_Blobs5(); - //RGB_Blobs4(); - //RGB_Blobs3(); - //RGB_Blobs2(); - //RGB_Blobs(); - //Polar_Waves(); - //Slow_Fade(); - //Zoom2(); - //Zoom(); - //Hot_Blob(); - //Spiralus2(); - //Spiralus(); - //Yves(); - //Scaledemo1(); - art->Lava1(); - //Caleido3(); - //Caleido2(); - //Caleido1(); - //Distance_Experiment(); - //Center_Field(); - //Waves(); - //Chasing_Spirals(); - //Rotating_Blob(); - //Rings(); + //FastLED.clear(); + // art.RGB_Blobs5(); + // art.RGB_Blobs4(); + // art.RGB_Blobs3(); + // art.RGB_Blobs2(); + art.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(); FastLED.show(); - EVERY_N_MILLIS(500) report_performance(); // check serial monitor for report + EVERY_N_MILLIS(500) art.report_performance(); // check serial monitor for report } diff --git a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino index 69c8ab7..2ec0922 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -29,8 +29,8 @@ License CC BY-NC 3.0 #include #include -#define num_x 32 // how many LEDs are in one row? -#define num_y 32 // how many rows? +#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 @@ -47,24 +47,20 @@ 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)) +#define NUM_LEDS ((num_x) * (num_y)) CRGB leds[num_x * num_y]; // framebuffer -ANIMartRIX art; +bool serpentine = false; + +ANIMartRIX art(num_x, num_y, leds, serpentine); //****************************************************************************************************************** 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 - - art.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 + // polar origin is set to matrix centre matrix.addLayer(&backgroundLayer); matrix.setBrightness(brightness); matrix.begin(); @@ -128,7 +124,14 @@ void loop() { //Chasing_Spirals(); // slim //Rotating_Blob(); // - art.show_frame(); - + // TODO: nasty hack, but ok for now + rgb24 *buffer = backgroundLayer.backBuffer(); + for(int i = 0; i < NUM_LEDS; i++) { + buffer[i] = leds[i]; + } + + backgroundLayer.swapBuffers(false); + EVERY_N_MILLIS(500) art.report_performance(); // check serial monitor for report + } From ce831738892234c8309a51310b4c32c65173b887 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Wed, 17 May 2023 19:40:13 +0100 Subject: [PATCH 04/32] Allow delaying step to init rather than constructor only --- ANIMartRIX.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 9dd17d1..ccc7ec1 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -116,7 +116,13 @@ 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, struct CRGB *data, bool serpentine) { + this->init(w, h, data, serpentine); +} + +void init(int w, int h, struct CRGB *data, bool serpentine) { this->num_x = w; this->num_y = h; this->buffer = data; From 2ff51b521d32016432eafa35273a7d1225c0e88c Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Tue, 23 May 2023 17:27:27 +0100 Subject: [PATCH 05/32] Tweak polar_theta and distance to more sane values for now --- ANIMartRIX.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index ccc7ec1..915fd08 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -106,8 +106,8 @@ CRGB* buffer; bool serpentine; // TODO set sizes -float polar_theta[99][99]; // look-up table for polar angles -float distance[99][99]; // look-up table for polar distances +float polar_theta[32][32]; // look-up table for polar angles +float distance[32][32]; // look-up table for polar distances unsigned long a, b, c; // for time measurements From f4089cb53110a5cc1c41173918ac73040dc86cbc Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Tue, 23 May 2023 19:01:19 +0100 Subject: [PATCH 06/32] Add setBuffer --- ANIMartRIX.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 915fd08..1e228e5 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -131,6 +131,10 @@ void init(int w, int h, struct CRGB *data, bool serpentine) { // polar origin is set to matrix centre } +void setBuffer(struct CRGB *data) { + this->buffer = data; +} + // Dynamic darkening methods: float subtract(float &a, float&b) { From 5d7a7f1475d51404a9b7d139d6ea1b1206d98056 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 29 May 2023 13:15:48 +0100 Subject: [PATCH 07/32] Remove CRGB from ANIMartRIX, making abstract class where setPixelColor is defined by extension --- ANIMartRIX.h | 135 +++++++++--------- .../ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino | 20 ++- .../ANIMartRIX_SmartMatrix.ino | 35 +++-- 3 files changed, 104 insertions(+), 86 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 1e228e5..9565474 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -101,8 +101,6 @@ int num_y; // how many rows? #define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 -//#define NUM_LEDS ((num_x) * (num_y)) -CRGB* buffer; bool serpentine; // TODO set sizes @@ -118,23 +116,18 @@ float show1, show2, show3, show4, show5, show6, show7, show8, show9, show0; ANIMartRIX() {} -ANIMartRIX(int w, int h, struct CRGB *data, bool serpentine) { - this->init(w, h, data, serpentine); +ANIMartRIX(int w, int h, bool serpentine) { + this->init(w, h, serpentine); } -void init(int w, int h, struct CRGB *data, bool serpentine) { +void init(int w, int h, bool serpentine) { this->num_x = w; this->num_y = h; - this->buffer = data; this->serpentine = serpentine; 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 } -void setBuffer(struct CRGB *data) { - this->buffer = data; -} - // Dynamic darkening methods: float subtract(float &a, float&b) { @@ -389,9 +382,9 @@ void get_ready() { // wait until new buffer is ready, measure time // b = micros(); } -CRGB setPixelColor(rgb pixel) { - return CRGB(pixel.red, pixel.green, pixel.blue); -} +virtual void setPixelColor(int x, int y, rgb pixel) = 0; + +virtual void setPixelColor(int index, rgb pixel) = 0; // Show the current framerate, rendered pixels per second, // rendering time & time spend to push the data to the leds. @@ -477,7 +470,7 @@ void Rotating_Blob() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -537,7 +530,7 @@ void Chasing_Spirals() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -594,7 +587,7 @@ void Rings() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -643,7 +636,7 @@ void Waves() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -699,7 +692,7 @@ void Center_Field() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -756,7 +749,7 @@ void Distance_Experiment() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -823,7 +816,7 @@ void Caleido1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -888,7 +881,7 @@ void Caleido2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -963,7 +956,7 @@ void Caleido3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1028,7 +1021,7 @@ void Lava1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1086,7 +1079,7 @@ void Scaledemo1() { pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1163,7 +1156,7 @@ void Yves() { pixel.blue = 0; pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1226,7 +1219,7 @@ void Spiralus() { pixel.blue = f*(show3-show1); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1291,7 +1284,7 @@ void Spiralus2() { pixel.blue = f*(show3-show1); pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1344,7 +1337,7 @@ void Hot_Blob() { // nice one pixel.green = linear * radial* 0.3* (show2-show4); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1385,7 +1378,7 @@ void Zoom() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1443,7 +1436,7 @@ void Slow_Fade() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1497,7 +1490,7 @@ void Polar_Waves() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1553,7 +1546,7 @@ void RGB_Blobs() { // nice one pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1606,7 +1599,7 @@ void RGB_Blobs2() { // nice one pixel.blue = radial * (show3-show2); pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -1659,7 +1652,7 @@ void RGB_Blobs3() { // nice one pixel.blue = radial * (show3+show2)*0.5 * x/15; pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1714,7 +1707,7 @@ void RGB_Blobs4() { // nice one pixel.blue = radial * (show3+show2)*0.5 * x/15; pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1770,7 +1763,7 @@ void RGB_Blobs5() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -1849,7 +1842,7 @@ void Big_Caleido() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } //show_frame(); @@ -1933,11 +1926,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)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); - buffer[xy(31-x, y)] = setPixelColor(pixel); - buffer[xy(31-x, 31-y)] = setPixelColor(pixel); - buffer[xy(x, 31-y)] = setPixelColor(pixel); + setPixelColor(xy(31-x, y), pixel); + setPixelColor(xy(31-x, 31-y), pixel); + setPixelColor(xy(x, 31-y), pixel); } } //show_frame(); @@ -2001,7 +1994,7 @@ void SM2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } @@ -2095,7 +2088,7 @@ void SM3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -2152,7 +2145,7 @@ void SM4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } @@ -2248,7 +2241,7 @@ void SM5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2349,7 +2342,7 @@ void SM6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2427,7 +2420,7 @@ void SM8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2509,7 +2502,7 @@ void SM9() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2592,7 +2585,7 @@ void SM10() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2681,7 +2674,7 @@ void Complex_Kaleido() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2770,7 +2763,7 @@ void Complex_Kaleido_2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2869,7 +2862,7 @@ void Complex_Kaleido_3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -2976,7 +2969,7 @@ void Complex_Kaleido_4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3027,7 +3020,7 @@ void Complex_Kaleido_5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3086,7 +3079,7 @@ void Complex_Kaleido_6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3174,7 +3167,7 @@ void Water() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3268,7 +3261,7 @@ void Parametric_Water() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3306,7 +3299,7 @@ void Module_Experiment1() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3346,7 +3339,7 @@ void Module_Experiment2() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3386,7 +3379,7 @@ void Module_Experiment3() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3426,7 +3419,7 @@ void Zoom2() { // nice one pixel = rgb_sanity_check(pixel); - buffer[num_x * y + x] = setPixelColor(pixel); + setPixelColor((num_x * y + x), pixel); } } @@ -3503,7 +3496,7 @@ void Module_Experiment4() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3547,7 +3540,7 @@ void Module_Experiment5() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3611,7 +3604,7 @@ void Module_Experiment6() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3676,7 +3669,7 @@ void Module_Experiment7() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3768,7 +3761,7 @@ void Module_Experiment8() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3812,7 +3805,7 @@ void Module_Experiment9() { pixel = rgb_sanity_check(pixel); - buffer[xy(x, y)] = setPixelColor(pixel); + setPixelColor(x, y, pixel); } } } @@ -3904,8 +3897,12 @@ void Module_Experiment10() { pixel = rgb_sanity_check(pixel); byte a = millis()/100; - - buffer[xy(x, y)] = 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); } } } diff --git a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino index fba3726..820125f 100644 --- a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino +++ b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino @@ -35,7 +35,21 @@ CRGB leds[NUM_LED]; // framebuffer bool serpentine = true; -ANIMartRIX art(num_x, num_y, leds, serpentine); +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); //****************************************************************************************************************** @@ -63,7 +77,7 @@ void loop() { // art.RGB_Blobs4(); // art.RGB_Blobs3(); // art.RGB_Blobs2(); - art.RGB_Blobs(); + animatrix.RGB_Blobs(); // art.Polar_Waves(); // art.Slow_Fade(); // art.Zoom2(); @@ -84,6 +98,6 @@ void loop() { // art.Rotating_Blob(); // art.Rings(); FastLED.show(); - EVERY_N_MILLIS(500) art.report_performance(); // check serial monitor for report + 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 index 2ec0922..1a7feed 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -47,12 +47,23 @@ 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 - -bool serpentine = false; - -ANIMartRIX art(num_x, num_y, leds, serpentine); +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); + } +}; +SmartMatrixANIMartRIX animatrix(num_x, num_y); //****************************************************************************************************************** @@ -64,6 +75,7 @@ void setup() { matrix.addLayer(&backgroundLayer); matrix.setBrightness(brightness); matrix.begin(); + animatrix.setBuffer(backgroundLayer.backBuffer()); } //******************************************************************************************************************* @@ -86,7 +98,7 @@ void loop() { //Water(); // nice water simulation //Complex_Kaleido_6(); // red blue moire //Complex_Kaleido_5(); // interference pattern - art.Complex_Kaleido_4(); // colorful slow mandala + animatrix.Complex_Kaleido_4(); // colorful slow mandala //Complex_Kaleido_3(); //Complex_Kaleido_2(); // hypnotic smooth //Complex_Kaleido(); @@ -124,14 +136,9 @@ void loop() { //Chasing_Spirals(); // slim //Rotating_Blob(); // - // TODO: nasty hack, but ok for now - rgb24 *buffer = backgroundLayer.backBuffer(); - for(int i = 0; i < NUM_LEDS; i++) { - buffer[i] = leds[i]; - } - + backgroundLayer.swapBuffers(false); - EVERY_N_MILLIS(500) art.report_performance(); // check serial monitor for report + EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report } From d7c1896166f13fec2917c305222a77e3b504d060 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 29 May 2023 15:04:44 +0100 Subject: [PATCH 08/32] Replace fixed size polar array with dynamic vectors --- ANIMartRIX.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 9565474..82470bb 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -103,9 +103,8 @@ int num_y; // how many rows? bool serpentine; -// TODO set sizes -float polar_theta[32][32]; // look-up table for polar angles -float distance[32][32]; // look-up table for polar distances +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 @@ -302,6 +301,9 @@ float render_value(render_parameters &animation) { 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++) { From b1d35b8602726ea9e93b71f8b63e160487092232 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 29 May 2023 20:39:01 +0100 Subject: [PATCH 09/32] Include --- ANIMartRIX.h | 2 +- examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 82470bb..413accc 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -24,7 +24,7 @@ License CC BY-NC 3.0 */ -//#include +#include #include #define num_oscillators 10 diff --git a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino index 1a7feed..d927237 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -26,7 +26,6 @@ License CC BY-NC 3.0 #include // SmartLED Shield for Teensy 4 (V5) #include -#include #include #define num_x 64 // how many LEDs are in one row? From 647ca37170cade98ef327f9c573b3db714f14e1b Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 29 May 2023 20:48:49 +0100 Subject: [PATCH 10/32] Call method of object --- .../ANIMartRIX_SmartMatrix.ino | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino index d927237..62acd2c 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -82,58 +82,58 @@ void setup() { 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 + //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 - //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(); // + //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(false); From 0d9fe3689034c70a605818fdace4bf1ab9307279 Mon Sep 17 00:00:00 2001 From: netmindz Date: Tue, 30 May 2023 11:10:18 +0100 Subject: [PATCH 11/32] Update ANIMartRIX_SmartMatrix.ino Preserve buffer contents between frames --- examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino index d927237..002ae11 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -136,7 +136,7 @@ void loop() { //Rotating_Blob(); // - backgroundLayer.swapBuffers(false); + backgroundLayer.swapBuffers(true); EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report } From 65bcfc5410464fc9721dd13d11a0e29eaf7a94e5 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Thu, 29 Jun 2023 11:51:48 +0100 Subject: [PATCH 12/32] Add setSpeedFactor --- ANIMartRIX.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 413accc..86506e4 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -99,6 +99,8 @@ class ANIMartRIX { int num_x; // how many LEDs are in one row? int num_y; // how many rows? +float speed_factor = 1; // 0.1 to 10 + #define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 bool serpentine; @@ -127,6 +129,15 @@ void init(int w, int h, bool serpentine) { // polar origin is set to matrix centre } +/** + * @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) { @@ -220,7 +231,7 @@ return lerp(w,lerp(v,lerp(u, grad(P(AA ), x, y, z), /* AND ADD */ void calculate_oscillators(oscillators &timings) { - double runtime = millis() * timings.master_speed; // global anaimation speed + double runtime = millis() * timings.master_speed * speed_factor; // global anaimation speed for (int i = 0; i < num_oscillators; i++) { From af1e52bc9f5ec844869d5ec9cfa251d4103fe9e3 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Thu, 29 Jun 2023 12:22:07 +0100 Subject: [PATCH 13/32] Remove magic values for 31 --- ANIMartRIX.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 86506e4..2f7019c 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -1941,9 +1941,9 @@ void SM1() { // nice one //leds[xy(x, y)] = CRGB(pixel.red, pixel.green, pixel.blue); setPixelColor(x, y, pixel); - setPixelColor(xy(31-x, y), pixel); - setPixelColor(xy(31-x, 31-y), pixel); - setPixelColor(xy(x, 31-y), pixel); + 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(); @@ -2826,7 +2826,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); From baa6802fb86aa55be3cca66fa2049c7038009aa7 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Thu, 29 Jun 2023 12:59:19 +0100 Subject: [PATCH 14/32] make radial_filter_radius runtime value --- ANIMartRIX.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 2f7019c..bc8efc7 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -101,7 +101,7 @@ int num_y; // how many rows? float speed_factor = 1; // 0.1 to 10 -#define radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 +float radial_filter_radius 23.0; // on 32x32, use 11 for 16x16 bool serpentine; @@ -125,6 +125,12 @@ 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 } From f070fefc42febe2de3a2ab5d6d39e78bbc539702 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Thu, 29 Jun 2023 13:04:08 +0100 Subject: [PATCH 15/32] make radial_filter_radius runtime value --- ANIMartRIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index bc8efc7..563bba3 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -101,7 +101,7 @@ 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 +float radial_filter_radius = 23.0; // on 32x32, use 11 for 16x16 bool serpentine; From c7524bda993c9f6320f9863928661daf855e43bc Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 13:22:15 +0100 Subject: [PATCH 16/32] Add ANIMartRIX_FastLED_TeensyDMX example --- .../ANIMartRIX_FastLED_TeensyDMX.ino | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino 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..86d7342 --- /dev/null +++ b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino @@ -0,0 +1,120 @@ + /* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +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 + +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); + + + +//****************************************************************************************************************** + + +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(); + +} + +//******************************************************************************************************************* + +void loop() { + uint8_t v = dmxRx.get(1); // fetch speed + float speedFactor = (float) map(v, 0, 255, 10, 100) / 10.0f; + animatrix.setSpeedFactor(speedFactor); + //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(); + FastLED.show(); + EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report +} + From 2a295255df33ce9ef47f0832b1025d6082736e24 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 14:12:27 +0100 Subject: [PATCH 17/32] Untested attempt at selection of pattern via DMX --- .../ANIMartRIX_FastLED_TeensyDMX.ino | 101 ++++++++++-------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino index 86d7342..58b0f28 100644 --- a/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino +++ b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino @@ -1,4 +1,4 @@ - /* +/* ___ _ ___ ______ _____ _ / _ \ (_) / _ \ | ___ \_ _| (_) / /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ @@ -23,6 +23,8 @@ This code is licenced under a Creative Commons Attribution License CC BY-NC 3.0 */ +#include +#include #include #include @@ -31,27 +33,27 @@ License CC BY-NC 3.0 namespace teensydmx = ::qindesign::teensydmx; -#define num_x 30 // how many LEDs are in one row? -#define num_y 30 // how many rows? +#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 +CRGB leds[NUM_LED]; // framebuffer bool serpentine = true; // Create the DMX receiver on Serial1. -teensydmx::Receiver dmxRx{Serial1}; +teensydmx::Receiver dmxRx{ Serial1 }; class FastLEDANIMartRIX : public ANIMartRIX { CRGB* leds; - public: +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); + 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); @@ -60,61 +62,72 @@ class FastLEDANIMartRIX : public ANIMartRIX { 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] + FastLED.addLeds(leds, NUM_LED); - Serial.begin(115200); // check serial monitor for current fps count - - // fill_rainbow(leds, NUM_LED, 0); + 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() { - uint8_t v = dmxRx.get(1); // fetch speed - float speedFactor = (float) map(v, 0, 255, 10, 100) / 10.0f; - animatrix.setSpeedFactor(speedFactor); //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(); - FastLED.show(); - EVERY_N_MILLIS(500) animatrix.report_performance(); // check serial monitor for report -} + 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); + FastLED.show(); + EVERY_N_MILLIS(500) + animatrix.report_performance(); // check serial monitor for report +} From baf11d5236f30f4fcbed6e3653f28777e9d16ba1 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 14:57:05 +0100 Subject: [PATCH 18/32] Add playlist example --- .../ANIMartRIX_SmartMatrix_Playlist.ino | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino 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..e37d878 --- /dev/null +++ b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino @@ -0,0 +1,173 @@ +/* + ___ _ ___ ______ _____ _ + / _ \ (_) / _ \ | ___ \_ _| (_) +/ /_\ \_ __ _ _ __ ___ / /_\ \| |_/ / | |_ __ ___ __ +| _ | '_ \| | '_ ` _ \| _ || / | | '__| \ \/ / +| | | | | | | | | | | | | | | || |\ \ | | | | |> < +\_| |_/_| |_|_|_| |_| |_\_| |_/\_| \_| \_/_| |_/_/\_\ + +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); + } +}; +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); + + EVERY_N_MILLIS(500) { + animatrix.report_performance(); // check serial monitor for report + } + + EVERY_N_SECONDS( 10 ) { + pattern++; + if(pattern >= gPatternCount) pattern = 0; + } // change patterns periodically + Serial.println("New pattern"); +} + + From dcd76d2611f7c411e11bdf110b9dd1a27b1971d9 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 14:59:54 +0100 Subject: [PATCH 19/32] Add playlist example - enable more patterns --- .../ANIMartRIX_SmartMatrix_Playlist.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino index e37d878..ebec601 100644 --- a/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino +++ b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino @@ -99,8 +99,8 @@ void setup() { // 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_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 @@ -114,7 +114,7 @@ void setup() { // 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::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)); @@ -130,12 +130,12 @@ void setup() { // 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::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::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)); // @@ -166,8 +166,8 @@ void loop() { EVERY_N_SECONDS( 10 ) { pattern++; if(pattern >= gPatternCount) pattern = 0; + Serial.println("New pattern"); } // change patterns periodically - Serial.println("New pattern"); } From 679b9030c3fb7a7392a57c8e0fff8b7076da1fb1 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 17:41:23 +0100 Subject: [PATCH 20/32] Fix performance logging --- ANIMartRIX.h | 14 ++++++++++---- examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino | 2 ++ .../ANIMartRIX_FastLED_TeensyDMX.ino | 2 ++ .../ANIMartRIX_SmartMatrix.ino | 6 ++++++ .../ANIMartRIX_SmartMatrix_Playlist.ino | 6 ++++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 563bba3..7c99382 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -395,16 +395,22 @@ uint16_t xy(uint8_t x, uint8_t y) { void get_ready() { // wait until new buffer is ready, measure time - // TODO: make callback - // a = micros(); - // while(backgroundLayer.isSwapPending()); - // b = micros(); + 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. diff --git a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino index 820125f..ea85030 100644 --- a/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino +++ b/examples/ANIMartRIX_FastLED/ANIMartRIX_FastLED.ino @@ -97,7 +97,9 @@ void loop() { // 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 index 58b0f28..00e8272 100644 --- a/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino +++ b/examples/ANIMartRIX_FastLED_TeensyDMX/ANIMartRIX_FastLED_TeensyDMX.ino @@ -127,7 +127,9 @@ void loop() { 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 index 1fce5ed..ce2cbcf 100644 --- a/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino +++ b/examples/ANIMartRIX_SmartMatrix/ANIMartRIX_SmartMatrix.ino @@ -61,6 +61,11 @@ class SmartMatrixANIMartRIX : public ANIMartRIX { 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); @@ -137,6 +142,7 @@ void loop() { 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 index ebec601..a076424 100644 --- a/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino +++ b/examples/ANIMartRIX_SmartMatrix_Playlist/ANIMartRIX_SmartMatrix_Playlist.ino @@ -65,6 +65,11 @@ class SmartMatrixANIMartRIX : public ANIMartRIX { 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); @@ -158,6 +163,7 @@ void loop() { // animatrix.Lava1(); backgroundLayer.swapBuffers(true); + animatrix.logFrame(); EVERY_N_MILLIS(500) { animatrix.report_performance(); // check serial monitor for report From b41f04fae43bc5184ff689d8ce763e6267a622e9 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Mon, 3 Jul 2023 18:02:07 +0100 Subject: [PATCH 21/32] Add ANIMartRIX_SmartMatrix_TeensyDMX --- .../ANIMartRIX_SmartMatrix_TeensyDMX.ino | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 examples/ANIMartRIX_SmartMatrix_TeensyDMX/ANIMartRIX_SmartMatrix_TeensyDMX.ino 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 + } + +} + + From 8fd0df3e0b006244d53eaf480c2720daa5a697aa Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Tue, 17 Oct 2023 18:53:03 +0100 Subject: [PATCH 22/32] Always set all 3 values for rgb pixel data --- ANIMartRIX.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 7c99382..4da5274 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -1043,6 +1043,7 @@ void Lava1() { pixel.red = linear*show2; pixel.green = 0.1*linear*(show2-show3); + pixel.blue = 0; pixel = rgb_sanity_check(pixel); @@ -1360,6 +1361,7 @@ 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); setPixelColor(x, y, pixel); @@ -1400,6 +1402,7 @@ void Zoom() { // nice one pixel.red = show1*linear; pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); @@ -3042,6 +3045,8 @@ 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); @@ -3100,6 +3105,7 @@ 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); @@ -3183,8 +3189,9 @@ void Water() { //pixel.red = show2; - pixel.blue = (0.7*show2+0.6*show3+0.5*show4); pixel.red = pixel.blue-40; + pixel.green = 0; + pixel.blue = (0.7*show2+0.6*show3+0.5*show4); //pixel.red = radial*show3; //pixel.green = 0.9*radial*show4; @@ -3278,8 +3285,9 @@ 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; @@ -3320,6 +3328,8 @@ 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); @@ -3440,6 +3450,7 @@ void Zoom2() { // nice one //float linear = 1;//(y+1)/(num_y-1.f); pixel.red = show1; + pixel.green = 0; pixel.blue = 40-show1; @@ -3561,6 +3572,8 @@ void Module_Experiment5() { pixel.red = show1; + pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); @@ -3827,6 +3840,8 @@ void Module_Experiment9() { show1 = render_value(animation); pixel.red = 10*show1; + pixel.green = 0; + pixel.blue = 0; pixel = rgb_sanity_check(pixel); From eaa27af44340a988a3dc2806f86323e924e18d2e Mon Sep 17 00:00:00 2001 From: netmindz Date: Sat, 21 Oct 2023 21:54:57 +0100 Subject: [PATCH 23/32] Update ANIMartRIX.h reset ordering of params in water --- ANIMartRIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 4da5274..d1c6e38 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -3189,9 +3189,9 @@ void Water() { //pixel.red = show2; + pixel.blue = (0.7*show2+0.6*show3+0.5*show4); pixel.red = pixel.blue-40; pixel.green = 0; - pixel.blue = (0.7*show2+0.6*show3+0.5*show4); //pixel.red = radial*show3; //pixel.green = 0.9*radial*show4; From 18bf17389e57c69f11bc8d04ebe1d215422c7fb7 Mon Sep 17 00:00:00 2001 From: netmindz Date: Sat, 21 Oct 2023 22:13:55 +0100 Subject: [PATCH 24/32] Update ANIMartRIX.h Fix rgb_sanity_check --- ANIMartRIX.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index d1c6e38..4c4d88c 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -373,7 +373,13 @@ rgb rgb_sanity_check(rgb &pixel) { //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; From 091c6b4055704a2faa2508aad2057755ed871d9f Mon Sep 17 00:00:00 2001 From: netmindz Date: Sun, 17 Mar 2024 14:55:03 +0000 Subject: [PATCH 25/32] Update ANIMartRIX.h --- ANIMartRIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 4c4d88c..61d07b9 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -2388,7 +2388,7 @@ void SM8() { - timings.master_speed = 0.06; // master speed + timings.master_speed = 0.03; // master speed timings.ratio[0] = 0.025; // speed ratios for the oscillators, higher values = faster transitions timings.ratio[1] = 0.027; From b93e6d596dcda712ab712ba6daabc81c534494ee Mon Sep 17 00:00:00 2001 From: netmindz Date: Sat, 23 Nov 2024 17:06:27 +0000 Subject: [PATCH 26/32] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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. From c06a893a03aac42d95853ed6e75b6ed33c777031 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 17:51:32 +0000 Subject: [PATCH 27/32] Set default timings.master_speed --- ANIMartRIX.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 4da5274..3882b5d 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -133,6 +133,9 @@ void init(int w, int h, bool serpentine) { } 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 + } /** From 482854b0616e2ed3db45d26cb1f8f7dda37220e9 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 17:52:00 +0000 Subject: [PATCH 28/32] Fix negative colour values --- ANIMartRIX.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 3882b5d..a6573fb 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -376,7 +376,13 @@ rgb rgb_sanity_check(rgb &pixel) { //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; From 955250bb9fec8dddd724c7cb280a08e6c3d41751 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 17:58:35 +0000 Subject: [PATCH 29/32] Slow down SM8 --- ANIMartRIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index a6573fb..1311bab 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -2391,7 +2391,7 @@ void SM8() { - timings.master_speed = 0.06; // master speed + timings.master_speed = 0.005; // master speed timings.ratio[0] = 0.025; // speed ratios for the oscillators, higher values = faster transitions timings.ratio[1] = 0.027; From 3a37ff8cfa4252efa846def0f3d079d9324d8b2b Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 18:16:20 +0000 Subject: [PATCH 30/32] Fix redundant calling of calculate_oscillators --- ANIMartRIX.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 1311bab..6a863ea 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -258,8 +258,6 @@ void calculate_oscillators(oscillators &timings) { 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; @@ -1330,7 +1328,7 @@ void Hot_Blob() { // nice one get_ready(); - + timings.master_speed = 0.005; // master speed run_default_oscillators(); for (int x = 0; x < num_x; x++) { @@ -1385,9 +1383,8 @@ void Zoom() { // nice one - 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++) { @@ -1430,9 +1427,8 @@ void Slow_Fade() { // nice one - 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++) { @@ -3434,9 +3430,8 @@ void Zoom2() { // nice one - 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++) { From 83e69893426929ee2bdf53cde2d3ef1413621091 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 18:31:55 +0000 Subject: [PATCH 31/32] More sane speed values for Scaledemo1 --- ANIMartRIX.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index 6a863ea..b2d9e4b 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -1067,9 +1067,9 @@ void Scaledemo1() { 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; From ccb11dd9a4ec4ff6e7bdf617f6651cced4ed9826 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 23 Nov 2024 18:32:34 +0000 Subject: [PATCH 32/32] More sane speed for Hot_Blob --- ANIMartRIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ANIMartRIX.h b/ANIMartRIX.h index b2d9e4b..f347428 100644 --- a/ANIMartRIX.h +++ b/ANIMartRIX.h @@ -1328,7 +1328,7 @@ void Hot_Blob() { // nice one get_ready(); - timings.master_speed = 0.005; // master speed + timings.master_speed = 0.001; // master speed run_default_oscillators(); for (int x = 0; x < num_x; x++) {