From 0e4e9738b6ecbffa260cc8e5e8e4c4d9f1bf6499 Mon Sep 17 00:00:00 2001 From: Kosso Date: Sun, 13 Sep 2020 15:56:29 +0100 Subject: [PATCH] Kosso: Updated Aurora demo for chained virtual displays. Added a better Fire demo. Removed some old Aurora demos which just didn't work and saves some memory. --- examples/ChainedPanelsAuroraDemo/Attractor.h | 50 + examples/ChainedPanelsAuroraDemo/Boid.h | 326 +++++++ .../ChainedPanelsAuroraDemo.ino | 181 ++++ examples/ChainedPanelsAuroraDemo/Drawable.h | 50 + examples/ChainedPanelsAuroraDemo/Effects.h | 914 ++++++++++++++++++ examples/ChainedPanelsAuroraDemo/Geometry.h | 150 +++ .../ChainedPanelsAuroraDemo/PaletteFireKoz.h | 6 + .../ChainedPanelsAuroraDemo/PatternAttract.h | 73 ++ .../PatternElectricMandala.h | 116 +++ .../ChainedPanelsAuroraDemo/PatternFire.h | 121 +++ .../ChainedPanelsAuroraDemo/PatternFireKoz.h | 109 +++ .../ChainedPanelsAuroraDemo/PatternFlock.h | 125 +++ .../PatternFlowField.h | 92 ++ .../PatternIncrementalDrift.h | 51 + .../ChainedPanelsAuroraDemo/PatternInfinity.h | 58 ++ .../ChainedPanelsAuroraDemo/PatternLife.h | 129 +++ .../ChainedPanelsAuroraDemo/PatternMaze.h | 264 +++++ .../ChainedPanelsAuroraDemo/PatternMunch.h | 74 ++ .../PatternNoiseSmearing.h | 338 +++++++ .../PatternPendulumWave.h | 56 ++ .../ChainedPanelsAuroraDemo/PatternPlasma.h | 66 ++ .../ChainedPanelsAuroraDemo/PatternRadar.h | 56 ++ .../PatternSimplexNoise.h | 79 ++ .../ChainedPanelsAuroraDemo/PatternSnake.h | 145 +++ .../ChainedPanelsAuroraDemo/PatternSpiral.h | 138 +++ .../ChainedPanelsAuroraDemo/PatternSpiro.h | 107 ++ .../ChainedPanelsAuroraDemo/PatternSwirl.h | 77 ++ .../ChainedPanelsAuroraDemo/PatternWave.h | 120 +++ examples/ChainedPanelsAuroraDemo/Patterns.h | 259 +++++ examples/ChainedPanelsAuroraDemo/Playlist.h | 39 + examples/ChainedPanelsAuroraDemo/Vector.h | 169 ++++ 31 files changed, 4538 insertions(+) create mode 100644 examples/ChainedPanelsAuroraDemo/Attractor.h create mode 100644 examples/ChainedPanelsAuroraDemo/Boid.h create mode 100644 examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino create mode 100644 examples/ChainedPanelsAuroraDemo/Drawable.h create mode 100644 examples/ChainedPanelsAuroraDemo/Effects.h create mode 100644 examples/ChainedPanelsAuroraDemo/Geometry.h create mode 100644 examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternAttract.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternFire.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternFireKoz.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternFlock.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternFlowField.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternInfinity.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternLife.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternMaze.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternMunch.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternPlasma.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternRadar.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternSnake.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternSpiral.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternSpiro.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternSwirl.h create mode 100644 examples/ChainedPanelsAuroraDemo/PatternWave.h create mode 100644 examples/ChainedPanelsAuroraDemo/Patterns.h create mode 100644 examples/ChainedPanelsAuroraDemo/Playlist.h create mode 100644 examples/ChainedPanelsAuroraDemo/Vector.h diff --git a/examples/ChainedPanelsAuroraDemo/Attractor.h b/examples/ChainedPanelsAuroraDemo/Attractor.h new file mode 100644 index 0000000..5a03511 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Attractor.h @@ -0,0 +1,50 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Attractor" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "Vector.h" + +class Attractor { +public: + float mass; // Mass, tied to size + float G; // Gravitational Constant + PVector location; // Location + + Attractor() { + location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y); + mass = 8; + G = .5; + } + + PVector attract(Boid m) { + PVector force = location - m.location; // Calculate direction of force + float d = force.mag(); // Distance between objects + d = constrain(d, 5.0, 32.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects + force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction) + float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude + force *= strength; // Get force vector --> magnitude * direction + return force; + } +}; diff --git a/examples/ChainedPanelsAuroraDemo/Boid.h b/examples/ChainedPanelsAuroraDemo/Boid.h new file mode 100644 index 0000000..fa5a9e6 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Boid.h @@ -0,0 +1,326 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Boid class +// Methods for Separation, Cohesion, Alignment added + +class Boid { + public: + + PVector location; + PVector velocity; + PVector acceleration; + float maxforce; // Maximum steering force + float maxspeed; // Maximum speed + + float desiredseparation = 4; + float neighbordist = 8; + byte colorIndex = 0; + float mass; + + boolean enabled = true; + + Boid() {} + + Boid(float x, float y) { + acceleration = PVector(0, 0); + velocity = PVector(randomf(), randomf()); + location = PVector(x, y); + maxspeed = 1.5; + maxforce = 0.05; + } + + static float randomf() { + return mapfloat(random(0, 255), 0, 255, -.5, .5); + } + + static float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } + + void run(Boid boids [], uint8_t boidCount) { + flock(boids, boidCount); + update(); + // wrapAroundBorders(); + // render(); + } + + // Method to update location + void update() { + // Update velocity + velocity += acceleration; + // Limit speed + velocity.limit(maxspeed); + location += velocity; + // Reset acceleration to 0 each cycle + acceleration *= 0; + } + + void applyForce(PVector force) { + // We could add mass here if we want A = F / M + acceleration += force; + } + + void repelForce(PVector obstacle, float radius) { + //Force that drives boid away from obstacle. + + PVector futPos = location + velocity; //Calculate future position for more effective behavior. + PVector dist = obstacle - futPos; + float d = dist.mag(); + + if (d <= radius) { + PVector repelVec = location - obstacle; + repelVec.normalize(); + if (d != 0) { //Don't divide by zero. + // float scale = 1.0 / d; //The closer to the obstacle, the stronger the force. + repelVec.normalize(); + repelVec *= (maxforce * 7); + if (repelVec.mag() < 0) { //Don't let the boids turn around to avoid the obstacle. + repelVec.y = 0; + } + } + applyForce(repelVec); + } + } + + // We accumulate a new acceleration each time based on three rules + void flock(Boid boids [], uint8_t boidCount) { + PVector sep = separate(boids, boidCount); // Separation + PVector ali = align(boids, boidCount); // Alignment + PVector coh = cohesion(boids, boidCount); // Cohesion + // Arbitrarily weight these forces + sep *= 1.5; + ali *= 1.0; + coh *= 1.0; + // Add the force vectors to acceleration + applyForce(sep); + applyForce(ali); + applyForce(coh); + } + + // Separation + // Method checks for nearby boids and steers away + PVector separate(Boid boids [], uint8_t boidCount) { + PVector steer = PVector(0, 0); + int count = 0; + // For every boid in the system, check if it's too close + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + PVector diff = location - other.location; + diff.normalize(); + diff /= d; // Weight by distance + steer += diff; + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer /= (float) count; + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer *= maxspeed; + steer -= velocity; + steer.limit(maxforce); + } + return steer; + } + + // Alignment + // For every nearby boid in the system, calculate the average velocity + PVector align(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.velocity; + count++; + } + } + if (count > 0) { + sum /= (float) count; + sum.normalize(); + sum *= maxspeed; + PVector steer = sum - velocity; + steer.limit(maxforce); + return steer; + } + else { + return PVector(0, 0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + PVector cohesion(Boid boids [], uint8_t boidCount) { + PVector sum = PVector(0, 0); // Start with empty vector to accumulate all locations + int count = 0; + for (int i = 0; i < boidCount; i++) { + Boid other = boids[i]; + if (!other.enabled) + continue; + float d = location.dist(other.location); + if ((d > 0) && (d < neighbordist)) { + sum += other.location; // Add location + count++; + } + } + if (count > 0) { + sum /= count; + return seek(sum); // Steer towards the location + } + else { + return PVector(0, 0); + } + } + + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + PVector seek(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired *= maxspeed; + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + return steer; + } + + // A method that calculates a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + void arrive(PVector target) { + PVector desired = target - location; // A vector pointing from the location to the target + float d = desired.mag(); + // Normalize desired and scale with arbitrary damping within 100 pixels + desired.normalize(); + if (d < 4) { + float m = map(d, 0, 100, 0, maxspeed); + desired *= m; + } + else { + desired *= maxspeed; + } + + // Steering = Desired minus Velocity + PVector steer = desired - velocity; + steer.limit(maxforce); // Limit to maximum steering force + applyForce(steer); + //Serial.println(d); + } + + void wrapAroundBorders() { + if (location.x < 0) location.x = VPANEL_W - 1; + if (location.y < 0) location.y = VPANEL_H - 1; + if (location.x >= VPANEL_W) location.x = 0; + if (location.y >= VPANEL_H) location.y = 0; + } + + void avoidBorders() { + PVector desired = velocity; + + if (location.x < 8) desired = PVector(maxspeed, velocity.y); + if (location.x >= VPANEL_W - 8) desired = PVector(-maxspeed, velocity.y); + if (location.y < 8) desired = PVector(velocity.x, maxspeed); + if (location.y >= VPANEL_H - 8) desired = PVector(velocity.x, -maxspeed); + + if (desired != velocity) { + PVector steer = desired - velocity; + steer.limit(maxforce); + applyForce(steer); + } + + if (location.x < 0) location.x = 0; + if (location.y < 0) location.y = 0; + if (location.x >= VPANEL_W) location.x = VPANEL_W - 1; + if (location.y >= VPANEL_H) location.y = VPANEL_H - 1; + } + + bool bounceOffBorders(float bounce) { + bool bounced = false; + + if (location.x >= VPANEL_W) { + location.x = VPANEL_W - 1; + velocity.x *= -bounce; + bounced = true; + } + else if (location.x < 0) { + location.x = 0; + velocity.x *= -bounce; + bounced = true; + } + + if (location.y >= VPANEL_H) { + location.y = VPANEL_H - 1; + velocity.y *= -bounce; + bounced = true; + } + else if (location.y < 0) { + location.y = 0; + velocity.y *= -bounce; + bounced = true; + } + + return bounced; + } + + void render() { + //// Draw a triangle rotated in the direction of velocity + //float theta = velocity.heading2D() + radians(90); + //fill(175); + //stroke(0); + //pushMatrix(); + //translate(location.x,location.y); + //rotate(theta); + //beginShape(TRIANGLES); + //vertex(0, -r*2); + //vertex(-r, r*2); + //vertex(r, r*2); + //endShape(); + //popMatrix(); + //matrix.drawBackgroundPixelRGB888(location.x, location.y, CRGB::Blue); + } +}; + +static const uint8_t AVAILABLE_BOID_COUNT = 40; +Boid boids[AVAILABLE_BOID_COUNT]; diff --git a/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino b/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino new file mode 100644 index 0000000..1dddd56 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino @@ -0,0 +1,181 @@ +/* ------------------------- CUSTOM GPIO PIN MAPPING ------------------------- */ +// Kosso's ESP32 Matrix PCB pins +#define R1_PIN 2 +#define G1_PIN 15 +#define B1_PIN 4 +#define R2_PIN 16 +#define G2_PIN 13 +#define B2_PIN 17 +#define A_PIN 5 +#define B_PIN 18 +#define C_PIN 19 +#define D_PIN 27 +#define E_PIN -1 +#define LAT_PIN 21 +#define OE_PIN 23 +#define CLK_PIN 22 + + +/* -------------------------- Display Config Initialisation -------------------- */ +#define MATRIX_WIDTH 128 // Overall matrix dimensions if laid out end-to-end. +#define MATRIX_HEIGHT 32 + +#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module. +#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module. + +#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS +#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW + +// Virtual Panl dimensions +#define VPANEL_W 64 // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these. +#define VPANEL_H 64 // + +// Kosso added: Button with debounce +#define BTN_PIN 0 // Pattern advance. Using EPS32 Boot button. +int buttonState; // the current reading from the input pin +int lastButtonState = LOW; // the previous reading from the input pin +unsigned long lastDebounceTime = 0; // the last time the output pin was toggled +unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers + +// The palettes are set to change every 60 seconds. + +// Kosso added: Non-volatile memory to save last pattern index. +#include +Preferences preferences; +int lastPattern = 0; + + +/* -------------------------- Class Initialisation -------------------------- */ +//#include +//RGB64x32MatrixPanel_I2S_DMA matrix; + +#include +RGB64x32MatrixPanel_I2S_DMA matrix; +// Added support for 'Chained' virtual panel configurations. +VirtualMatrixPanel virtualDisp(matrix, NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, true); + +#include // Used for some mathematics calculations and effects. + +#include "Effects.h" +Effects effects; + +#include "Drawable.h" +#include "Playlist.h" +//#include "Geometry.h" + +#include "Patterns.h" +Patterns patterns; + +/* -------------------------- Some variables -------------------------- */ +unsigned long ms_current = 0; +unsigned long ms_previous = 0; +unsigned long ms_animation_max_duration = 60000; // 10 seconds +unsigned long next_frame = 0; + +void setup() +{ + // Setup serial interface + Serial.begin(115200); + delay(250); + + // Added a button to manually advance the pattern index. + pinMode(BTN_PIN, INPUT); + // For saving last pattern index. TO reboot with same. + preferences.begin("RGBMATRIX", false); + lastPattern = preferences.getInt("lastPattern", 0); + + matrix.setPanelBrightness(30); + matrix.setMinRefreshRate(200); + + + matrix.begin(R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN ); // setup the LED matrix + + virtualDisp.fillScreen(virtualDisp.color444(0, 0, 0)); + + Serial.println("**************** Starting Aurora Effects Demo ****************"); + + Serial.println("MATRIX_WIDTH " + String(MATRIX_WIDTH)); + Serial.println("MATRIX_HEIGHT " + String(MATRIX_HEIGHT)); + +#ifdef VPANEL_W + Serial.println("VIRTUAL PANEL WIDTH " + String(VPANEL_W)); + Serial.println("VIRTUAL PANEL HEIGHT " + String(VPANEL_H)); +#endif + + // setup the effects generator + effects.Setup(); + + delay(500); + Serial.println("Effects being loaded: "); + listPatterns(); + + Serial.println("LastPattern index: " + String(lastPattern)); + + patterns.setPattern(lastPattern); // // simple noise + patterns.start(); + + Serial.print("Starting with pattern: "); + Serial.println(patterns.getCurrentPatternName()); + + preferences.end(); + +} + + +void patternAdvance(){ + // Go to next pattern in the list (se Patterns.h) + patterns.stop(); + patterns.move(1); + patterns.start(); + // Select a random palette as well + effects.RandomPalette(); + Serial.print("Changing pattern to: "); + Serial.println(patterns.getCurrentPatternName()); + Serial.println(patterns.getPatternIndex()); + lastPattern = patterns.getPatternIndex(); + // Save last index. + preferences.begin("RGBMATRIX", false); + preferences.putInt("lastPattern", lastPattern); + preferences.end(); + +} + +void loop() +{ + // Boot button Pattern advance with debounce + int reading = digitalRead(BTN_PIN); + if (reading != lastButtonState) { + lastDebounceTime = millis(); + } + + if ((millis() - lastDebounceTime) > debounceDelay) { + if (reading != buttonState) { + buttonState = reading; + if (buttonState == LOW) { + Serial.println("NEXT PATTERN ..."); + patternAdvance(); + } + } + } + lastButtonState = reading; + // end button debounce + + ms_current = millis(); + + if ( (ms_current - ms_previous) > ms_animation_max_duration ) + { + // patternAdvance(); + // just auto-change the palette + effects.RandomPalette(); + ms_previous = ms_current; + } + + if ( next_frame < ms_current) + next_frame = patterns.drawFrame() + ms_current; + +} + + +void listPatterns() { + patterns.listPatterns(); +} diff --git a/examples/ChainedPanelsAuroraDemo/Drawable.h b/examples/ChainedPanelsAuroraDemo/Drawable.h new file mode 100644 index 0000000..6e97098 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Drawable.h @@ -0,0 +1,50 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Drawable_H +#define Drawable_H + +class Drawable{ +public: + char* name; + + virtual bool isRunnable() { + return false; + } + + virtual bool isPlaylist() { + return false; + } + + // a single frame should be drawn as fast as possible, without any delay or blocking + // return how many millisecond delay is requested before the next call to drawFrame() + virtual unsigned int drawFrame() { + matrix.fillScreen(0); + //backgroundLayer.fillScreen({ 0, 0, 0 }); + return 0; + }; + + virtual void start() {}; + virtual void stop() {}; +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/Effects.h b/examples/ChainedPanelsAuroraDemo/Effects.h new file mode 100644 index 0000000..8ca709e --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Effects.h @@ -0,0 +1,914 @@ + +/* + Aurora: https://github.com/pixelmatix/aurora + Copyright (c) 2014 Jason Coon + + Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35 + Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a + Copyright (c) 2014 Stefan Petrick + http://www.stefan-petrick.de/wordpress_beta + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef Effects_H +#define Effects_H + +/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */ + +//const int MATRIX_CENTER_X = MATRIX_WIDTH / 2; +//const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2; +//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1; +//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1; + +const int MATRIX_CENTER_X = VPANEL_W / 2; +const int MATRIX_CENTER_Y = VPANEL_H / 2; +const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1; +const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1; + +const uint16_t NUM_LEDS = (VPANEL_W * VPANEL_H) + 1; // one led spare to capture out of bounds + +/* Convert x,y co-ordinate to flat array index. + x and y positions start from 0, so must not be >= 'real' panel width or height + (i.e. 64 pixels or 32 pixels.). Max value: MATRIX_WIDTH-1 etc. +*/ +uint16_t XY( uint8_t x, uint8_t y) +{ + if ( x >= VPANEL_W || x < 0) return 0; + if ( y >= VPANEL_H || y < 0) return 0; + + return (y * VPANEL_W) + x + 1; // everything offset by one to capture out of bounds stuff - never displayed by ShowFrame() + +} + +/// Some mathematics provided by FastLED +uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0) +{ + uint8_t beat = beat8(beats_per_minute, timebase); + uint8_t beatcos = cos8(beat + phase_offset); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapsin8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatsin = sin8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatsin, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +uint8_t mapcos8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) { + uint8_t beatcos = cos8(theta); + uint8_t rangewidth = highest - lowest; + uint8_t scaledbeat = scale8(beatcos, rangewidth); + uint8_t result = lowest + scaledbeat; + return result; +} + +// Array of temperature readings at each simulation cell +byte heat[NUM_LEDS]; + +uint32_t noise_x; +uint32_t noise_y; +uint32_t noise_z; +uint32_t noise_scale_x; +uint32_t noise_scale_y; + +uint8_t noise[VPANEL_W][VPANEL_H]; +uint8_t noisesmoothing; + +class Effects { + public: + //CRGB *leds; + CRGB leds[NUM_LEDS]; + CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k). + + + /* The only 'framebuffer' we have is what is contained in the leds and leds2 variables. + We don't store what the color a particular pixel might be, other than when it's turned + into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible. + + As such, any time these effects want to write a pixel color, we first have to update + the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame(). + */ + void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color) + { + leds[XY(x, y)] = color; + virtualDisp.drawPixelRGB888(x, y, color.r, color.g, color.b); + } + + // write one pixel with the specified color from the current palette to coordinates + void Pixel(int x, int y, uint8_t colorIndex) { + CRGB temp = ColorFromCurrentPalette(colorIndex); + leds[XY(x, y)] = temp; + virtualDisp.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it? + } + + void PrepareFrame() { + // leds = (CRGB*) backgroundLayer.backBuffer(); + } + + void ShowFrame() { +#if (FASTLED_VERSION >= 3001000) + nblendPaletteTowardPalette(currentPalette, targetPalette, 24); +#else + currentPalette = targetPalette; +#endif + // backgroundLayer.swapBuffers(); + // leds = (CRGB*) backgroundLayer.backBuffer(); + // LEDS.countFPS(); + for (int y = 0; y < VPANEL_H; y++) { + for (int x = 0; x < VPANEL_W; x++) + { + CRGB tmp_led = leds[XY(x, y)]; + virtualDisp.drawPixelRGB888( x, y, tmp_led.r, tmp_led.g, tmp_led.b); + } // end loop to copy fast led to the dma matrix + } + } + + + // scale the brightness of the screenbuffer down + void DimAll(byte value) + { + for (int i = 0; i < NUM_LEDS; i++) + { + leds[i].nscale8(value); + } + } + + void ClearFrame() + { + memset(leds, 0x00, sizeof(leds)); // flush + } + + + + + void CircleStream(uint8_t value) { + DimAll(value); ShowFrame(); + + for (uint8_t offset = 0; offset < MATRIX_CENTER_X; offset++) { + boolean hasprev = false; + uint16_t prevxy = 0; + + for (uint8_t theta = 0; theta < 255; theta++) { + uint8_t x = mapcos8(theta, offset, (VPANEL_W - 1) - offset); + uint8_t y = mapsin8(theta, offset, (VPANEL_H - 1) - offset); + + uint16_t xy = XY(x, y); + + if (hasprev) { + leds[prevxy] += leds[xy]; + } + + prevxy = xy; + hasprev = true; + } + } + + for (uint8_t x = 0; x < VPANEL_W; x++) { + for (uint8_t y = 0; y < VPANEL_H; y++) { + uint16_t xy = XY(x, y); + leds[xy] = leds2[xy]; + leds[xy].nscale8(value); + leds2[xy].nscale8(value); + } + } + } + + + // palettes + static const int paletteCount = 10; + int paletteIndex = -1; + TBlendType currentBlendType = LINEARBLEND; + CRGBPalette16 currentPalette; + CRGBPalette16 targetPalette; + char* currentPaletteName; + + static const int HeatColorsPaletteIndex = 6; + static const int RandomPaletteIndex = 9; + + void Setup() { + currentPalette = RainbowColors_p; + loadPalette(0); + NoiseVariablesSetup(); + } + + void CyclePalette(int offset = 1) { + loadPalette(paletteIndex + offset); + } + + void RandomPalette() { + loadPalette(RandomPaletteIndex); + } + + void loadPalette(int index) { + paletteIndex = index; + + if (paletteIndex >= paletteCount) + paletteIndex = 0; + else if (paletteIndex < 0) + paletteIndex = paletteCount - 1; + + switch (paletteIndex) { + case 0: + targetPalette = RainbowColors_p; + currentPaletteName = (char *)"Rainbow"; + break; + case 1: + targetPalette = OceanColors_p; + currentPaletteName = (char *)"Ocean"; + break; + case 2: + targetPalette = CloudColors_p; + currentPaletteName = (char *)"Cloud"; + break; + case 3: + targetPalette = ForestColors_p; + currentPaletteName = (char *)"Forest"; + break; + case 4: + targetPalette = PartyColors_p; + currentPaletteName = (char *)"Party"; + break; + case 5: + setupGrayscalePalette(); + currentPaletteName = (char *)"Grey"; + break; + case HeatColorsPaletteIndex: + targetPalette = HeatColors_p; + currentPaletteName = (char *)"Heat"; + break; + case 7: + targetPalette = LavaColors_p; + currentPaletteName = (char *)"Lava"; + break; + case 8: + setupIcePalette(); + currentPaletteName = (char *)"Ice"; + break; + case RandomPaletteIndex: + loadPalette(random(0, paletteCount - 1)); + paletteIndex = RandomPaletteIndex; + currentPaletteName = (char *)"Random"; + break; + } + } + + void setPalette(String paletteName) { + if (paletteName == "Rainbow") + loadPalette(0); + else if (paletteName == "Ocean") + loadPalette(1); + else if (paletteName == "Cloud") + loadPalette(2); + else if (paletteName == "Forest") + loadPalette(3); + else if (paletteName == "Party") + loadPalette(4); + else if (paletteName == "Grayscale") + loadPalette(5); + else if (paletteName == "Heat") + loadPalette(6); + else if (paletteName == "Lava") + loadPalette(7); + else if (paletteName == "Ice") + loadPalette(8); + else if (paletteName == "Random") + RandomPalette(); + } + + void listPalettes() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(paletteCount); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + String paletteNames [] = { + "Rainbow", + // "RainbowStripe", + "Ocean", + "Cloud", + "Forest", + "Party", + "Grayscale", + "Heat", + "Lava", + "Ice", + "Random" + }; + + for (int i = 0; i < paletteCount; i++) { + Serial.print(F(" \"")); + Serial.print(paletteNames[i]); + if (i == paletteCount - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + void setupGrayscalePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::White); + } + + void setupIcePalette() { + targetPalette = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White); + } + + // Oscillators and Emitters + + // the oscillators: linear ramps 0-255 + byte osci[6]; + + // sin8(osci) swinging between 0 to MATRIX_WIDTH - 1 + byte p[6]; + + // set the speeds (and by that ratios) of the oscillators here + void MoveOscillators() { + osci[0] = osci[0] + 5; + osci[1] = osci[1] + 2; + osci[2] = osci[2] + 3; + osci[3] = osci[3] + 4; + osci[4] = osci[4] + 1; + if (osci[4] % 2 == 0) + osci[5] = osci[5] + 1; // .5 + for (int i = 0; i < 4; i++) { + p[i] = map8(sin8(osci[i]), 0, VPANEL_W - 1); //why? to keep the result in the range of 0-MATRIX_WIDTH (matrix size) + } + } + + + // All the caleidoscope functions work directly within the screenbuffer (leds array). + // Draw whatever you like in the area x(0-15) and y (0-15) and then copy it arround. + + // rotates the first 16x16 quadrant 3 times onto a 32x32 (+90 degrees rotation for each one) + void Caleidoscope1() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY(VPANEL_W - 1 - x, y)] = leds[XY(x, y)]; + leds[XY(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; + leds[XY(x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; + } + } + } + + + // mirror the first 16x16 quadrant 3 times onto a 32x32 + void Caleidoscope2() { + for (int x = 0; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < MATRIX_CENTER_Y; y++) { + leds[XY(VPANEL_W - 1 - x, y)] = leds[XY(y, x)]; + leds[XY(x, VPANEL_H - 1 - y)] = leds[XY(y, x)]; + leds[XY(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY(x, y)]; + } + } + } + + // copy one diagonal triangle into the other one within a 16x16 + void Caleidoscope3() { + for (int x = 0; x <= MATRIX_CENTRE_X; x++) { + for (int y = 0; y <= x; y++) { + leds[XY(x, y)] = leds[XY(y, x)]; + } + } + } + + // copy one diagonal triangle into the other one within a 16x16 (90 degrees rotated compared to Caleidoscope3) + void Caleidoscope4() { + for (int x = 0; x <= MATRIX_CENTRE_X; x++) { + for (int y = 0; y <= MATRIX_CENTRE_Y - x; y++) { + leds[XY(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY(x, y)]; + } + } + } + + // copy one diagonal triangle into the other one within a 8x8 + void Caleidoscope5() { + for (int x = 0; x < VPANEL_W / 4; x++) { + for (int y = 0; y <= x; y++) { + leds[XY(x, y)] = leds[XY(y, x)]; + } + } + + for (int x = VPANEL_W / 4; x < VPANEL_W / 2; x++) { + for (int y = VPANEL_H / 4; y >= 0; y--) { + leds[XY(x, y)] = leds[XY(y, x)]; + } + } + } + + void Caleidoscope6() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 7)] = leds[XY(x, 0)]; + } //a + for (int x = 2; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 6)] = leds[XY(x, 1)]; + } //b + for (int x = 3; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 5)] = leds[XY(x, 2)]; + } //c + for (int x = 4; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 4)] = leds[XY(x, 3)]; + } //d + for (int x = 5; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 3)] = leds[XY(x, 4)]; + } //e + for (int x = 6; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 2)] = leds[XY(x, 5)]; + } //f + for (int x = 7; x < MATRIX_CENTER_X; x++) { + leds[XY(7 - x, 1)] = leds[XY(x, 6)]; + } //g + } + + // create a square twister to the left or counter-clockwise + // x and y for center, r for radius + void SpiralStream(int x, int y, int r, byte dimm) { + for (int d = r; d >= 0; d--) { // from the outside to the inside + for (int i = x - d; i <= x + d; i++) { + leds[XY(i, y - d)] += leds[XY(i + 1, y - d)]; // lowest row to the right + leds[XY(i, y - d)].nscale8(dimm); + } + for (int i = y - d; i <= y + d; i++) { + leds[XY(x + d, i)] += leds[XY(x + d, i + 1)]; // right colum up + leds[XY(x + d, i)].nscale8(dimm); + } + for (int i = x + d; i >= x - d; i--) { + leds[XY(i, y + d)] += leds[XY(i - 1, y + d)]; // upper row to the left + leds[XY(i, y + d)].nscale8(dimm); + } + for (int i = y + d; i >= y - d; i--) { + leds[XY(x - d, i)] += leds[XY(x - d, i - 1)]; // left colum down + leds[XY(x - d, i)].nscale8(dimm); + } + } + } + + // expand everything within a circle + void Expand(int centerX, int centerY, int radius, byte dimm) { + if (radius == 0) + return; + + int currentRadius = radius; + + while (currentRadius > 0) { + int a = radius, b = 0; + int radiusError = 1 - a; + + int nextRadius = currentRadius - 1; + int nextA = nextRadius - 1, nextB = 0; + int nextRadiusError = 1 - nextA; + + while (a >= b) + { + // move them out one pixel on the radius + leds[XY(a + centerX, b + centerY)] = leds[XY(nextA + centerX, nextB + centerY)]; + leds[XY(b + centerX, a + centerY)] = leds[XY(nextB + centerX, nextA + centerY)]; + leds[XY(-a + centerX, b + centerY)] = leds[XY(-nextA + centerX, nextB + centerY)]; + leds[XY(-b + centerX, a + centerY)] = leds[XY(-nextB + centerX, nextA + centerY)]; + leds[XY(-a + centerX, -b + centerY)] = leds[XY(-nextA + centerX, -nextB + centerY)]; + leds[XY(-b + centerX, -a + centerY)] = leds[XY(-nextB + centerX, -nextA + centerY)]; + leds[XY(a + centerX, -b + centerY)] = leds[XY(nextA + centerX, -nextB + centerY)]; + leds[XY(b + centerX, -a + centerY)] = leds[XY(nextB + centerX, -nextA + centerY)]; + + // dim them + leds[XY(a + centerX, b + centerY)].nscale8(dimm); + leds[XY(b + centerX, a + centerY)].nscale8(dimm); + leds[XY(-a + centerX, b + centerY)].nscale8(dimm); + leds[XY(-b + centerX, a + centerY)].nscale8(dimm); + leds[XY(-a + centerX, -b + centerY)].nscale8(dimm); + leds[XY(-b + centerX, -a + centerY)].nscale8(dimm); + leds[XY(a + centerX, -b + centerY)].nscale8(dimm); + leds[XY(b + centerX, -a + centerY)].nscale8(dimm); + + b++; + if (radiusError < 0) + radiusError += 2 * b + 1; + else + { + a--; + radiusError += 2 * (b - a + 1); + } + + nextB++; + if (nextRadiusError < 0) + nextRadiusError += 2 * nextB + 1; + else + { + nextA--; + nextRadiusError += 2 * (nextB - nextA + 1); + } + } + + currentRadius--; + } + } + + // give it a linear tail to the right + void StreamRight(byte scale, int fromX = 0, int toX = VPANEL_W, int fromY = 0, int toY = VPANEL_H) + { + for (int x = fromX + 1; x < toX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY(x, y)] += leds[XY(x - 1, y)]; + leds[XY(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY(0, y)].nscale8(scale); + } + + // give it a linear tail to the left + void StreamLeft(byte scale, int fromX = VPANEL_W, int toX = 0, int fromY = 0, int toY = VPANEL_H) + { + for (int x = toX; x < fromX; x++) { + for (int y = fromY; y < toY; y++) { + leds[XY(x, y)] += leds[XY(x + 1, y)]; + leds[XY(x, y)].nscale8(scale); + } + } + for (int y = fromY; y < toY; y++) + leds[XY(0, y)].nscale8(scale); + } + + // give it a linear tail downwards + void StreamDown(byte scale) + { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 1; y < VPANEL_H; y++) { + leds[XY(x, y)] += leds[XY(x, y - 1)]; + leds[XY(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY(x, 0)].nscale8(scale); + } + + // give it a linear tail upwards + void StreamUp(byte scale) + { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY(x, y)] += leds[XY(x, y + 1)]; + leds[XY(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY(x, VPANEL_H - 1)].nscale8(scale); + } + + // give it a linear tail up and to the left + void StreamUpAndLeft(byte scale) + { + for (int x = 0; x < VPANEL_W - 1; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY(x, y)] += leds[XY(x + 1, y + 1)]; + leds[XY(x, y)].nscale8(scale); + } + } + for (int x = 0; x < VPANEL_W; x++) + leds[XY(x, VPANEL_H - 1)].nscale8(scale); + for (int y = 0; y < VPANEL_H; y++) + leds[XY(VPANEL_W - 1, y)].nscale8(scale); + } + + // give it a linear tail up and to the right + void StreamUpAndRight(byte scale) + { + for (int x = 0; x < VPANEL_W - 1; x++) { + for (int y = VPANEL_H - 2; y >= 0; y--) { + leds[XY(x + 1, y)] += leds[XY(x, y + 1)]; + leds[XY(x, y)].nscale8(scale); + } + } + // fade the bottom row + for (int x = 0; x < VPANEL_W; x++) + leds[XY(x, VPANEL_H - 1)].nscale8(scale); + + // fade the right column + for (int y = 0; y < VPANEL_H; y++) + leds[XY(VPANEL_W - 1, y)].nscale8(scale); + } + + // just move everything one line down + void MoveDown() { + for (int y = VPANEL_H - 1; y > 0; y--) { + for (int x = 0; x < VPANEL_W; x++) { + leds[XY(x, y)] = leds[XY(x, y - 1)]; + } + } + } + + // just move everything one line down + void VerticalMoveFrom(int start, int end) { + for (int y = end; y > start; y--) { + for (int x = 0; x < VPANEL_W; x++) { + leds[XY(x, y)] = leds[XY(x, y - 1)]; + } + } + } + + // copy the rectangle defined with 2 points x0, y0, x1, y1 + // to the rectangle beginning at x2, x3 + void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) { + for (int y = y0; y < y1 + 1; y++) { + for (int x = x0; x < x1 + 1; x++) { + leds[XY(x + x2 - x0, y + y2 - y0)] = leds[XY(x, y)]; + } + } + } + + // rotate + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void RotateTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY(x, 7 - y)] = leds[XY(7 - x, y)]; + } + } + } + + // mirror + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X) + void MirrorTriangle() { + for (int x = 1; x < MATRIX_CENTER_X; x++) { + for (int y = 0; y < x; y++) { + leds[XY(7 - y, x)] = leds[XY(7 - x, y)]; + } + } + } + + // draw static rainbow triangle pattern (MATRIX_CENTER_XxWIDTH / 2) + // (just for debugging) + void RainbowTriangle() { + for (int i = 0; i < MATRIX_CENTER_X; i++) { + for (int j = 0; j <= i; j++) { + Pixel(7 - i, j, i * j * 4); + } + } + } + + void BresenhamLine(int x0, int y0, int x1, int y1, byte colorIndex) + { + BresenhamLine(x0, y0, x1, y1, ColorFromCurrentPalette(colorIndex)); + } + + void BresenhamLine(int x0, int y0, int x1, int y1, CRGB color) + { + int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; + for (;;) { + leds[XY(x0, y0)] += color; + if (x0 == x1 && y0 == y1) break; + e2 = 2 * err; + if (e2 > dy) { + err += dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + } + + // write one pixel with the specified color from the current palette to coordinates + /* + void Pixel(int x, int y, uint8_t colorIndex) { + leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex); + matrix.drawBackgroundPixelRGB888(x,y, leds[XY(x, y)]); // now draw it? + } + */ + + CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) { + return ColorFromPalette(currentPalette, index, brightness, currentBlendType); + } + + CRGB HsvToRgb(uint8_t h, uint8_t s, uint8_t v) { + CHSV hsv = CHSV(h, s, v); + CRGB rgb; + hsv2rgb_spectrum(hsv, rgb); + return rgb; + } + + void NoiseVariablesSetup() { + noisesmoothing = 200; + + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + } + + void FillNoise() { + for (uint8_t i = 0; i < VPANEL_W; i++) { + uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y); + + for (uint8_t j = 0; j < VPANEL_H; j++) { + uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y); + + byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8; + + uint8_t olddata = noise[i][j]; + uint8_t newdata = scale8(olddata, noisesmoothing) + scale8(data, 256 - noisesmoothing); + data = newdata; + + noise[i][j] = data; + } + } + } + + // non leds2 memory version. + void MoveX(byte delta) + { + + CRGB tmp = 0; + + for (int y = 0; y < VPANEL_H; y++) + { + + // Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/ + // Computationally heavier but doesn't need an entire leds2 array + + tmp = leds[XY(0, y)]; + for (int m = 0; m < delta; m++) + { + // Do this delta time for each row... computationally expensive potentially. + for (int x = 0; x < VPANEL_H; x++) + { + leds[XY(x, y)] = leds [XY(x + 1, y)]; + } + + leds[XY(VPANEL_W - 1, y)] = tmp; + } + + + /* + // Shift + for (int x = 0; x < VPANEL_W - delta; x++) { + leds2[XY(x, y)] = leds[XY(x + delta, y)]; + } + + // Wrap around + for (int x = VPANEL_W - delta; x < VPANEL_W; x++) { + leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_H, y)]; + } + */ + } // end row loop + + /* + // write back to leds + for (uint8_t y = 0; y < VPANEL_H; y++) { + for (uint8_t x = 0; x < VPANEL_W; x++) { + leds[XY(x, y)] = leds2[XY(x, y)]; + } + } + */ + } + + void MoveY(byte delta) + { + + CRGB tmp = 0; + for (int x = 0; x < VPANEL_W; x++) + { + tmp = leds[XY(x, 0)]; + for (int m = 0; m < delta; m++) // moves + { + // Do this delta time for each row... computationally expensive potentially. + for (int y = 0; y < VPANEL_H; y++) + { + leds[XY(x, y)] = leds [XY(x, y + 1)]; + } + + leds[XY(x, VPANEL_H - 1)] = tmp; + } + } // end column loop + } /// MoveY + + void MoveFractionalNoiseX(byte amt = 16) { + // move delta pixelwise + for (int y = 0; y < VPANEL_H; y++) { + uint16_t amount = noise[0][y] * amt; + byte delta = 31 - (amount / 256); + + for (int x = 0; x < VPANEL_W - delta; x++) { + leds2[XY(x, y)] = leds[XY(x + delta, y)]; + } + for (int x = VPANEL_H - delta; x < VPANEL_W; x++) { + leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_W, y)]; + } + } + + //move fractions + CRGB PixelA; + CRGB PixelB; + + for (uint8_t y = 0; y < VPANEL_H; y++) { + uint16_t amount = noise[0][y] * amt; + byte delta = 31 - (amount / 256); + byte fractions = amount - (delta * 256); + + for (uint8_t x = 1; x < VPANEL_W; x++) { + PixelA = leds2[XY(x, y)]; + PixelB = leds2[XY(x - 1, y)]; + + PixelA %= 255 - fractions; + PixelB %= fractions; + + leds[XY(x, y)] = PixelA + PixelB; + } + + PixelA = leds2[XY(0, y)]; + PixelB = leds2[XY(VPANEL_W - 1, y)]; + + PixelA %= 255 - fractions; + PixelB %= fractions; + + leds[XY(0, y)] = PixelA + PixelB; + } + } + + void MoveFractionalNoiseY(byte amt = 16) { + // move delta pixelwise + for (int x = 0; x < VPANEL_W; x++) { + uint16_t amount = noise[x][0] * amt; + byte delta = 31 - (amount / 256); + + for (int y = 0; y < VPANEL_W - delta; y++) { + leds2[XY(x, y)] = leds[XY(x, y + delta)]; + } + for (int y = VPANEL_W - delta; y < VPANEL_W; y++) { + leds2[XY(x, y)] = leds[XY(x, y + delta - VPANEL_W)]; + } + } + + //move fractions + CRGB PixelA; + CRGB PixelB; + + for (uint8_t x = 0; x < VPANEL_H; x++) { + uint16_t amount = noise[x][0] * amt; + byte delta = 31 - (amount / 256); + byte fractions = amount - (delta * 256); + + for (uint8_t y = 1; y < VPANEL_W; y++) { + PixelA = leds2[XY(x, y)]; + PixelB = leds2[XY(x, y - 1)]; + + PixelA %= 255 - fractions; + PixelB %= fractions; + + leds[XY(x, y)] = PixelA + PixelB; + } + + PixelA = leds2[XY(x, 0)]; + PixelB = leds2[XY(x, VPANEL_W - 1)]; + + PixelA %= 255 - fractions; + PixelB %= fractions; + + leds[XY(x, 0)] = PixelA + PixelB; + } + } + + void standardNoiseSmearing() { + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + FillNoise(); + + MoveX(3); + MoveFractionalNoiseY(4); + + MoveY(3); + MoveFractionalNoiseX(4); + } + + +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/Geometry.h b/examples/ChainedPanelsAuroraDemo/Geometry.h new file mode 100644 index 0000000..8efb768 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Geometry.h @@ -0,0 +1,150 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d + * Copyright (c) 2014 Noel Bundy + * + * Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/ + * Copyright (c) 2008 Windell H Oskay. All right reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Geometry_H +#define Geometry_H + +struct Vertex +{ + float x, y, z; + Vertex() + { + this->set(0, 0, 0); + } + + Vertex(float x, float y, float z) + { + this->set(x, y, z); + } + + void set(float x, float y, float z) + { + this->x = x; + this->y = y; + this->z = z; + } +}; + +struct EdgePoint +{ + int x, y; + boolean visible; + + EdgePoint() + { + this->set(0, 0); + this->visible = false; + } + + void set(int a, int b) + { + this->x = a; + this->y = b; + } +}; + +struct Point +{ + float x, y; + + Point() + { + set(0, 0); + } + + Point(float x, float y) + { + set(x, y); + } + + void set(float x, float y) + { + this->x = x; + this->y = y; + } + +}; + +struct squareFace +{ + int length; + int sommets[4]; + int ed[4]; + + squareFace() + { + set(-1, -1, -1, -1); + } + + squareFace(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + + void set(int a, int b, int c, int d) + { + this->length = 4; + this->sommets[0] = a; + this->sommets[1] = b; + this->sommets[2] = c; + this->sommets[3] = d; + } + +}; + +struct triFace +{ + int length; + int sommets[3]; + int ed[3]; + + triFace() + { + set(-1,-1,-1); + } + triFace(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } + void set(int a, int b, int c) + { + this->length =3; + this->sommets[0]=a; + this->sommets[1]=b; + this->sommets[2]=c; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h b/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h new file mode 100644 index 0000000..8398331 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PaletteFireKoz.h @@ -0,0 +1,6 @@ +const uint8_t PROGMEM palette_fire[] = {/* RGB888 R,G,B,R,G,B,R,G,B,... */ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0x0a,0x00,0x00,0x10,0x00,0x00,0x15,0x00,0x00,0x1b,0x00,0x00,0x20,0x00,0x00,0x25,0x00,0x00,0x2b,0x00,0x00,0x31,0x00,0x00,0x36,0x00,0x00,0x3c,0x00,0x00,0x41,0x00,0x00,0x46,0x00,0x00,0x4c,0x00,0x00,0x52,0x00,0x00,0x57,0x00,0x00,0x5d,0x00,0x00,0x62,0x00,0x00,0x68,0x00,0x00,0x6d,0x00,0x00,0x73,0x00,0x00,0x79,0x00,0x00,0x7e,0x00,0x00,0x83,0x00,0x00,0x89,0x00,0x00,0x8e,0x00,0x00,0x94,0x00,0x00,0x9a,0x00,0x00,0x9f,0x00,0x00,0xa5,0x00,0x00,0xaa,0x00,0x00,0xb0,0x00,0x00,0xb5,0x00,0x00,0xbb,0x00,0x00,0xc0,0x00,0x00,0xc6,0x00,0x00,0xcb,0x00,0x00,0xd1,0x00,0x00,0xd7,0x00,0x00,0xdc,0x00,0x00,0xe1,0x00,0x00,0xe6,0x00,0x00,0xe8,0x02,0x00,0xe9,0x08,0x00,0xe9,0x0f,0x00,0xe9,0x13,0x00,0xe9,0x16,0x00,0xe9,0x1b,0x00,0xe9,0x21,0x00,0xe9,0x26,0x00,0xe9,0x2a,0x00,0xe9,0x2e,0x00,0xe9,0x32,0x00,0xe9,0x37,0x00,0xe9,0x3b,0x00,0xe9,0x3f,0x00,0xe9,0x44,0x00,0xe9,0x4a,0x00,0xe9,0x4e,0x00,0xe9,0x52,0x00,0xe9,0x56,0x00,0xe9,0x5a,0x00,0xe9,0x5d,0x00,0xe9,0x63,0x00,0xe9,0x67,0x00,0xe9,0x6b,0x00,0xe9,0x71,0x00,0xe9,0x77,0x00,0xe9,0x78,0x00,0xe9,0x7c,0x00,0xe9,0x81,0x00,0xe9,0x86,0x00,0xe9,0x8b,0x00,0xe9,0x8f,0x00,0xe9,0x93,0x00,0xe9,0x99,0x00,0xe9,0x9d,0x00,0xe9,0xa0,0x00,0xe9,0xa4,0x00,0xe9,0xaa,0x00,0xe9,0xb0,0x00,0xe9,0xb4,0x00,0xe9,0xb5,0x00,0xe9,0xb9,0x00,0xe9,0xbe,0x00,0xe9,0xc3,0x00,0xe9,0xc9,0x00,0xe9,0xce,0x00,0xe9,0xd2,0x00,0xe9,0xd6,0x00,0xe9,0xd9,0x00,0xe9,0xdd,0x00,0xe9,0xe2,0x00,0xe9,0xe7,0x02,0xe9,0xe9,0x0e,0xe9,0xe9,0x1c,0xe9,0xe9,0x28,0xe9,0xe9,0x38,0xe9,0xe9,0x48,0xe9,0xe9,0x57,0xe9,0xe9,0x67,0xe9,0xe9,0x73,0xe9,0xe9,0x81,0xe9,0xe9,0x90,0xe9,0xe9,0xa1,0xe9,0xe9,0xb1,0xe9,0xe9,0xbf,0xe9,0xe9,0xcb,0xe9,0xe9,0xcb,0xe9,0xe9,0xcd,0xe9,0xe9,0xd9,0xe9,0xe9,0xe5,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe0,0xe0,0xe0,0xdc,0xdc,0xdc,0xd8,0xd8,0xd8,0xd2,0xd2,0xd2,0xca,0xca,0xca,0xc1,0xc1,0xc1,0xb7,0xb7,0xb7,0xab,0xab,0xab,0x9d,0x9d,0x9d,0x8f,0x8f,0x8f,0x81,0x81,0x81,0x72,0x72,0x72,0x64,0x64,0x64,0x56,0x56,0x56,0x4a,0x4a,0x4a,0x3e,0x3e,0x3e,0x33,0x33,0x33,0x2a,0x2a,0x2a,0x22,0x22,0x22,0x1b,0x1b,0x1b,0x16,0x16,0x16,0x11,0x11,0x11,0x0d,0x0d,0x0d,0x0b,0x0b,0x0b,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +//const uint8_t PROGMEM palletfire[] = {/* RGB888 R,G,B,R,G,B,R,G,B,... */ +//0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x00,0x00,0x0a,0x00,0x00,0x10,0x00,0x00,0x15,0x00,0x00,0x1b,0x00,0x00,0x20,0x00,0x00,0x25,0x00,0x00,0x2b,0x00,0x00,0x31,0x00,0x00,0x36,0x00,0x00,0x3c,0x00,0x00,0x41,0x00,0x00,0x46,0x00,0x00,0x4c,0x00,0x00,0x52,0x00,0x00,0x57,0x00,0x00,0x5d,0x00,0x00,0x62,0x00,0x00,0x68,0x00,0x00,0x6d,0x00,0x00,0x73,0x00,0x00,0x79,0x00,0x00,0x7e,0x00,0x00,0x83,0x00,0x00,0x89,0x00,0x00,0x8e,0x00,0x00,0x94,0x00,0x00,0x9a,0x00,0x00,0x9f,0x00,0x00,0xa5,0x00,0x00,0xaa,0x00,0x00,0xb0,0x00,0x00,0xb5,0x00,0x00,0xbb,0x00,0x00,0xc0,0x00,0x00,0xc6,0x00,0x00,0xcb,0x00,0x00,0xd1,0x00,0x00,0xd7,0x00,0x00,0xdc,0x00,0x00,0xe1,0x00,0x00,0xe6,0x00,0x00,0xe8,0x02,0x00,0xe9,0x08,0x00,0xe9,0x0f,0x00,0xe9,0x13,0x00,0xe9,0x16,0x00,0xe9,0x1b,0x00,0xe9,0x21,0x00,0xe9,0x26,0x00,0xe9,0x2a,0x00,0xe9,0x2e,0x00,0xe9,0x32,0x00,0xe9,0x37,0x00,0xe9,0x3b,0x00,0xe9,0x3f,0x00,0xe9,0x44,0x00,0xe9,0x4a,0x00,0xe9,0x4e,0x00,0xe9,0x52,0x00,0xe9,0x56,0x00,0xe9,0x5a,0x00,0xe9,0x5d,0x00,0xe9,0x63,0x00,0xe9,0x67,0x00,0xe9,0x6b,0x00,0xe9,0x71,0x00,0xe9,0x77,0x00,0xe9,0x78,0x00,0xe9,0x7c,0x00,0xe9,0x81,0x00,0xe9,0x86,0x00,0xe9,0x8b,0x00,0xe9,0x8f,0x00,0xe9,0x93,0x00,0xe9,0x99,0x00,0xe9,0x9d,0x00,0xe9,0xa0,0x00,0xe9,0xa4,0x00,0xe9,0xaa,0x00,0xe9,0xb0,0x00,0xe9,0xb4,0x00,0xe9,0xb5,0x00,0xe9,0xb9,0x00,0xe9,0xbe,0x00,0xe9,0xc3,0x00,0xe9,0xc9,0x00,0xe9,0xce,0x00,0xe9,0xd2,0x00,0xe9,0xd6,0x00,0xe9,0xd9,0x00,0xe9,0xdd,0x00,0xe9,0xe2,0x00,0xe9,0xe7,0x02,0xe9,0xe9,0x0e,0xe9,0xe9,0x1c,0xe9,0xe9,0x28,0xe9,0xe9,0x38,0xe9,0xe9,0x48,0xe9,0xe9,0x57,0xe9,0xe9,0x67,0xe9,0xe9,0x73,0xe9,0xe9,0x81,0xe9,0xe9,0x90,0xe9,0xe9,0xa1,0xe9,0xe9,0xb1,0xe9,0xe9,0xbf,0xe9,0xe9,0xcb,0xe9,0xe9,0xcb,0xe9,0xe9,0xcd,0xe9,0xe9,0xd9,0xe9,0xe9,0xe5,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,0xe6,0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe0,0xe0,0xe0,0xdc,0xdc,0xdc,0xd8,0xd8,0xd8,0xd2,0xd2,0xd2,0xca,0xca,0xca,0xc1,0xc1,0xc1,0xb7,0xb7,0xb7,0xab,0xab,0xab,0x9d,0x9d,0x9d,0x8f,0x8f,0x8f,0x81,0x81,0x81,0x72,0x72,0x72,0x64,0x64,0x64,0x56,0x56,0x56,0x4a,0x4a,0x4a,0x3e,0x3e,0x3e,0x33,0x33,0x33,0x2a,0x2a,0x2a,0x22,0x22,0x22,0x1b,0x1b,0x1b,0x16,0x16,0x16,0x11,0x11,0x11,0x0d,0x0d,0x0d,0x0b,0x0b,0x0b,0x08,0x08,0x08,0x07,0x07,0x07,0x06,0x06,0x06,0x05,0x05,0x05,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +//}; diff --git a/examples/ChainedPanelsAuroraDemo/PatternAttract.h b/examples/ChainedPanelsAuroraDemo/PatternAttract.h new file mode 100644 index 0000000..7df342c --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternAttract.h @@ -0,0 +1,73 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternAttract_H + +class PatternAttract : public Drawable { +private: + const int count = 8; + Attractor attractor; + +public: + PatternAttract() { + name = (char *)"Attract"; + } + + void start() { + int direction = random(0, 2); + if (direction == 0) + direction = -1; + + for (int i = 0; i < count; i++) { + Boid boid = Boid(15, 31 - i); + boid.mass = 1; // random(0.1, 2); + boid.velocity.x = ((float) random(40, 50)) / 100.0; + boid.velocity.x *= direction; + boid.velocity.y = 0; + boid.colorIndex = i * 32; + boids[i] = boid; + //dim = random(170, 250); + } + } + + unsigned int drawFrame() { + // dim all pixels on the display + uint8_t dim = beatsin8(2, 170, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (int i = 0; i < count; i++) { + Boid boid = boids[i]; + + PVector force = attractor.attract(boid); + boid.applyForce(force); + + boid.update(); + effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex)); + + boids[i] = boid; + } + + return 15; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h b/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h new file mode 100644 index 0000000..c6ea4a7 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternElectricMandala.h @@ -0,0 +1,116 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Funky Noise" by Stefan Petrick: https://github.com/StefanPetrick/FunkyNoise + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternElectricMandala_H + +class PatternElectricMandala : public Drawable { + private: + + // The coordinates for 16-bit noise spaces. +#define NUM_LAYERS 1 + + // used for the random based animations + int16_t dx; + int16_t dy; + int16_t dz; + int16_t dsx; + int16_t dsy; + + public: + PatternElectricMandala() { + name = (char *)"ElectricMandala"; + } + + void start() { + // set to reasonable values to avoid a black out + noisesmoothing = 200; + + // just any free input pin + //random16_add_entropy(analogRead(18)); + + // fill coordinates with random values + // set zoom levels + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + noise_scale_x = 6000; + noise_scale_y = 6000; + + // for the random movement + dx = random8(); + dy = random8(); + dz = random8(); + dsx = random8(); + dsy = random8(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(25) { + //SetupRandomPalette3(); + dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too + dx = random16(500) - 250; + dz = random16(500) - 250; + noise_scale_x = random16(10000) + 2000; + noise_scale_y = random16(10000) + 2000; + } +#endif + + noise_y += dy; + noise_x += dx; + noise_z += dz; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + effects.Caleidoscope3(); + effects.Caleidoscope1(); + + effects.ShowFrame(); + + return 0; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint8_t i = 0; i < VPANEL_W; i++) { + for (uint8_t j = 0; j < VPANEL_H; j++) { + + uint8_t color = noise[i][j]; + + uint8_t bri = color; + + // assign a color depending on the actual palette + CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri); + + effects.leds[XY(i, j)] = pixel; + } + } + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternFire.h b/examples/ChainedPanelsAuroraDemo/PatternFire.h new file mode 100644 index 0000000..5d5d021 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternFire.h @@ -0,0 +1,121 @@ +/* + Aurora: https://github.com/pixelmatix/aurora + Copyright (c) 2014 Jason Coon + + Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette + Copyright (c) 2013 FastLED + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Note: (Kosso) : Doesn't look good with certain palettes. + +#ifndef PatternFire_H +#define PatternFire_H + +#ifndef Effects_H +#include "Effects.h" +#endif + +class PatternFire : public Drawable { + private: + + public: + PatternFire() { + name = (char *)"Fire"; + } + + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // cooling: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 55, suggested range 20-100 + int cooling = 100; + + // sparking: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + unsigned int sparking = 100; + + unsigned int drawFrame() { + // Add entropy to random number generator; we use a lot of it. + random16_add_entropy( random16()); + + effects.DimAll(235); + + for (int x = 0; x < VPANEL_W; x++) { + // Step 1. Cool down every cell a little + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / VPANEL_H) + 2)); + } + + // Step 2. Heat from each cell drifts 'up' and diffuses a little + for (int y = 0; y < VPANEL_H; y++) { + heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3; + } + + // Step 2. Randomly ignite new 'sparks' of heat + if (random8() < sparking) { + // int x = (p[0] + p[1] + p[2]) / 3; + + int xy = XY(x, VPANEL_H - 1); + heat[xy] = qadd8(heat[xy], random8(160, 255)); + } + + // Step 4. Map from heat cells to LED colors + for (int y = 0; y < VPANEL_H; y++) { + int xy = XY(x, y); + byte colorIndex = heat[xy]; + + // Recommend that you use values 0-240 rather than + // the usual 0-255, as the last 15 colors will be + // 'wrapping around' from the hot end to the cold end, + // which looks wrong. + colorIndex = scale8(colorIndex, 200); + + // override color 0 to ensure a black background? + //if (colorIndex != 0) { + // effects.leds[xy] = CRGB::Black; + //} + //else { + effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex); + //} + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + // effects.MoveX(2); + effects.MoveFractionalNoiseX(2); + + effects.ShowFrame(); + + return 15; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h b/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h new file mode 100644 index 0000000..c553d6b --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternFireKoz.h @@ -0,0 +1,109 @@ +/* + Aurora: https://github.com/pixelmatix/aurora + Copyright (c) 2014 Jason Coon + + Added by @Kosso. Cobbled together from various places which I can't remember. I'll update this when I track it down. + Requires PaletteFireKoz.h + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternFireKoz_H +#define PatternFireKoz_H + +class PatternFireKoz : public Drawable { + private: + + const int FIRE_HEIGHT = 800; + + int Bit = 0, NBit = 1; + float fire_c; + // might not need this buffer here... there some led buffers set up in Effects.h + uint8_t fireBuffer[VPANEL_W][VPANEL_H][2]; + + public: + PatternFireKoz() { + name = (char *)"FireKoz"; + } + + unsigned int drawFrame() { + + for (int x = 1; x < VPANEL_W - 1; x++) + { + fireBuffer[x][VPANEL_H - 2][Bit] = random(0, FIRE_HEIGHT); + if (random(0, 100) > 80) + { + fireBuffer[x][VPANEL_H - 2][Bit] = 0; + fireBuffer[x][VPANEL_H - 3][Bit] = 0; + } + } + for (int y = 1; y < VPANEL_H - 1; y++) + { + for (int x = 1; x < VPANEL_W - 1; x++) + { + fire_c = (fireBuffer[x - 1][y][Bit] + + fireBuffer[x + 1][y][Bit] + + fireBuffer[x][y - 1][Bit] + + fireBuffer[x][y + 1][Bit] + + fireBuffer[x][y][Bit]) / + 5.0; + + fire_c = (fireBuffer[x - 1][y][Bit] + + fireBuffer[x + 1][y][Bit] + + fireBuffer[x][y - 1][Bit] + + fireBuffer[x][y + 1][Bit] + + fireBuffer[x][y][Bit]) / + 5.0; + + if (fire_c > (FIRE_HEIGHT / 2) && fire_c < FIRE_HEIGHT) { + fire_c -= 0.2; + } else if (fire_c > (FIRE_HEIGHT / 4) && fire_c < (FIRE_HEIGHT / 2)) { + fire_c -= 0.4; + } else if (fire_c <= (FIRE_HEIGHT / 8)) { + fire_c -= 0.7; + } else { + fire_c -= 1; + } + if (fire_c < 0) + fire_c = 0; + if (fire_c >= FIRE_HEIGHT + 1) + fire_c = FIRE_HEIGHT - 1; + fireBuffer[x][y - 1][NBit] = fire_c; + int index = (int)fire_c * 3; + if (fire_c == 0) + { + effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(0, 0, 0)); + } + else + { + effects.drawBackgroundFastLEDPixelCRGB(x, y, CRGB(palette_fire[index], palette_fire[index + 1], palette_fire[index + 2])); + } + } + } + //display.drawRect(0, 0, VPANEL_W, VPANEL_H, display.color565(25, 25, 25)); + + NBit = Bit; + Bit = 1 - Bit; + + effects.ShowFrame(); + + return 30; // no idea what this is for... + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternFlock.h b/examples/ChainedPanelsAuroraDemo/PatternFlock.h new file mode 100644 index 0000000..3ae31b1 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternFlock.h @@ -0,0 +1,125 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/ + * Copyright (c) 2014 Daniel Shiffman + * http://www.shiffman.net + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Flocking +// Daniel Shiffman +// The Nature of Code, Spring 2009 + +// Demonstration of Craig Reynolds' "Flocking" behavior +// See: http://www.red3d.com/cwr/ +// Rules: Cohesion, Separation, Alignment + +#ifndef PatternFlock_H +#define PatternFlock_H + +class PatternFlock : public Drawable { + public: + PatternFlock() { + name = (char *)"Flock"; + } + + static const int boidCount = 10; + Boid predator; + + PVector wind; + byte hue = 0; + bool predatorPresent = true; + + void start() { + for (int i = 0; i < boidCount; i++) { + boids[i] = Boid(15, 15); + boids[i].maxspeed = 0.380; + boids[i].maxforce = 0.015; + } + + predatorPresent = random(0, 2) >= 1; + if (predatorPresent) { + predator = Boid(31, 31); + predatorPresent = true; + predator.maxspeed = 0.385; + predator.maxforce = 0.020; + predator.neighbordist = 16.0; + predator.desiredseparation = 0.0; + } + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + bool applyWind = random(0, 255) > 250; + if (applyWind) { + wind.x = Boid::randomf() * .015; + wind.y = Boid::randomf() * .015; + } + + CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < boidCount; i++) { + Boid * boid = &boids[i]; + + if (predatorPresent) { + // flee from predator + boid->repelForce(predator.location, 10); + } + + boid->run(boids, boidCount); + boid->wrapAroundBorders(); + PVector location = boid->location; + // PVector velocity = boid->velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + + if (applyWind) { + boid->applyForce(wind); + applyWind = false; + } + } + + if (predatorPresent) { + predator.run(boids, boidCount); + predator.wrapAroundBorders(); + color = effects.ColorFromCurrentPalette(hue + 128); + PVector location = predator.location; + // PVector velocity = predator.velocity; + // backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color); + // effects.leds[XY(location.x, location.y)] += color; + effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color); + } + + EVERY_N_MILLIS(200) { + hue++; + } + + EVERY_N_SECONDS(30) { + predatorPresent = !predatorPresent; + } + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternFlowField.h b/examples/ChainedPanelsAuroraDemo/PatternFlowField.h new file mode 100644 index 0000000..be91ff2 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternFlowField.h @@ -0,0 +1,92 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternFlowField_H + +class PatternFlowField : public Drawable { + public: + PatternFlowField() { + name = (char *)"FlowField"; + } + + uint16_t x; + uint16_t y; + uint16_t z; + + uint16_t speed = 1; + uint16_t scale = 26; + + static const int count = 40; + + byte hue = 0; + + void start() { + x = random16(); + y = random16(); + z = random16(); + + for (int i = 0; i < count; i++) { + boids[i] = Boid(random(VPANEL_W), 0); + } + } + + unsigned int drawFrame() { + effects.DimAll(240); + + // CRGB color = effects.ColorFromCurrentPalette(hue); + + for (int i = 0; i < count; i++) { + Boid * boid = &boids[i]; + + int ioffset = scale * boid->location.x; + int joffset = scale * boid->location.y; + + byte angle = inoise8(x + ioffset, y + joffset, z); + + boid->velocity.x = (float) sin8(angle) * 0.0078125 - 1.0; + boid->velocity.y = -((float)cos8(angle) * 0.0078125 - 1.0); + boid->update(); + + effects.drawBackgroundFastLEDPixelCRGB(boid->location.x, boid->location.y, effects.ColorFromCurrentPalette(angle + hue)); // color + + if (boid->location.x < 0 || boid->location.x >= VPANEL_W || + boid->location.y < 0 || boid->location.y >= VPANEL_H) { + boid->location.x = random(VPANEL_W); + boid->location.y = 0; + } + } + + EVERY_N_MILLIS(200) { + hue++; + } + + x += speed; + y += speed; + z += speed; + + effects.ShowFrame(); + + return 50; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h b/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h new file mode 100644 index 0000000..98c9b08 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternIncrementalDrift.h @@ -0,0 +1,51 @@ +/* +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternIncrementalDrift_H +#define PatternIncrementalDrift_H + +class PatternIncrementalDrift : public Drawable { + public: + PatternIncrementalDrift() { + name = (char *)"Incremental Drift"; + } + + unsigned int drawFrame() { + uint8_t dim = beatsin8(2, 230, 250); + effects.DimAll(dim); effects.ShowFrame(); + + for (int i = 2; i <= VPANEL_W / 2; i++) + { + CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (VPANEL_W / 2))); + + uint8_t x = beatcos8((17 - i) * 2, MATRIX_CENTER_X - i, MATRIX_CENTER_X + i); + uint8_t y = beatsin8((17 - i) * 2, MATRIX_CENTER_Y - i, MATRIX_CENTER_Y + i); + + effects.drawBackgroundFastLEDPixelCRGB(x, y, color); + } + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternInfinity.h b/examples/ChainedPanelsAuroraDemo/PatternInfinity.h new file mode 100644 index 0000000..87803a7 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternInfinity.h @@ -0,0 +1,58 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternInfinity_H + +class PatternInfinity : public Drawable { +public: + PatternInfinity() { + name = (char *)"Infinity"; + } + + unsigned int drawFrame() { + // dim all pixels on the display slightly + // to 250/255 (98%) of their current brightness + effects.DimAll(250); effects.ShowFrame(); + + // the Effects class has some sample oscillators + // that move from 0 to 255 at different speeds + effects.MoveOscillators(); + + // the horizontal position of the head of the infinity sign + // oscillates from 0 to the maximum horizontal and back + int x = (VPANEL_W - 1) - effects.p[1]; + + // the vertical position of the head oscillates + // from 8 to 23 and back (hard-coded for a 32x32 matrix) + int y = map8(sin8(effects.osci[3]), 8, 23); + + // the hue oscillates from 0 to 255, overflowing back to 0 + byte hue = sin8(effects.osci[5]); + + // draw a pixel at x,y using a color from the current palette + effects.Pixel(x, y, hue); + + return 15; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternLife.h b/examples/ChainedPanelsAuroraDemo/PatternLife.h new file mode 100644 index 0000000..8074e40 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternLife.h @@ -0,0 +1,129 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from Andrew: http://pastebin.com/f22bfe94d + * which, in turn, was "Adapted from the Life example on the Processing.org site" + * + * Made much more colorful by J.B. Langston: https://github.com/jblang/aurora/commit/6db5a884e3df5d686445c4f6b669f1668841929b + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternLife_H +#define PatternLife_H + +class Cell { +public: + byte alive : 1; + byte prev : 1; + byte hue: 6; + byte brightness; +}; + +class PatternLife : public Drawable { +private: + Cell world[VPANEL_W][VPANEL_H]; + unsigned int density = 50; + int generation = 0; + + void randomFillWorld() { + for (int i = 0; i < VPANEL_W; i++) { + for (int j = 0; j < VPANEL_H; j++) { + if (random(100) < density) { + world[i][j].alive = 1; + world[i][j].brightness = 255; + } + else { + world[i][j].alive = 0; + world[i][j].brightness = 0; + } + world[i][j].prev = world[i][j].alive; + world[i][j].hue = 0; + } + } + } + + int neighbours(int x, int y) { + return (world[(x + 1) % VPANEL_W][y].prev) + + (world[x][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][y].prev) + + (world[x][(y + VPANEL_H - 1) % VPANEL_H].prev) + + (world[(x + 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][(y + 1) % VPANEL_H].prev) + + (world[(x + VPANEL_W - 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev) + + (world[(x + 1) % VPANEL_W][(y + VPANEL_H - 1) % VPANEL_H].prev); + } + +public: + PatternLife() { + name = (char *)"Life"; + } + + unsigned int drawFrame() { + if (generation == 0) { + effects.ClearFrame(); + + randomFillWorld(); + } + + // Display current generation + for (int i = 0; i < VPANEL_W; i++) { + for (int j = 0; j < VPANEL_H; j++) { + effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(world[i][j].hue * 4, world[i][j].brightness); + } + } + + // Birth and death cycle + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + // Default is for cell to stay the same + if (world[x][y].brightness > 0 && world[x][y].prev == 0) + world[x][y].brightness *= 0.9; + int count = neighbours(x, y); + if (count == 3 && world[x][y].prev == 0) { + // A new cell is born + world[x][y].alive = 1; + world[x][y].hue += 2; + world[x][y].brightness = 255; + } else if ((count < 2 || count > 3) && world[x][y].prev == 1) { + // Cell dies + world[x][y].alive = 0; + } + } + } + + // Copy next generation into place + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + world[x][y].prev = world[x][y].alive; + } + } + + + generation++; + if (generation >= 256) + generation = 0; + + effects.ShowFrame(); + + return 60; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternMaze.h b/examples/ChainedPanelsAuroraDemo/PatternMaze.h new file mode 100644 index 0000000..8a94d26 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternMaze.h @@ -0,0 +1,264 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Many thanks to Jamis Buck for the documentation of the Growing Tree maze generation algorithm: http://weblog.jamisbuck.org/2011/1/27/maze-generation-growing-tree-algorithm + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMaze_H +#define PatternMaze_H + +class PatternMaze : public Drawable { +private: + enum Directions { + None = 0, + Up = 1, + Down = 2, + Left = 4, + Right = 8, + }; + + struct Point{ + int x; + int y; + + static Point New(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + Point Move(Directions direction) { + switch (direction) + { + case Up: + return New(x, y - 1); + + case Down: + return New(x, y + 1); + + case Left: + return New(x - 1, y); + + case Right: + default: + return New(x + 1, y); + } + } + + static Directions Opposite(Directions direction) { + switch (direction) { + case Up: + return Down; + + case Down: + return Up; + + case Left: + return Right; + + case Right: + default: + return Left; + } + } + }; + +// int width = 16; +// int height = 16; + + static const int width = VPANEL_W / 2; + static const int height = VPANEL_H / 2; + + + Directions grid[width][height]; + + Point point; + + Point cells[256]; + int cellCount = 0; + + int algorithm = 0; + int algorithmCount = 1; + + byte hue = 0; + byte hueOffset = 0; + + Directions directions[4] = { Up, Down, Left, Right }; + + void removeCell(int index) {// shift cells after index down one + for (int i = index; i < cellCount - 1; i++) { + cells[i] = cells[i + 1]; + } + + cellCount--; + } + + void shuffleDirections() { + for (int a = 0; a < 4; a++) + { + int r = random(a, 4); + Directions temp = directions[a]; + directions[a] = directions[r]; + directions[r] = temp; + } + } + + Point createPoint(int x, int y) { + Point point; + point.x = x; + point.y = y; + return point; + } + + CRGB chooseColor(int index) { + byte h = index + hueOffset; + + switch (algorithm) { + case 0: + default: + return effects.ColorFromCurrentPalette(h); + + case 1: + return effects.ColorFromCurrentPalette(hue++); + } + } + + int chooseIndex(int max) { + switch (algorithm) { + case 0: + default: + // choose newest (recursive backtracker) + return max - 1; + + case 1: + // choose random(Prim's) + return random(max); + + // case 2: + // // choose oldest (not good, so disabling) + // return 0; + } + } + + void generateMaze() { + while (cellCount > 1) { + drawNextCell(); + } + } + + void drawNextCell() { + int index = chooseIndex(cellCount); + + if (index < 0) + return; + + point = cells[index]; + + Point imagePoint = createPoint(point.x * 2, point.y * 2); + + //effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray)); + + shuffleDirections(); + + CRGB color = chooseColor(index); + + for (int i = 0; i < 4; i++) { + Directions direction = directions[i]; + + Point newPoint = point.Move(direction); + if (newPoint.x >= 0 && newPoint.y >= 0 && newPoint.x < width && newPoint.y < height && grid[newPoint.y][newPoint.x] == None) { + grid[point.y][point.x] = (Directions) ((int) grid[point.y][point.x] | (int) direction); + grid[newPoint.y][newPoint.x] = (Directions) ((int) grid[newPoint.y][newPoint.x] | (int) point.Opposite(direction)); + + Point newImagePoint = imagePoint.Move(direction); + + effects.drawBackgroundFastLEDPixelCRGB(newImagePoint.x, newImagePoint.y, color); + + cellCount++; + cells[cellCount - 1] = newPoint; + + index = -1; + break; + } + } + + if (index > -1) { + Point finishedPoint = cells[index]; + imagePoint = createPoint(finishedPoint.x * 2, finishedPoint.y * 2); + effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, color); + + removeCell(index); + } + } + +public: + PatternMaze() { + name = (char *)"Maze"; + } + + unsigned int drawFrame() { + if (cellCount < 1) { + + effects.ClearFrame(); + + // reset the maze grid + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + grid[y][x] = None; + } + } + + int x = random(width); + int y = random(height); + + cells[0] = createPoint(x, y); + + cellCount = 1; + + hue = 0; + hueOffset = random(0, 256); + + } + + drawNextCell(); + + if (cellCount < 1) { + algorithm++; + if (algorithm >= algorithmCount) + algorithm = 0; + + return 1000; + } + + effects.ShowFrame(); + + return 0; + } + + void start() { + matrix.fillScreen(0); + cellCount = 0; + hue = 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternMunch.h b/examples/ChainedPanelsAuroraDemo/PatternMunch.h new file mode 100644 index 0000000..21d6720 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternMunch.h @@ -0,0 +1,74 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Munch pattern created by J.B. Langston: https://github.com/jblang/aurora/blob/master/PatternMunch.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternMunch_H +#define PatternMunch_H + + +class PatternMunch : public Drawable { +private: + byte count = 0; + byte dir = 1; + byte flip = 0; + byte generation = 0; + +public: + PatternMunch() { + name = (char *)"Munch"; + } + + unsigned int drawFrame() { + + for (byte x = 0; x < VPANEL_W; x++) { + for (byte y = 0; y < VPANEL_H; y++) { + effects.leds[XY(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black; + + // The below is more pleasant + // effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ; + } + } + + count += dir; + + if (count <= 0 || count >= VPANEL_W) { + dir = -dir; + } + + if (count <= 0) { + if (flip == 0) + flip = VPANEL_W-1; + else + flip = 0; + } + + generation++; + + // show it ffs! + effects.ShowFrame(); + + return 60; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h b/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h new file mode 100644 index 0000000..96e8e53 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternNoiseSmearing.h @@ -0,0 +1,338 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from "Noise Smearing" by Stefan Petrick: https://gist.githubusercontent.com/embedded-creations/5cd47d83cb0e04f4574d/raw/ebf6a82b4755d55cfba3bf6598f7b19047f89daf/NoiseSmearing.ino +* Copyright (c) 2014 Stefan Petrick +* http://www.stefan-petrick.de/wordpress_beta +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternNoiseSmearing_H +#define PatternNoiseSmearing_H + +byte patternNoiseSmearingHue = 0; + +class PatternMultipleStream : public Drawable { +public: + PatternMultipleStream() { + name = (char *)"MultipleStream"; + } + + // this pattern draws two points to the screen based on sin/cos if a counter + // (comment out NoiseSmearWithRadius to see pattern of pixels) + // these pixels are smeared by a large radius, giving a lot of movement + // the image is dimmed before each drawing to not saturate the screen with color + // the smear has an offset so the pixels usually have a trail leading toward the upper left + unsigned int drawFrame() { + static unsigned long counter = 0; +#if 0 + // this counter lets put delays between each frame and still get the same animation + counter++; +#else + // this counter updates in real time and can't be slowed down for debugging + counter = millis() / 10; +#endif + + byte x1 = 4 + sin8(counter * 2) / 10; + byte x2 = 8 + sin8(counter * 2) / 16; + byte y2 = 8 + cos8((counter * 2) / 3) / 16; + + effects.leds[XY(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + effects.leds[XY(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128); + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + // effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + // effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream2 : public Drawable { +public: + PatternMultipleStream2() { + name = (char *)"MultipleStream2"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + byte xx = 4 + sin8(millis() / 9) / 10; + byte yy = 4 + cos8(millis() / 10) / 10; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + xx = 8 + sin8(millis() / 10) / 16; + yy = 8 + cos8(millis() / 7) / 16; + effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160); + + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + // effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + //effects.MoveFractionalNoiseX(4); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream3 : public Drawable { +public: + PatternMultipleStream3() { + name = (char *)"MultipleStream3"; + } + + unsigned int drawFrame() { + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 15)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + // effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + // effects.MoveFractionalNoiseX(4); + + effects.ShowFrame(); + + return 1; + } +}; + +class PatternMultipleStream4 : public Drawable { +public: + PatternMultipleStream4() { + name = (char *)"MultipleStream4"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue); + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(8); + // effects.MoveFractionalNoiseX(); + + effects.MoveY(8); + // effects.MoveFractionalNoiseY(); + + patternNoiseSmearingHue++; + + return 0; + } +}; + +class PatternMultipleStream5 : public Drawable { +public: + PatternMultipleStream5() { + name = (char *)"MultipleStream5"; + } + + unsigned int drawFrame() { + + //CLS(); + effects.DimAll(235); effects.ShowFrame(); + + + for (uint8_t i = 3; i < 32; i = i + 4) { + effects.leds[XY(i, 31)] += effects.ColorFromCurrentPalette(i * 8); + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + // effects.MoveFractionalNoiseY(4); + + effects.MoveY(4); + // effects.MoveFractionalNoiseX(4); + + return 0; + } +}; + +class PatternMultipleStream8 : public Drawable { +public: + PatternMultipleStream8() { + name = (char *)"MultipleStream8"; + } + + unsigned int drawFrame() { + effects.DimAll(230); effects.ShowFrame(); + + // draw grid of rainbow dots on top of the dimmed image + for (uint8_t y = 1; y < 32; y = y + 6) { + for (uint8_t x = 1; x < 32; x = x + 6) { + + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4); + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_z += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + // effects.MoveFractionalNoiseX(4); + + effects.MoveY(3); + //effects.MoveFractionalNoiseY(4); + + return 0; + } +}; + +class PatternPaletteSmear : public Drawable { +public: + PatternPaletteSmear() { + name = (char *)"PaletteSmear"; + } + + unsigned int drawFrame() { + + effects.DimAll(170); effects.ShowFrame(); + + // draw a rainbow color palette + for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) { + for (uint8_t x = 0; x < MATRIX_WIDTH; x++) { + effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7); + } + } + + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + + effects.FillNoise(); + + effects.MoveX(3); + //effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + // effects.MoveFractionalNoiseX(4); + effects.ShowFrame(); + + return 0; + } +}; + +class PatternRainbowFlag : public Drawable { +public: + PatternRainbowFlag() { + name = (char *)"RainbowFlag"; + } + + unsigned int drawFrame() { + effects.DimAll(10); effects.ShowFrame(); + + CRGB rainbow[7] = { + CRGB::Red, + CRGB::Orange, + CRGB::Yellow, + CRGB::Green, + CRGB::Blue, + CRGB::Violet + }; + + uint8_t y = 2; + + for (uint8_t c = 0; c < 6; c++) { + for (uint8_t j = 0; j < 5; j++) { + for (uint8_t x = 0; x < VPANEL_W; x++) { + effects.leds[XY(x, y)] += rainbow[c]; + } + + y++; + if (y >= VPANEL_H) + break; + } + } + + // Noise + noise_x += 1000; + noise_y += 1000; + noise_scale_x = 4000; + noise_scale_y = 4000; + effects.FillNoise(); + + effects.MoveX(3); + // effects.MoveFractionalNoiseY(4); + + effects.MoveY(3); + // effects.MoveFractionalNoiseX(4); + + return 0; + } +}; +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h b/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h new file mode 100644 index 0000000..bc6618b --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternPendulumWave.h @@ -0,0 +1,56 @@ +/* +* +* Inspired by and based on a loading animation for Prismata by Lunarch Studios: +* http://www.reddit.com/r/gifs/comments/2on8si/connecting_to_server_so_mesmerizing/cmow0sz +* +* Lunarch Studios Inc. hereby publishes the Actionscript 3 source code pasted in this +* comment under the Creative Commons CC0 1.0 Universal Public Domain Dedication. +* Lunarch Studios Inc. waives all rights to the work worldwide under copyright law, +* including all related and neighboring rights, to the extent allowed by law. +* You can copy, modify, distribute and perform the work, even for commercial purposes, +* all without asking permission. +* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternPendulumWave_H +#define PatternPendulumWave_H + +class PatternPendulumWave : public Drawable { + public: + PatternPendulumWave() { + name = (char *)"Pendulum Wave"; + } + + unsigned int drawFrame() { + effects.DimAll(170); effects.ShowFrame(); + + for (int x = 0; x < VPANEL_W; x++) + { + uint8_t y = beatsin8(x + VPANEL_W, 0, VPANEL_H); + effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7)); + } + + return 15; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternPlasma.h b/examples/ChainedPanelsAuroraDemo/PatternPlasma.h new file mode 100644 index 0000000..dcecc97 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternPlasma.h @@ -0,0 +1,66 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternPlasma_H +#define PatternPlasma_H + +class PatternPlasma : public Drawable { +private: + int time = 0; + int cycles = 0; + +public: + PatternPlasma() { + name = (char *)"Plasma"; + } + + unsigned int drawFrame() { + for (int x = 0; x < VPANEL_W; x++) { + for (int y = 0; y < VPANEL_H; y++) { + int16_t v = 0; + uint8_t wibble = sin8(time); + v += sin16(x * wibble * 6 + time); + v += cos16(y * (128 - wibble) * 6 + time); + v += sin16(y * x * cos8(-time) / 8); + + effects.Pixel(x, y, (v >> 8) + 127); + } + } + + time += 1; + cycles++; + + if (cycles >= 2048) { + time = 0; + cycles = 0; + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternRadar.h b/examples/ChainedPanelsAuroraDemo/PatternRadar.h new file mode 100644 index 0000000..602078b --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternRadar.h @@ -0,0 +1,56 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternRadar_H + +class PatternRadar : public Drawable { + private: + byte theta = 0; + byte hueoffset = 0; + + public: + PatternRadar() { + name = (char *)"Radar"; + } + + unsigned int drawFrame() { + effects.DimAll(254); effects.ShowFrame(); + + for (int offset = 0; offset < MATRIX_CENTER_X; offset++) { + byte hue = 255 - (offset * 16 + hueoffset); + CRGB color = effects.ColorFromCurrentPalette(hue); + uint8_t x = mapcos8(theta, offset, (VPANEL_W - 1) - offset); + uint8_t y = mapsin8(theta, offset, (VPANEL_H - 1) - offset); + uint16_t xy = XY(x, y); + effects.leds[xy] = color; + + EVERY_N_MILLIS(25) { + theta += 2; + hueoffset += 1; + } + } + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h b/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h new file mode 100644 index 0000000..272c604 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternSimplexNoise.h @@ -0,0 +1,79 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/blob/master/examples/Noise/Noise.ino + * Copyright (c) 2013 FastLED + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSimplexNoise_H +#define PatternSimplexNoise_H + +class PatternSimplexNoise : public Drawable { + public: + PatternSimplexNoise() { + name = (char *)"Noise"; + } + + void start() { + // Initialize our coordinates to some random values + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } + + unsigned int drawFrame() { +#if FASTLED_VERSION >= 3001000 + // a new parameter set every 15 seconds + EVERY_N_SECONDS(15) { + noise_x = random16(); + noise_y = random16(); + noise_z = random16(); + } +#endif + + uint32_t speed = 100; + + effects.FillNoise(); + ShowNoiseLayer(0, 1, 0); + + // noise_x += speed; + noise_y += speed; + noise_z += speed; + + effects.ShowFrame(); + + return 0; + } + + // show just one layer + void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) { + for (uint8_t i = 0; i < VPANEL_W; i++) { + for (uint8_t j = 0; j < VPANEL_H; j++) { + uint8_t pixel = noise[i][j]; + + // assign a color depending on the actual palette + effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel); + } + } + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternSnake.h b/examples/ChainedPanelsAuroraDemo/PatternSnake.h new file mode 100644 index 0000000..6201985 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternSnake.h @@ -0,0 +1,145 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Portions of this code are adapted from LedEffects Snake by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Snake.cpp?at=default + * Copyright (c) 2013 Robert Atkins + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSnake_H +#define PatternSnake_H + +class PatternSnake : public Drawable { +private: + static const byte SNAKE_LENGTH = 16; + + CRGB colors[SNAKE_LENGTH]; + uint8_t initialHue; + + enum Direction { + UP, DOWN, LEFT, RIGHT + }; + + struct Pixel { + uint8_t x; + uint8_t y; + }; + + struct Snake { + Pixel pixels[SNAKE_LENGTH]; + + Direction direction; + + void newDirection() { + switch (direction) { + case UP: + case DOWN: + direction = random(0, 2) == 1 ? RIGHT : LEFT; + break; + + case LEFT: + case RIGHT: + direction = random(0, 2) == 1 ? DOWN : UP; + + default: + break; + } + } + + void shuffleDown() { + for (byte i = SNAKE_LENGTH - 1; i > 0; i--) { + pixels[i] = pixels[i - 1]; + } + } + + void reset() { + direction = UP; + for (int i = 0; i < SNAKE_LENGTH; i++) { + pixels[i].x = 0; + pixels[i].y = 0; + } + } + + void move() { + switch (direction) { + case UP: + pixels[0].y = (pixels[0].y + 1) % VPANEL_H; + break; + case LEFT: + pixels[0].x = (pixels[0].x + 1) % VPANEL_W; + break; + case DOWN: + pixels[0].y = pixels[0].y == 0 ? VPANEL_H - 1 : pixels[0].y - 1; + break; + case RIGHT: + pixels[0].x = pixels[0].x == 0 ? VPANEL_W - 1 : pixels[0].x - 1; + break; + } + } + + void draw(CRGB colors[SNAKE_LENGTH]) { + for (byte i = 0; i < SNAKE_LENGTH; i++) { + effects.leds[XY(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH)); + } + } + }; + + static const int snakeCount = 40; + Snake snakes[snakeCount]; + +public: + PatternSnake() { + name = (char *)"Snake"; + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + snake->reset(); + } + } + + void start() + { + effects.ClearFrame(); + } + + unsigned int drawFrame() { + + + fill_palette(colors, SNAKE_LENGTH, initialHue++, 5, effects.currentPalette, 255, LINEARBLEND); + + for (int i = 0; i < snakeCount; i++) { + Snake* snake = &snakes[i]; + + snake->shuffleDown(); + + if (random(10) > 7) { + snake->newDirection(); + } + + snake->move(); + snake->draw(colors); + } + + effects.ShowFrame(); + + return 30; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternSpiral.h b/examples/ChainedPanelsAuroraDemo/PatternSpiral.h new file mode 100644 index 0000000..23ce699 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternSpiral.h @@ -0,0 +1,138 @@ +/* + * Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: + * https://gist.github.com/anonymous/876f908333cd95315c35 + * + * Copyright (c) 2014 Stefan Petrick + * http://www.stefan-petrick.de/wordpress_beta + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiral_H +#define PatternSpiral_H + +class PatternSpiral : public Drawable { +private: + // Timer stuff (Oszillators) + struct timer { + unsigned long takt; + unsigned long lastMillis; + unsigned long count; + int delta; + byte up; + byte down; + }; + timer multiTimer[5]; + + int timers = sizeof(multiTimer) / sizeof(multiTimer[0]); + + // counts all variables with different speeds linear up and down + void UpdateTimers() + { + unsigned long now = millis(); + for (int i = 0; i < timers; i++) + { + while (now - multiTimer[i].lastMillis >= multiTimer[i].takt) + { + multiTimer[i].lastMillis += multiTimer[i].takt; + multiTimer[i].count = multiTimer[i].count + multiTimer[i].delta; + if ((multiTimer[i].count == multiTimer[i].up) || (multiTimer[i].count == multiTimer[i].down)) + { + multiTimer[i].delta = -multiTimer[i].delta; + } + } + } + } + +public: + PatternSpiral() { + name = (char *)"Spiral"; + } + + void start() { + // set all counting directions positive for the beginning + for (int i = 0; i < timers; i++) multiTimer[i].delta = 1; + + // set range (up/down), speed (takt=ms between steps) and starting point of all oszillators + + unsigned long now = millis(); + + multiTimer[0].lastMillis = now; + multiTimer[0].takt = 42; //x1 + multiTimer[0].up = VPANEL_W - 1; + multiTimer[0].down = 0; + multiTimer[0].count = 0; + + multiTimer[1].lastMillis = now; + multiTimer[1].takt = 55; //y1 + multiTimer[1].up = VPANEL_H - 1; + multiTimer[1].down = 0; + multiTimer[1].count = 0; + + multiTimer[2].lastMillis = now; + multiTimer[2].takt = 3; //color + multiTimer[2].up = 255; + multiTimer[2].down = 0; + multiTimer[2].count = 0; + + multiTimer[3].lastMillis = now; + multiTimer[3].takt = 71; //x2 + multiTimer[3].up = VPANEL_W - 1; + multiTimer[3].down = 0; + multiTimer[3].count = 0; + + multiTimer[4].lastMillis = now; + multiTimer[4].takt = 89; //y2 + multiTimer[4].up = VPANEL_H - 1; + multiTimer[4].down = 0; + multiTimer[4].count = 0; + } + + unsigned int drawFrame() { + // manage the Oszillators + UpdateTimers(); + + // draw just a line defined by 5 oszillators + effects.BresenhamLine( + multiTimer[3].count, // x1 + multiTimer[4].count, // y1 + multiTimer[0].count, // x2 + multiTimer[1].count, // y2 + multiTimer[2].count); // color + + // manipulate the screen buffer + // with fixed parameters (could be oszillators too) + // Params: center x, y, radius, scale color down + // --> NOTE: Affects always a SQUARE with an odd length + // effects.SpiralStream(15, 15, 10, 128); + + effects.SpiralStream(31, 15, 64, 128); // for 64 pixel wide matrix! + // effects.SpiralStream(47, 15, 10, 128); // for 64 pixel wide matrix! + + // why not several times?! + // effects.SpiralStream(16, 6, 6, 128); + // effects.SpiralStream(10, 24, 10, 128); + + // increase the contrast + effects.DimAll(250); effects.ShowFrame(); + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternSpiro.h b/examples/ChainedPanelsAuroraDemo/PatternSpiro.h new file mode 100644 index 0000000..9c75952 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternSpiro.h @@ -0,0 +1,107 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternSpiro_H + +class PatternSpiro : public Drawable { + private: + byte theta1 = 0; + byte theta2 = 0; + byte hueoffset = 0; + + uint8_t radiusx = VPANEL_W / 4; + uint8_t radiusy = VPANEL_H / 4; + uint8_t minx = MATRIX_CENTER_X - radiusx; + uint8_t maxx = MATRIX_CENTER_X + radiusx + 1; + uint8_t miny = MATRIX_CENTER_Y - radiusy; + uint8_t maxy = MATRIX_CENTER_Y + radiusy + 1; + + uint8_t spirocount = 1; + uint8_t spirooffset = 256 / spirocount; + boolean spiroincrement = false; + + boolean handledChange = false; + + public: + PatternSpiro() { + name = (char *)"Spiro"; + } + + unsigned int drawFrame() { + effects.DimAll(254); effects.ShowFrame(); + + boolean change = false; + + for (int i = 0; i < spirocount; i++) { + uint8_t x = mapsin8(theta1 + i * spirooffset, minx, maxx); + uint8_t y = mapcos8(theta1 + i * spirooffset, miny, maxy); + + uint8_t x2 = mapsin8(theta2 + i * spirooffset, x - radiusx, x + radiusx); + uint8_t y2 = mapcos8(theta2 + i * spirooffset, y - radiusy, y + radiusy); + + CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128); + effects.leds[XY(x2, y2)] += color; + + if((x2 == MATRIX_CENTER_X && y2 == MATRIX_CENTER_Y) || + (x2 == MATRIX_CENTRE_X && y2 == MATRIX_CENTRE_Y)) change = true; + } + + theta2 += 1; + + EVERY_N_MILLIS(25) { + theta1 += 1; + } + + EVERY_N_MILLIS(100) { + if (change && !handledChange) { + handledChange = true; + + if (spirocount >= VPANEL_W || spirocount == 1) spiroincrement = !spiroincrement; + + if (spiroincrement) { + if(spirocount >= 4) + spirocount *= 2; + else + spirocount += 1; + } + else { + if(spirocount > 4) + spirocount /= 2; + else + spirocount -= 1; + } + + spirooffset = 256 / spirocount; + } + + if(!change) handledChange = false; + } + + EVERY_N_MILLIS(33) { + hueoffset += 1; + } + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternSwirl.h b/examples/ChainedPanelsAuroraDemo/PatternSwirl.h new file mode 100644 index 0000000..96793ca --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternSwirl.h @@ -0,0 +1,77 @@ +/* +* Aurora: https://github.com/pixelmatix/aurora +* Copyright (c) 2014 Jason Coon +* +* Portions of this code are adapted from SmartMatrixSwirl by Mark Kriegsman: https://gist.github.com/kriegsman/5adca44e14ad025e6d3b +* https://www.youtube.com/watch?v=bsGBT-50cts +* Copyright (c) 2014 Mark Kriegsman +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef PatternSwirl_H + +class PatternSwirl : public Drawable { + private: + const uint8_t borderWidth = 2; + + public: + PatternSwirl() { + name = (char *)"Swirl"; + } + + void start() { + } + + unsigned int drawFrame() { + // Apply some blurring to whatever's already on the matrix + // Note that we never actually clear the matrix, we just constantly + // blur it repeatedly. Since the blurring is 'lossy', there's + // an automatic trend toward black -- by design. + uint8_t blurAmount = beatsin8(2, 10, 255); + +#if FASTLED_VERSION >= 3001000 + blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount); +#else + effects.DimAll(blurAmount); +#endif + + // Use two out-of-sync sine waves + uint8_t i = beatsin8(27, borderWidth, VPANEL_H - borderWidth); + uint8_t j = beatsin8(41, borderWidth, VPANEL_W - borderWidth); + // Also calculate some reflections + uint8_t ni = (VPANEL_W - 1) - i; + uint8_t nj = (VPANEL_W - 1) - j; + + // The color of each point shifts over time, each at a different speed. + uint16_t ms = millis(); + effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11); + effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13); + effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17); + effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); + effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37); + effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41); + + + effects.ShowFrame(); + return 0; + + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/PatternWave.h b/examples/ChainedPanelsAuroraDemo/PatternWave.h new file mode 100644 index 0000000..90e7448 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/PatternWave.h @@ -0,0 +1,120 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PatternWave_H +#define PatternWave_H + +class PatternWave : public Drawable { +private: + byte thetaUpdate = 0; + byte thetaUpdateFrequency = 0; + byte theta = 0; + + byte hueUpdate = 0; + byte hueUpdateFrequency = 0; + byte hue = 0; + + byte rotation = 0; + + uint8_t scale = 256 / VPANEL_W; + + uint8_t maxX = VPANEL_W - 1; + uint8_t maxY = VPANEL_H - 1; + + uint8_t waveCount = 1; + +public: + PatternWave() { + name = (char *)"Wave"; + } + + void start() { + rotation = random(0, 4); + waveCount = random(1, 3); + + } + + unsigned int drawFrame() { + int n = 0; + + switch (rotation) { + case 0: + for (int x = 0; x < VPANEL_W; x++) { + n = quadwave8(x * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 1: + for (int y = 0; y < VPANEL_H; y++) { + n = quadwave8(y * 2 + theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + + case 2: + for (int x = 0; x < VPANEL_W; x++) { + n = quadwave8(x * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue)); + } + break; + + case 3: + for (int y = 0; y < VPANEL_H; y++) { + n = quadwave8(y * 2 - theta) / scale; + effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue)); + if (waveCount == 2) + effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue)); + } + break; + } + + effects.DimAll(254); + effects.ShowFrame(); + + if (thetaUpdate >= thetaUpdateFrequency) { + thetaUpdate = 0; + theta++; + } + else { + thetaUpdate++; + } + + if (hueUpdate >= hueUpdateFrequency) { + hueUpdate = 0; + hue++; + } + else { + hueUpdate++; + } + + return 0; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/Patterns.h b/examples/ChainedPanelsAuroraDemo/Patterns.h new file mode 100644 index 0000000..8242fb1 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Patterns.h @@ -0,0 +1,259 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Patterns_H +#define Patterns_H + +#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) + +#include "Vector.h" +#include "Boid.h" +#include "Attractor.h" + +/* + * Note from mrfaptastic: + * + * Commented out patterns are due to the fact they either didn't work properly with a non-square display, + * or from my personal opinion, are crap. + * + * Kosso: I have removed the crappy ones and added a less crappy (and working!) Fire demo ;) + * + */ +#include "PaletteFireKoz.h" // Added by Kosso +#include "PatternFireKoz.h" // Added by Kosso +#include "PatternSpiro.h" +#include "PatternRadar.h" +#include "PatternSwirl.h" +#include "PatternPendulumWave.h" +#include "PatternFlowField.h" +#include "PatternIncrementalDrift.h" +#include "PatternMunch.h" +#include "PatternElectricMandala.h" +#include "PatternSimplexNoise.h" +#include "PatternWave.h" +#include "PatternAttract.h" +#include "PatternFlock.h" +#include "PatternInfinity.h" +#include "PatternPlasma.h" +#include "PatternSnake.h" +#include "PatternFire.h" // Not very good. +#include "PatternLife.h" +#include "PatternMaze.h" +#include "PatternSpiral.h" + + +class Patterns : public Playlist { + private: + PatternFireKoz fireKoz; + PatternSpiro spiro; + PatternSwirl swirl; + PatternPendulumWave pendulumWave; + PatternFlowField flowField; + PatternIncrementalDrift incrementalDrift; + PatternMunch munch; + PatternElectricMandala electricMandala; + PatternSimplexNoise simplexNoise; + PatternWave wave; + PatternAttract attract; + PatternFlock flock; + PatternPlasma plasma; + PatternSnake snake; + PatternFire fire; + PatternLife life; + PatternMaze maze; + PatternSpiral spiral; + + int currentIndex = 0; + Drawable* currentItem; + + int getCurrentIndex() { + return currentIndex; + } + + const static int PATTERN_COUNT = 18; + + Drawable* shuffledItems[PATTERN_COUNT]; + + Drawable* items[PATTERN_COUNT] = { + &fireKoz, // added by Kosso + &spiro, + &life, + &flowField, + &pendulumWave, + &incrementalDrift, + &munch, + &electricMandala, + &simplexNoise, + &wave, + &attract, + &swirl, + &flock, + &plasma, + &snake, + &fire, + &maze, + &spiral, + }; + + public: + Patterns() { + // add the items to the shuffledItems array + for (int a = 0; a < PATTERN_COUNT; a++) { + shuffledItems[a] = items[a]; + } + + shuffleItems(); + + this->currentItem = items[0]; + this->currentItem->start(); + } + + char* Drawable::name = (char *)"Patterns"; + + void stop() { + if (currentItem) + currentItem->stop(); + } + + void start() { + if (currentItem) + currentItem->start(); + } + + void move(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + moveTo(currentIndex); + + //if (!isTimeAvailable && currentItem == &analogClock) + // move(step); + } + + void moveRandom(int step) { + currentIndex += step; + + if (currentIndex >= PATTERN_COUNT) currentIndex = 0; + else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1; + + if (effects.paletteIndex == effects.RandomPaletteIndex) + effects.RandomPalette(); + + if (currentItem) + currentItem->stop(); + + currentItem = shuffledItems[currentIndex]; + + if (currentItem) + currentItem->start(); + + // if (!isTimeAvailable && currentItem == &analogClock) + // moveRandom(step); + } + + void shuffleItems() { + for (int a = 0; a < PATTERN_COUNT; a++) + { + int r = random(a, PATTERN_COUNT); + Drawable* temp = shuffledItems[a]; + shuffledItems[a] = shuffledItems[r]; + shuffledItems[r] = temp; + } + } + + + unsigned int drawFrame() { + return currentItem->drawFrame(); + } + + void listPatterns() { + Serial.println(F("{")); + Serial.print(F(" \"count\": ")); + Serial.print(PATTERN_COUNT); + Serial.println(","); + Serial.println(F(" \"results\": [")); + + for (int i = 0; i < PATTERN_COUNT; i++) { + Serial.print(F(" \"")); + Serial.print(i, DEC); + Serial.print(F(": ")); + Serial.print(items[i]->name); + if (i == PATTERN_COUNT - 1) + Serial.println(F("\"")); + else + Serial.println(F("\",")); + } + + Serial.println(" ]"); + Serial.println("}"); + } + + int getPatternIndex() + { + return currentIndex; + } + + char * getCurrentPatternName() + { + return currentItem->name; + } + + void moveTo(int index) { + if (currentItem) + currentItem->stop(); + + currentIndex = index; + + currentItem = items[currentIndex]; + + if (currentItem) + currentItem->start(); + } + + bool setPattern(String name) { + for (int i = 0; i < PATTERN_COUNT; i++) { + if (name.compareTo(items[i]->name) == 0) { + moveTo(i); + return true; + } + } + + return false; + } + + + bool setPattern(int index) { + if (index >= PATTERN_COUNT || index < 0) + return false; + + moveTo(index); + + return true; + } +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/Playlist.h b/examples/ChainedPanelsAuroraDemo/Playlist.h new file mode 100644 index 0000000..29c0c87 --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Playlist.h @@ -0,0 +1,39 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Playlist_H +#define Playlist_H + +class Playlist : public Drawable { +public: + virtual bool isPlaylist() { + return true; + } + + boolean isCurrentItemFinished = true; + + virtual void move(int step) = 0; + virtual void moveRandom(int step) = 0; + virtual int getCurrentIndex(); +}; + +#endif diff --git a/examples/ChainedPanelsAuroraDemo/Vector.h b/examples/ChainedPanelsAuroraDemo/Vector.h new file mode 100644 index 0000000..8acbadc --- /dev/null +++ b/examples/ChainedPanelsAuroraDemo/Vector.h @@ -0,0 +1,169 @@ +/* + * Aurora: https://github.com/pixelmatix/aurora + * Copyright (c) 2014 Jason Coon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef Vector_H +#define Vector_H + +template +class Vector2 { +public: + T x, y; + + Vector2() :x(0), y(0) {} + Vector2(T x, T y) : x(x), y(y) {} + Vector2(const Vector2& v) : x(v.x), y(v.y) {} + + Vector2& operator=(const Vector2& v) { + x = v.x; + y = v.y; + return *this; + } + + bool isEmpty() { + return x == 0 && y == 0; + } + + bool operator==(Vector2& v) { + return x == v.x && y == v.y; + } + + bool operator!=(Vector2& v) { + return !(x == y); + } + + Vector2 operator+(Vector2& v) { + return Vector2(x + v.x, y + v.y); + } + Vector2 operator-(Vector2& v) { + return Vector2(x - v.x, y - v.y); + } + + Vector2& operator+=(Vector2& v) { + x += v.x; + y += v.y; + return *this; + } + Vector2& operator-=(Vector2& v) { + x -= v.x; + y -= v.y; + return *this; + } + + Vector2 operator+(double s) { + return Vector2(x + s, y + s); + } + Vector2 operator-(double s) { + return Vector2(x - s, y - s); + } + Vector2 operator*(double s) { + return Vector2(x * s, y * s); + } + Vector2 operator/(double s) { + return Vector2(x / s, y / s); + } + + Vector2& operator+=(double s) { + x += s; + y += s; + return *this; + } + Vector2& operator-=(double s) { + x -= s; + y -= s; + return *this; + } + Vector2& operator*=(double s) { + x *= s; + y *= s; + return *this; + } + Vector2& operator/=(double s) { + x /= s; + y /= s; + return *this; + } + + void set(T x, T y) { + this->x = x; + this->y = y; + } + + void rotate(double deg) { + double theta = deg / 180.0 * M_PI; + double c = cos(theta); + double s = sin(theta); + double tx = x * c - y * s; + double ty = x * s + y * c; + x = tx; + y = ty; + } + + Vector2& normalize() { + if (length() == 0) return *this; + *this *= (1.0 / length()); + return *this; + } + + float dist(Vector2 v) const { + Vector2 d(v.x - x, v.y - y); + return d.length(); + } + float length() const { + return sqrt(x * x + y * y); + } + + float mag() const { + return length(); + } + + float magSq() { + return (x * x + y * y); + } + + void truncate(double length) { + double angle = atan2f(y, x); + x = length * cos(angle); + y = length * sin(angle); + } + + Vector2 ortho() const { + return Vector2(y, -x); + } + + static float dot(Vector2 v1, Vector2 v2) { + return v1.x * v2.x + v1.y * v2.y; + } + static float cross(Vector2 v1, Vector2 v2) { + return (v1.x * v2.y) - (v1.y * v2.x); + } + + void limit(float max) { + if (magSq() > max*max) { + normalize(); + *this *= max; + } + } +}; + +typedef Vector2 PVector; + +#endif