Compare commits
1 commit
master
...
fix/allow-
Author | SHA1 | Date | |
---|---|---|---|
95dccdcc38 |
|
@ -204,7 +204,7 @@ Yes!
|
|||
|
||||
For example: If you want to chain two of these horizontally to make a 128x32 panel you can do so by connecting the panels in series using the HUB75 ribbon cable. Than you must provide proper configuration structure to the class constructor letting it know that you use "one long virtual matrix chain". Refer to [Pattern Plasma](/examples/2_PatternPlasma/) example for all the details about configuration setup.
|
||||
|
||||
Finally, if you wanted to chain 4 x (64x32px) panels to make 128x64px display (essentially a 2x2 grid of 64x32 LED Matrix modules), a little more magic will be required. Refer to the [VirtualMatrixPanel](examples/VirtualMatrixPanel/) example and the [AuroraDemo](examples/AuroraDemo/) example of its practical use.
|
||||
Finally, if you wanted to chain 4 x (64x32px) panels to make 128x64px display (essentially a 2x2 grid of 64x32 LED Matrix modules), a little more magic will be required. Refer to the [Chained Panels](examples/ChainedPanels/) example.
|
||||
|
||||
Resolutions beyond 128x64 are more likely to result in crashes due to [memory](/doc/i2s_memcalc.md) constraints etc. You are on your own after this point - PLEASE do not raise issues about this, the library can't magically defeat the SRAM memory constraints of the ESP32.
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ void setup() {
|
|||
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
|
||||
// let's adjust default brightness to about 75%
|
||||
dma_display->setBrightness8(255); // range is 0-255, 0 - 0%, 255 - 100%
|
||||
dma_display->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100%
|
||||
|
||||
// Allocate memory and start DMA display
|
||||
if( not dma_display->begin() )
|
||||
|
@ -176,13 +176,13 @@ void loop() {
|
|||
|
||||
for (int x = 0; x < PANE_WIDTH; x++) {
|
||||
for (int y = 0; y < PANE_HEIGHT; y++) {
|
||||
int16_t v = 128;
|
||||
int16_t v = 0;
|
||||
uint8_t wibble = sin8(time_counter);
|
||||
v += sin16(x * wibble * 3 + time_counter);
|
||||
v += cos16(y * (128 - wibble) + time_counter);
|
||||
v += sin16(y * x * cos8(-time_counter) / 8);
|
||||
|
||||
currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
|
||||
currentColor = ColorFromPalette(currentPalette, (v >> 8) + 127); //, brightness, currentBlendType);
|
||||
dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
## Animated GIF Decoding Example
|
||||
|
||||
### Prerequisites
|
||||
1. The excellent 'AnimatedGIF' library by Larry Bank needs to be installed: https://github.com/bitbank2/AnimatedGIF
|
||||
|
||||
2. The files in the 'data' folder are written to the ESP32's SPIFFS file system. In order to be able to do this using the Arduino 2.0 IDE, you need to install the ESP32 LittleFS plugin: https://github.com/lorol/arduino-esp32littlefs-plugin
|
||||
|
||||
Follow the instructions in the link to install the plugin: https://randomnerdtutorials.com/arduino-ide-2-install-esp32-littlefs/
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
https://github.com/bitbank2/AnimatedGIF
|
|
@ -18,17 +18,26 @@
|
|||
* 3. Have fun.
|
||||
*/
|
||||
|
||||
#include "FS.h"
|
||||
#include <LittleFS.h>
|
||||
#define FILESYSTEM SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
#include <AnimatedGIF.h>
|
||||
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
|
||||
|
||||
#define FILESYSTEM LittleFS
|
||||
#define FORMAT_LITTLEFS_IF_FAILED true
|
||||
// ----------------------------
|
||||
|
||||
#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
|
||||
/*
|
||||
* Below is an is the 'legacy' way of initialising the MatrixPanel_I2S_DMA class.
|
||||
* i.e. MATRIX_WIDTH and MATRIX_HEIGHT are modified by compile-time directives.
|
||||
* By default the library assumes a single 64x32 pixel panel is connected.
|
||||
*
|
||||
* Refer to the example '2_PatternPlasma' on the new / correct way to setup this library
|
||||
* for different resolutions / panel chain lengths within the sketch 'setup()'.
|
||||
*
|
||||
*/
|
||||
|
||||
#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 PANEL_CHAIN 1 // Total number of panels chained one to another horizontally only.
|
||||
#define PANEL_CHAIN 1 // Total number of panels chained one to another
|
||||
|
||||
//MatrixPanel_I2S_DMA dma_display;
|
||||
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
||||
|
@ -39,6 +48,7 @@ uint16_t myRED = dma_display->color565(255, 0, 0);
|
|||
uint16_t myGREEN = dma_display->color565(0, 255, 0);
|
||||
uint16_t myBLUE = dma_display->color565(0, 0, 255);
|
||||
|
||||
|
||||
AnimatedGIF gif;
|
||||
File f;
|
||||
int x_offset, y_offset;
|
||||
|
@ -53,8 +63,8 @@ void GIFDraw(GIFDRAW *pDraw)
|
|||
int x, y, iWidth;
|
||||
|
||||
iWidth = pDraw->iWidth;
|
||||
if (iWidth > dma_display->width())
|
||||
iWidth = dma_display->width();
|
||||
if (iWidth > MATRIX_WIDTH)
|
||||
iWidth = MATRIX_WIDTH;
|
||||
|
||||
usPalette = pDraw->pPalette;
|
||||
y = pDraw->iY + pDraw->y; // current line
|
||||
|
@ -185,9 +195,9 @@ void ShowGIF(char *name)
|
|||
|
||||
if (gif.open(name, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
|
||||
{
|
||||
x_offset = (dma_display->width() - gif.getCanvasWidth())/2;
|
||||
x_offset = (MATRIX_WIDTH - gif.getCanvasWidth())/2;
|
||||
if (x_offset < 0) x_offset = 0;
|
||||
y_offset = (dma_display->height() - gif.getCanvasHeight())/2;
|
||||
y_offset = (MATRIX_HEIGHT - gif.getCanvasHeight())/2;
|
||||
if (y_offset < 0) y_offset = 0;
|
||||
Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
|
||||
Serial.flush();
|
||||
|
@ -207,21 +217,17 @@ void ShowGIF(char *name)
|
|||
/************************* Arduino Sketch Setup and Loop() *******************************/
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
|
||||
Serial.println("LittleFS Mount Failed");
|
||||
return;
|
||||
}
|
||||
delay(1000);
|
||||
|
||||
HUB75_I2S_CFG mxconfig(
|
||||
PANEL_RES_X, // module width
|
||||
PANEL_RES_Y, // module height
|
||||
PANEL_CHAIN // Chain of panels - Horizontal width only.
|
||||
PANEL_CHAIN // Chain length
|
||||
);
|
||||
|
||||
// mxconfig.gpio.e = 18;
|
||||
// mxconfig.clkphase = false;
|
||||
// mxconfig.driver = HUB75_I2S_CFG::FM6126A;
|
||||
// mxconfig.gpio.e = 18;
|
||||
// mxconfig.clkphase = false;
|
||||
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
|
||||
|
||||
// Display Setup
|
||||
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
|
@ -230,7 +236,18 @@ void setup() {
|
|||
dma_display->clearScreen();
|
||||
dma_display->fillScreen(myWHITE);
|
||||
|
||||
// Start going through GIFS
|
||||
Serial.println("Starting AnimatedGIFs Sketch");
|
||||
|
||||
// Start filesystem
|
||||
Serial.println(" * Loading SPIFFS");
|
||||
if(!SPIFFS.begin()){
|
||||
Serial.println("SPIFFS Mount Failed");
|
||||
}
|
||||
|
||||
dma_display->begin();
|
||||
|
||||
/* all other pixel drawing functions can only be called after .begin() */
|
||||
dma_display->fillScreen(dma_display->color565(0, 0, 0));
|
||||
gif.begin(LITTLE_ENDIAN_PIXELS);
|
||||
|
||||
}
|
||||
|
@ -270,7 +287,4 @@ void loop()
|
|||
delay(1000); // pause before restarting
|
||||
|
||||
} // while
|
||||
}
|
||||
|
||||
// Other LittleFS filesystem function examples available at:
|
||||
// https://randomnerdtutorials.com/esp32-write-data-littlefs-arduino/
|
||||
}
|
13
examples/AnimatedGIFPanel_SPIFFS/README.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
## Animated GIF Decoding Example
|
||||
|
||||
### Prerequisites
|
||||
1. The excellent 'AnimatedGIF' library by Larry Bank needs to be installed: https://github.com/bitbank2/AnimatedGIF
|
||||
|
||||
This is available via the Arduino Library manager, or can be placed in the 'libs' directory with PlatformIO.
|
||||
|
||||
2. The files in the 'data' folder are written to the ESP32's SPIFFS file system.
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
https://github.com/bitbank2/AnimatedGIF
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
@ -24,7 +24,7 @@
|
|||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Vector2.hpp"
|
||||
#include "Vector.h"
|
||||
|
||||
class Attractor {
|
||||
public:
|
||||
|
@ -33,7 +33,7 @@ public:
|
|||
PVector location; // Location
|
||||
|
||||
Attractor() {
|
||||
location = PVector(effects.getCenterX(), effects.getCenterY());
|
||||
location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y);
|
||||
mass = 10;
|
||||
G = .5;
|
||||
}
|
|
@ -1,204 +1,150 @@
|
|||
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
|
||||
|
||||
/*--------------------- MATRIX GPIO CONFIG -------------------------*/
|
||||
#define R1_PIN 25
|
||||
#define G1_PIN 26
|
||||
#define B1_PIN 27
|
||||
#define R2_PIN 14
|
||||
#define G2_PIN 12
|
||||
#define B2_PIN 13
|
||||
#define A_PIN 23
|
||||
#define B_PIN 19 // Changed from library default
|
||||
#define C_PIN 5
|
||||
#define D_PIN 17
|
||||
#define E_PIN -1
|
||||
#define LAT_PIN 4
|
||||
#define OE_PIN 15
|
||||
#define CLK_PIN 16
|
||||
|
||||
|
||||
/*--------------------- MATRIX PANEL CONFIG -------------------------*/
|
||||
#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 PANEL_CHAIN 1 // Total number of panels chained one to another
|
||||
|
||||
/*
|
||||
_ _ _ ____ ___ ____ _
|
||||
/ \ | | | | _ \ / _ \| _ \ / \
|
||||
/ _ \ | | | | |_) | | | | |_) | / _ \
|
||||
/ ___ \| |_| | _ <| |_| | _ < / ___ \
|
||||
/_/ \_\\___/|_| \_\\___/|_| \_\/_/ \_\
|
||||
|
||||
____ _____ __ __ ___
|
||||
| _ \| ____| \/ |/ _ \
|
||||
| | | | _| | |\/| | | | |
|
||||
| |_| | |___| | | | |_| |
|
||||
|____/|_____|_| |_|\___/
|
||||
|
||||
Description:
|
||||
* This demonstrates a combination of the following libraries two:
|
||||
- "ESP32-HUB75-MatrixPanel-DMA" to send pixel data to the physical panels in combination with its
|
||||
in-built "VirtualMatrix" class which used to create a virtual display of chained panels, so the
|
||||
graphical effects of the Aurora demonstration can be shown on a 'bigger' grid of physical panels
|
||||
acting as one big display.
|
||||
|
||||
- "GFX_Lite" to provide a simple graphics library for drawing on the virtual display.
|
||||
GFX_Lite is a fork of AdaFruitGFX and FastLED library combined together, with a focus on simplicity and ease of use.
|
||||
|
||||
Instructions:
|
||||
* Use the serial input to advance through the patterns, or to toggle auto advance. Sending 'n' will advance to the next
|
||||
pattern, 'p' will go to the previous pattern. Sending 'a' will toggle auto advance on and off.
|
||||
//Another way of creating config structure
|
||||
//Custom pin mapping for all pins
|
||||
HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK};
|
||||
HUB75_I2S_CFG mxconfig(
|
||||
64, // width
|
||||
64, // height
|
||||
4, // chain length
|
||||
_pins, // pin mapping
|
||||
HUB75_I2S_CFG::FM6126A // driver chip
|
||||
);
|
||||
|
||||
*/
|
||||
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
||||
|
||||
#define USE_GFX_LITE 1
|
||||
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>
|
||||
|
||||
/***************************************************************************************************************************/
|
||||
|
||||
// Step 1) Provide the size of each individual physical panel LED Matrix panel that is chained (or not) together
|
||||
#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.
|
||||
|
||||
// Step 2) Provide details of the physical panel chaining that is in place.
|
||||
#define NUM_ROWS 2 // Number of rows of chained INDIVIDUAL PANELS
|
||||
#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW
|
||||
#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another
|
||||
|
||||
// Step 3) How are the panels chained together?
|
||||
#define PANEL_CHAIN_TYPE CHAIN_TOP_RIGHT_DOWN
|
||||
|
||||
// Refer to: https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/tree/master/examples/VirtualMatrixPanel
|
||||
// and: https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA/blob/master/doc/VirtualMatrixPanel.pdf
|
||||
|
||||
// Virtual Panel dimensions - our combined panel would be a square 4x4 modules with a combined resolution of 128x128 pixels
|
||||
#define VPANEL_W PANEL_RES_X*NUM_COLS // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these.
|
||||
#define VPANEL_H PANEL_RES_Y*NUM_ROWS //
|
||||
|
||||
/***************************************************************************************************************************/
|
||||
|
||||
// The palettes are set to change every 60 seconds.
|
||||
int lastPattern = 0;
|
||||
// Module configuration
|
||||
HUB75_I2S_CFG mxconfig(
|
||||
PANEL_RES_X, // module width
|
||||
PANEL_RES_Y, // module height
|
||||
PANEL_CHAIN // Chain length
|
||||
);
|
||||
|
||||
|
||||
// placeholder for the matrix object
|
||||
MatrixPanel_I2S_DMA *matrix = nullptr;
|
||||
|
||||
// placeholder for the virtual display object
|
||||
VirtualMatrixPanel *virtualDisp = nullptr;
|
||||
//mxconfig.gpio.e = -1; // Assign a pin if you have a 64x64 panel
|
||||
//mxconfig.clkphase = false; // Change this if you have issues with ghosting.
|
||||
//mxconfig.driver = HUB75_I2S_CFG::FM6126A; // Change this according to your pane.
|
||||
|
||||
|
||||
#include "EffectsLayer.hpp" // FastLED CRGB Pixel Buffer for which the patterns are drawn
|
||||
EffectsLayer effects(VPANEL_W, VPANEL_H);
|
||||
|
||||
#include "Drawable.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include <FastLED.h>
|
||||
|
||||
#include "Patterns.hpp"
|
||||
#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_previous_palette = 0;
|
||||
unsigned long ms_animation_max_duration = 30000; // 10 seconds
|
||||
unsigned long next_frame = 0;
|
||||
|
||||
void listPatterns();
|
||||
unsigned long fps = 0, fps_timer; // fps (this is NOT a matrix refresh rate!)
|
||||
unsigned int default_fps = 30, pattern_fps = 30; // default fps limit (this is not a matrix refresh counter!)
|
||||
unsigned long ms_animation_max_duration = 20000; // 20 seconds
|
||||
unsigned long last_frame=0, ms_previous=0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Setup serial interface
|
||||
/************** SERIAL **************/
|
||||
Serial.begin(115200);
|
||||
delay(250);
|
||||
|
||||
/************** DISPLAY **************/
|
||||
Serial.println("...Starting Display");
|
||||
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
dma_display->begin();
|
||||
dma_display->setBrightness8(90); //0-255
|
||||
|
||||
|
||||
// Configure your matrix setup here
|
||||
HUB75_I2S_CFG mxconfig(PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN);
|
||||
|
||||
// custom pin mapping (if required)
|
||||
//HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK};
|
||||
//mxconfig.gpio = _pins;
|
||||
|
||||
// in case that we use panels based on FM6126A chip, we can change that
|
||||
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
|
||||
|
||||
// FM6126A panels could be cloked at 20MHz with no visual artefacts
|
||||
// mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
|
||||
|
||||
// OK, now we can create our matrix object
|
||||
matrix = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
|
||||
// Allocate memory and start DMA display
|
||||
if( not matrix->begin() )
|
||||
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
|
||||
|
||||
// let's adjust default brightness to about 75%
|
||||
matrix->setBrightness8(192); // range is 0-255, 0 - 0%, 255 - 100%
|
||||
|
||||
// create VirtualDisplay object based on our newly created dma_display object
|
||||
virtualDisp = new VirtualMatrixPanel((*matrix), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN_TYPE);
|
||||
|
||||
dma_display->fillScreenRGB888(128,0,0);
|
||||
delay(1000);
|
||||
dma_display->fillScreenRGB888(0,0,128);
|
||||
delay(1000);
|
||||
dma_display->clearScreen();
|
||||
delay(1000);
|
||||
Serial.println("**************** Starting Aurora Effects Demo ****************");
|
||||
|
||||
Serial.print("MATRIX_WIDTH: "); Serial.println(PANEL_RES_X*PANEL_CHAIN);
|
||||
Serial.print("MATRIX_HEIGHT: "); Serial.println(PANEL_RES_Y);
|
||||
|
||||
#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();
|
||||
|
||||
|
||||
patterns.setPattern(0);
|
||||
patterns.start();
|
||||
|
||||
ms_previous = millis();
|
||||
patterns.moveRandom(1); // start from a random pattern
|
||||
|
||||
Serial.print("Starting with pattern: ");
|
||||
Serial.println(patterns.getCurrentPatternName());
|
||||
|
||||
patterns.start();
|
||||
ms_previous = millis();
|
||||
fps_timer = millis();
|
||||
}
|
||||
|
||||
|
||||
bool autoAdvance = true;
|
||||
char incomingByte = 0;
|
||||
void handleSerialRead()
|
||||
{
|
||||
if (Serial.available() > 0) {
|
||||
|
||||
// read the incoming byte:
|
||||
incomingByte = Serial.read();
|
||||
|
||||
if (incomingByte == 'n') {
|
||||
Serial.println("Going to next pattern");
|
||||
patterns.move(1);
|
||||
}
|
||||
|
||||
if (incomingByte == 'p') {
|
||||
Serial.println("Going to previous pattern");
|
||||
patterns.move(-1);
|
||||
}
|
||||
|
||||
if (incomingByte == 'a') {
|
||||
autoAdvance = !autoAdvance;
|
||||
|
||||
if (autoAdvance)
|
||||
Serial.println("Auto pattern advance is ON");
|
||||
else
|
||||
Serial.println("Auto pattern advance is OFF");
|
||||
}
|
||||
|
||||
ms_previous = millis();
|
||||
}
|
||||
} // end handleSerialRead
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// menu.run(mainMenuItems, mainMenuItemCount);
|
||||
|
||||
handleSerialRead();
|
||||
if ( (millis() - ms_previous) > ms_animation_max_duration )
|
||||
{
|
||||
patterns.stop();
|
||||
patterns.moveRandom(1);
|
||||
//patterns.move(1);
|
||||
patterns.start();
|
||||
|
||||
Serial.print("Changing pattern to: ");
|
||||
Serial.println(patterns.getCurrentPatternName());
|
||||
|
||||
ms_previous = millis();
|
||||
|
||||
ms_current = millis();
|
||||
|
||||
if (ms_current - ms_previous_palette > 10000) // change colour palette evert 10 seconds
|
||||
{
|
||||
effects.RandomPalette();
|
||||
ms_previous_palette = ms_current;
|
||||
}
|
||||
|
||||
if ( ((ms_current - ms_previous) > ms_animation_max_duration) && autoAdvance)
|
||||
{
|
||||
|
||||
patterns.move(1);
|
||||
|
||||
ms_previous = ms_current;
|
||||
// Select a random palette as well
|
||||
//effects.RandomPalette();
|
||||
}
|
||||
|
||||
if ( next_frame < ms_current)
|
||||
next_frame = patterns.drawFrame() + ms_current;
|
||||
if ( 1000 / pattern_fps + last_frame < millis()){
|
||||
last_frame = millis();
|
||||
pattern_fps = patterns.drawFrame();
|
||||
if (!pattern_fps)
|
||||
pattern_fps = default_fps;
|
||||
|
||||
++fps;
|
||||
}
|
||||
|
||||
if (fps_timer + 1000 < millis()){
|
||||
Serial.printf_P(PSTR("Effect fps: %ld\n"), fps);
|
||||
fps_timer = millis();
|
||||
fps = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void listPatterns() {
|
||||
patterns.listPatterns();
|
||||
}
|
||||
}
|
326
examples/AuroraDemo/Boid.h
Normal file
|
@ -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 <http://www.shiffman.net>
|
||||
// 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 = MATRIX_WIDTH - 1;
|
||||
if (location.y < 0) location.y = MATRIX_HEIGHT - 1;
|
||||
if (location.x >= MATRIX_WIDTH) location.x = 0;
|
||||
if (location.y >= MATRIX_HEIGHT) location.y = 0;
|
||||
}
|
||||
|
||||
void avoidBorders() {
|
||||
PVector desired = velocity;
|
||||
|
||||
if (location.x < 8) desired = PVector(maxspeed, velocity.y);
|
||||
if (location.x >= MATRIX_WIDTH - 8) desired = PVector(-maxspeed, velocity.y);
|
||||
if (location.y < 8) desired = PVector(velocity.x, maxspeed);
|
||||
if (location.y >= MATRIX_HEIGHT - 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 >= MATRIX_WIDTH) location.x = MATRIX_WIDTH - 1;
|
||||
if (location.y >= MATRIX_HEIGHT) location.y = MATRIX_HEIGHT - 1;
|
||||
}
|
||||
|
||||
bool bounceOffBorders(float bounce) {
|
||||
bool bounced = false;
|
||||
|
||||
if (location.x >= MATRIX_WIDTH) {
|
||||
location.x = MATRIX_WIDTH - 1;
|
||||
velocity.x *= -bounce;
|
||||
bounced = true;
|
||||
}
|
||||
else if (location.x < 0) {
|
||||
location.x = 0;
|
||||
velocity.x *= -bounce;
|
||||
bounced = true;
|
||||
}
|
||||
|
||||
if (location.y >= MATRIX_HEIGHT) {
|
||||
location.y = MATRIX_HEIGHT - 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();
|
||||
//dma_display->drawBackgroundPixelRGB888(location.x, location.y, CRGB::Blue);
|
||||
}
|
||||
};
|
||||
|
||||
static const uint8_t AVAILABLE_BOID_COUNT = 40;
|
||||
Boid boids[AVAILABLE_BOID_COUNT];
|
55
examples/AuroraDemo/Drawable.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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() {
|
||||
dma_display->fillScreen(0);
|
||||
//backgroundLayer.fillScreen({ 0, 0, 0 });
|
||||
return 0;
|
||||
};
|
||||
|
||||
virtual void printTesting()
|
||||
{
|
||||
Serial.println("Testing...");
|
||||
}
|
||||
|
||||
virtual void start() {};
|
||||
virtual void stop() {};
|
||||
};
|
||||
|
||||
#endif
|
848
examples/AuroraDemo/Effects.h
Normal file
|
@ -0,0 +1,848 @@
|
|||
|
||||
/*
|
||||
* 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;
|
||||
// US vs GB, huh? :)
|
||||
//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
|
||||
//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
|
||||
#define MATRIX_CENTRE_X MATRIX_CENTER_X
|
||||
#define MATRIX_CENTRE_Y MATRIX_CENTER_Y
|
||||
|
||||
|
||||
const uint16_t NUM_LEDS = (MATRIX_WIDTH * MATRIX_HEIGHT) + 1; // one led spare to capture out of bounds
|
||||
|
||||
// forward declaration
|
||||
uint16_t XY16( uint16_t x, uint16_t y);
|
||||
|
||||
/* 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.
|
||||
* Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrices :(
|
||||
*/
|
||||
uint16_t XY( uint8_t x, uint8_t y)
|
||||
{
|
||||
return XY16(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* The one for 256+ matrices
|
||||
* otherwise this:
|
||||
* for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {}
|
||||
* turns into an infinite loop
|
||||
*/
|
||||
uint16_t XY16( uint16_t x, uint16_t y)
|
||||
{
|
||||
if( x >= MATRIX_WIDTH) return 0;
|
||||
if( y >= MATRIX_HEIGHT) return 0;
|
||||
|
||||
return (y * MATRIX_WIDTH) + x + 1; // everything offset by one to compute out of bounds stuff - never displayed by ShowFrame()
|
||||
}
|
||||
|
||||
|
||||
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]; // none of the currently enabled effects uses this
|
||||
|
||||
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[MATRIX_WIDTH][MATRIX_HEIGHT];
|
||||
uint8_t **noise = nullptr; // we will allocate mem later
|
||||
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).
|
||||
|
||||
Effects(){
|
||||
// we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices
|
||||
leds = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB));
|
||||
|
||||
// allocate mem for noise effect
|
||||
// (there should be some guards for malloc errors eventually)
|
||||
noise = (uint8_t **)malloc(MATRIX_WIDTH * sizeof(uint8_t *));
|
||||
for (int i = 0; i < MATRIX_WIDTH; ++i) {
|
||||
noise[i] = (uint8_t *)malloc(MATRIX_HEIGHT * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
ClearFrame();
|
||||
//dma_display->clearScreen();
|
||||
}
|
||||
~Effects(){
|
||||
free(leds);
|
||||
for (int i = 0; i < MATRIX_WIDTH; ++i) {
|
||||
free(noise[i]);
|
||||
}
|
||||
free(noise);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
//dma_display->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) {
|
||||
leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex);
|
||||
//dma_display->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<MATRIX_HEIGHT; ++y){
|
||||
for (int x=0; x<MATRIX_WIDTH; ++x){
|
||||
//Serial.printf("Flushing x, y coord %d, %d\n", x, y);
|
||||
uint16_t _pixel = XY16(x,y);
|
||||
dma_display->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].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, NUM_LEDS * sizeof(CRGB)); // 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, (MATRIX_WIDTH - 1) - offset);
|
||||
uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset);
|
||||
|
||||
uint16_t xy = XY(x, y);
|
||||
|
||||
if (hasprev) {
|
||||
leds[prevxy] += leds[xy];
|
||||
}
|
||||
|
||||
prevxy = xy;
|
||||
hasprev = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
|
||||
for (uint8_t y = 0; y < MATRIX_HEIGHT; 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 = RainbowStripeColors_p;
|
||||
// currentPaletteName = (char *)"RainbowStripe";
|
||||
// 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 == "RainbowStripe")
|
||||
// loadPalette(1);
|
||||
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, MATRIX_WIDTH - 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[XY16(MATRIX_WIDTH - 1 - x, y)] = leds[XY16(x, y)];
|
||||
leds[XY16(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(x, y)];
|
||||
leds[XY16(x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(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[XY16(MATRIX_WIDTH - 1 - x, y)] = leds[XY16(y, x)];
|
||||
leds[XY16(x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(y, x)];
|
||||
leds[XY16(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY16(x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy one diagonal triangle into the other one within a 16x16
|
||||
void Caleidoscope3() {
|
||||
for (int x = 0; x <= MATRIX_CENTRE_X && x < MATRIX_HEIGHT; x++) {
|
||||
for (int y = 0; y <= x && y<MATRIX_HEIGHT; y++) {
|
||||
leds[XY16(x, y)] = leds[XY16(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[XY16(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY16(x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy one diagonal triangle into the other one within a 8x8
|
||||
void Caleidoscope5() {
|
||||
for (int x = 0; x < MATRIX_WIDTH / 4; x++) {
|
||||
for (int y = 0; y <= x && y<=MATRIX_HEIGHT; y++) {
|
||||
leds[XY16(x, y)] = leds[XY16(y, x)];
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = MATRIX_WIDTH / 4; x < MATRIX_WIDTH / 2; x++) {
|
||||
for (int y = MATRIX_HEIGHT / 4; y >= 0; y--) {
|
||||
leds[XY16(x, y)] = leds[XY16(y, x)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Caleidoscope6() {
|
||||
for (int x = 1; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 7)] = leds[XY16(x, 0)];
|
||||
} //a
|
||||
for (int x = 2; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 6)] = leds[XY16(x, 1)];
|
||||
} //b
|
||||
for (int x = 3; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 5)] = leds[XY16(x, 2)];
|
||||
} //c
|
||||
for (int x = 4; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 4)] = leds[XY16(x, 3)];
|
||||
} //d
|
||||
for (int x = 5; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 3)] = leds[XY16(x, 4)];
|
||||
} //e
|
||||
for (int x = 6; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 2)] = leds[XY16(x, 5)];
|
||||
} //f
|
||||
for (int x = 7; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 1)] = leds[XY16(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[XY16(i, y - d)] += leds[XY16(i + 1, y - d)]; // lowest row to the right
|
||||
leds[XY16(i, y - d)].nscale8(dimm);
|
||||
}
|
||||
for (int i = y - d; i <= y + d; i++) {
|
||||
leds[XY16(x + d, i)] += leds[XY16(x + d, i + 1)]; // right column up
|
||||
leds[XY16(x + d, i)].nscale8(dimm);
|
||||
}
|
||||
for (int i = x + d; i >= x - d; i--) {
|
||||
leds[XY16(i, y + d)] += leds[XY16(i - 1, y + d)]; // upper row to the left
|
||||
leds[XY16(i, y + d)].nscale8(dimm);
|
||||
}
|
||||
for (int i = y + d; i >= y - d; i--) {
|
||||
leds[XY16(x - d, i)] += leds[XY16(x - d, i - 1)]; // left column down
|
||||
leds[XY16(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[XY16(a + centerX, b + centerY)] = leds[XY16(nextA + centerX, nextB + centerY)];
|
||||
leds[XY16(b + centerX, a + centerY)] = leds[XY16(nextB + centerX, nextA + centerY)];
|
||||
leds[XY16(-a + centerX, b + centerY)] = leds[XY16(-nextA + centerX, nextB + centerY)];
|
||||
leds[XY16(-b + centerX, a + centerY)] = leds[XY16(-nextB + centerX, nextA + centerY)];
|
||||
leds[XY16(-a + centerX, -b + centerY)] = leds[XY16(-nextA + centerX, -nextB + centerY)];
|
||||
leds[XY16(-b + centerX, -a + centerY)] = leds[XY16(-nextB + centerX, -nextA + centerY)];
|
||||
leds[XY16(a + centerX, -b + centerY)] = leds[XY16(nextA + centerX, -nextB + centerY)];
|
||||
leds[XY16(b + centerX, -a + centerY)] = leds[XY16(nextB + centerX, -nextA + centerY)];
|
||||
|
||||
// dim them
|
||||
leds[XY16(a + centerX, b + centerY)].nscale8(dimm);
|
||||
leds[XY16(b + centerX, a + centerY)].nscale8(dimm);
|
||||
leds[XY16(-a + centerX, b + centerY)].nscale8(dimm);
|
||||
leds[XY16(-b + centerX, a + centerY)].nscale8(dimm);
|
||||
leds[XY16(-a + centerX, -b + centerY)].nscale8(dimm);
|
||||
leds[XY16(-b + centerX, -a + centerY)].nscale8(dimm);
|
||||
leds[XY16(a + centerX, -b + centerY)].nscale8(dimm);
|
||||
leds[XY16(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 = MATRIX_WIDTH, int fromY = 0, int toY = MATRIX_HEIGHT)
|
||||
{
|
||||
for (int x = fromX + 1; x < toX; x++) {
|
||||
for (int y = fromY; y < toY; y++) {
|
||||
leds[XY16(x, y)] += leds[XY16(x - 1, y)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int y = fromY; y < toY; y++)
|
||||
leds[XY16(0, y)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail to the left
|
||||
void StreamLeft(byte scale, int fromX = MATRIX_WIDTH, int toX = 0, int fromY = 0, int toY = MATRIX_HEIGHT)
|
||||
{
|
||||
for (int x = toX; x < fromX; x++) {
|
||||
for (int y = fromY; y < toY; y++) {
|
||||
leds[XY16(x, y)] += leds[XY16(x + 1, y)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int y = fromY; y < toY; y++)
|
||||
leds[XY16(0, y)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail downwards
|
||||
void StreamDown(byte scale)
|
||||
{
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++) {
|
||||
for (int y = 1; y < MATRIX_HEIGHT; y++) {
|
||||
leds[XY16(x, y)] += leds[XY16(x, y - 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++)
|
||||
leds[XY16(x, 0)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail upwards
|
||||
void StreamUp(byte scale)
|
||||
{
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++) {
|
||||
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
|
||||
leds[XY16(x, y)] += leds[XY16(x, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++)
|
||||
leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail up and to the left
|
||||
void StreamUpAndLeft(byte scale)
|
||||
{
|
||||
for (int x = 0; x < MATRIX_WIDTH - 1; x++) {
|
||||
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
|
||||
leds[XY16(x, y)] += leds[XY16(x + 1, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++)
|
||||
leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale);
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++)
|
||||
leds[XY16(MATRIX_WIDTH - 1, y)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail up and to the right
|
||||
void StreamUpAndRight(byte scale)
|
||||
{
|
||||
for (int x = 0; x < MATRIX_WIDTH - 1; x++) {
|
||||
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
|
||||
leds[XY16(x + 1, y)] += leds[XY16(x, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
// fade the bottom row
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++)
|
||||
leds[XY16(x, MATRIX_HEIGHT - 1)].nscale8(scale);
|
||||
|
||||
// fade the right column
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++)
|
||||
leds[XY16(MATRIX_WIDTH - 1, y)].nscale8(scale);
|
||||
}
|
||||
|
||||
// just move everything one line down
|
||||
void MoveDown() {
|
||||
for (int y = MATRIX_HEIGHT - 1; y > 0; y--) {
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++) {
|
||||
leds[XY16(x, y)] = leds[XY16(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 < MATRIX_WIDTH; x++) {
|
||||
leds[XY16(x, y)] = leds[XY16(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[XY16(x + x2 - x0, y + y2 - y0)] = leds[XY16(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[XY16(x, 7 - y)] = leds[XY16(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[XY16(7 - y, x)] = leds[XY16(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[XY16(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 (uint16_t i = 0; i < MATRIX_WIDTH; i++) {
|
||||
uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y);
|
||||
|
||||
for (uint16_t j = 0; j < MATRIX_HEIGHT; 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 < MATRIX_HEIGHT; 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[XY16(0, y)];
|
||||
for (int m = 0; m < delta; m++)
|
||||
{
|
||||
// Do this delta time for each row... computationally expensive potentially.
|
||||
for(int x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
leds[XY16(x, y)] = leds [XY16(x+1, y)];
|
||||
}
|
||||
|
||||
leds[XY16(MATRIX_WIDTH-1, y)] = tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Shift
|
||||
for (int x = 0; x < MATRIX_WIDTH - delta; x++) {
|
||||
leds2[XY(x, y)] = leds[XY(x + delta, y)];
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
for (int x = MATRIX_WIDTH - delta; x < MATRIX_WIDTH; x++) {
|
||||
leds2[XY(x, y)] = leds[XY(x + delta - MATRIX_WIDTH, y)];
|
||||
}
|
||||
*/
|
||||
} // end row loop
|
||||
|
||||
/*
|
||||
// write back to leds
|
||||
for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
|
||||
leds[XY(x, y)] = leds2[XY(x, y)];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void MoveY(byte delta)
|
||||
{
|
||||
|
||||
CRGB tmp = 0;
|
||||
for (int x = 0; x < MATRIX_WIDTH; x++)
|
||||
{
|
||||
tmp = leds[XY16(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 < MATRIX_HEIGHT; y++)
|
||||
{
|
||||
leds[XY16(x, y)] = leds [XY16(x, y+1)];
|
||||
}
|
||||
|
||||
leds[XY16(x, MATRIX_HEIGHT-1)] = tmp;
|
||||
}
|
||||
} // end column loop
|
||||
} /// MoveY
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
class PatternAttract : public Drawable {
|
||||
private:
|
||||
const int count = AVAILABLE_BOID_COUNT-1;
|
||||
const int count = 8;
|
||||
Attractor attractor;
|
||||
|
||||
public:
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
direction = -1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Boid boid = Boid(VPANEL_W/2, VPANEL_H - 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;
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
boid.applyForce(force);
|
||||
|
||||
boid.update();
|
||||
effects.setPixel(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
|
||||
|
||||
boids[i] = boid;
|
||||
}
|
73
examples/AuroraDemo/PatternBounce.h
Normal file
|
@ -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 PatternBounce_H
|
||||
|
||||
class PatternBounce : public Drawable {
|
||||
private:
|
||||
static const int count = 32;
|
||||
PVector gravity = PVector(0, 0.0125);
|
||||
|
||||
public:
|
||||
PatternBounce() {
|
||||
name = (char *)"Bounce";
|
||||
}
|
||||
|
||||
void start() {
|
||||
unsigned int colorWidth = 256 / count;
|
||||
for (int i = 0; i < count; i++) {
|
||||
Boid boid = Boid(i, 0);
|
||||
boid.velocity.x = 0;
|
||||
boid.velocity.y = i * -0.01;
|
||||
boid.colorIndex = colorWidth * i;
|
||||
boid.maxforce = 10;
|
||||
boid.maxspeed = 10;
|
||||
boids[i] = boid;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
// dim all pixels on the display
|
||||
effects.DimAll(170); effects.ShowFrame();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Boid boid = boids[i];
|
||||
|
||||
boid.applyForce(gravity);
|
||||
|
||||
boid.update();
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
|
||||
|
||||
if (boid.location.y >= MATRIX_HEIGHT - 1) {
|
||||
boid.location.y = MATRIX_HEIGHT - 1;
|
||||
boid.velocity.y *= -1.0;
|
||||
}
|
||||
|
||||
boids[i] = boid;
|
||||
}
|
||||
|
||||
return 15;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
219
examples/AuroraDemo/PatternCube.h
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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 PatternCube_H
|
||||
#define PatternCube_H
|
||||
|
||||
class PatternCube : public Drawable {
|
||||
private:
|
||||
float focal = 30; // Focal of the camera
|
||||
int cubeWidth = 28; // Cube size
|
||||
float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis
|
||||
float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis
|
||||
float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center
|
||||
int zCamera = 110; // distance from cube to the eye of the camera
|
||||
|
||||
// Local vertices
|
||||
Vertex local[8];
|
||||
// Camera aligned vertices
|
||||
Vertex aligned[8];
|
||||
// On-screen projected vertices
|
||||
Point screen[8];
|
||||
// Faces
|
||||
squareFace face[6];
|
||||
// Edges
|
||||
EdgePoint edge[12];
|
||||
int nbEdges;
|
||||
// ModelView matrix
|
||||
float m00, m01, m02, m10, m11, m12, m20, m21, m22;
|
||||
|
||||
// constructs the cube
|
||||
void make(int w)
|
||||
{
|
||||
nbEdges = 0;
|
||||
|
||||
local[0].set(-w, w, w);
|
||||
local[1].set(w, w, w);
|
||||
local[2].set(w, -w, w);
|
||||
local[3].set(-w, -w, w);
|
||||
local[4].set(-w, w, -w);
|
||||
local[5].set(w, w, -w);
|
||||
local[6].set(w, -w, -w);
|
||||
local[7].set(-w, -w, -w);
|
||||
|
||||
face[0].set(1, 0, 3, 2);
|
||||
face[1].set(0, 4, 7, 3);
|
||||
face[2].set(4, 0, 1, 5);
|
||||
face[3].set(4, 5, 6, 7);
|
||||
face[4].set(1, 2, 6, 5);
|
||||
face[5].set(2, 3, 7, 6);
|
||||
|
||||
int f, i;
|
||||
for (f = 0; f < 6; f++)
|
||||
{
|
||||
for (i = 0; i < face[f].length; i++)
|
||||
{
|
||||
face[f].ed[i] = this->findEdge(face[f].sommets[i], face[f].sommets[i ? i - 1 : face[f].length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finds edges from faces
|
||||
int findEdge(int a, int b)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nbEdges; i++)
|
||||
if ((edge[i].x == a && edge[i].y == b) || (edge[i].x == b && edge[i].y == a))
|
||||
return i;
|
||||
edge[nbEdges++].set(a, b);
|
||||
return i;
|
||||
}
|
||||
|
||||
// rotates according to angle x&y
|
||||
void rotate(float angx, float angy)
|
||||
{
|
||||
int i;
|
||||
float cx = cos(angx);
|
||||
float sx = sin(angx);
|
||||
float cy = cos(angy);
|
||||
float sy = sin(angy);
|
||||
|
||||
m00 = cy;
|
||||
m01 = 0;
|
||||
m02 = -sy;
|
||||
m10 = sx * sy;
|
||||
m11 = cx;
|
||||
m12 = sx * cy;
|
||||
m20 = cx * sy;
|
||||
m21 = -sx;
|
||||
m22 = cx * cy;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
aligned[i].x = m00 * local[i].x + m01 * local[i].y + m02 * local[i].z;
|
||||
aligned[i].y = m10 * local[i].x + m11 * local[i].y + m12 * local[i].z;
|
||||
aligned[i].z = m20 * local[i].x + m21 * local[i].y + m22 * local[i].z + zCamera;
|
||||
|
||||
screen[i].x = floor((Ox + focal * aligned[i].x / aligned[i].z));
|
||||
screen[i].y = floor((Oy - focal * aligned[i].y / aligned[i].z));
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
edge[i].visible = false;
|
||||
|
||||
Point *pa, *pb, *pc;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
pa = screen + face[i].sommets[0];
|
||||
pb = screen + face[i].sommets[1];
|
||||
pc = screen + face[i].sommets[2];
|
||||
|
||||
boolean back = ((pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x)) < 0;
|
||||
if (!back)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
edge[face[i].ed[j]].visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte hue = 0;
|
||||
int step = 0;
|
||||
|
||||
public:
|
||||
PatternCube() {
|
||||
name = (char *)"Cube";
|
||||
make(cubeWidth);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
uint8_t blurAmount = beatsin8(2, 10, 255);
|
||||
|
||||
#if FASTLED_VERSION >= 3001000
|
||||
blur2d(effects.leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount);
|
||||
#else
|
||||
effects.DimAll(blurAmount); effects.ShowFrame();
|
||||
#endif
|
||||
|
||||
zCamera = beatsin8(2, 100, 140);
|
||||
AngxSpeed = beatsin8(3, 1, 10) / 100.0f;
|
||||
AngySpeed = beatcos8(5, 1, 10) / 100.0f;
|
||||
|
||||
// Update values
|
||||
Angx += AngxSpeed;
|
||||
Angy += AngySpeed;
|
||||
if (Angx >= TWO_PI)
|
||||
Angx -= TWO_PI;
|
||||
if (Angy >= TWO_PI)
|
||||
Angy -= TWO_PI;
|
||||
|
||||
rotate(Angx, Angy);
|
||||
|
||||
// Draw cube
|
||||
int i;
|
||||
|
||||
CRGB color = effects.ColorFromCurrentPalette(hue, 128);
|
||||
|
||||
// Backface
|
||||
EdgePoint *e;
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
e = edge + i;
|
||||
if (!e->visible) {
|
||||
dma_display->drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
}
|
||||
}
|
||||
|
||||
color = effects.ColorFromCurrentPalette(hue, 255);
|
||||
|
||||
// Frontface
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
e = edge + i;
|
||||
if (e->visible)
|
||||
{
|
||||
dma_display->drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
}
|
||||
}
|
||||
|
||||
step++;
|
||||
if (step == 8) {
|
||||
step = 0;
|
||||
hue++;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 20;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
116
examples/AuroraDemo/PatternElectricMandala.h
Normal file
|
@ -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(15) {
|
||||
//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 30;
|
||||
}
|
||||
|
||||
// show just one layer
|
||||
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
|
||||
for (uint16_t i = 0; i < MATRIX_WIDTH; i++) {
|
||||
for (uint16_t j = 0; j < MATRIX_HEIGHT; 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[XY16(i, j)] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
118
examples/AuroraDemo/PatternFire.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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 < MATRIX_WIDTH; x++) {
|
||||
// Step 1. Cool down every cell a little
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
int xy = XY(x, y);
|
||||
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2));
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (int y = 0; y < MATRIX_HEIGHT; 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, MATRIX_HEIGHT - 1);
|
||||
heat[xy] = qadd8(heat[xy], random8(160, 255));
|
||||
}
|
||||
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (int y = 0; y < MATRIX_HEIGHT; 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
|
|
@ -1,235 +0,0 @@
|
|||
#ifndef FireWork_H
|
||||
#define FireWork_H
|
||||
|
||||
/****************************************************************
|
||||
* Fireworks Class
|
||||
****************************************************************/
|
||||
// Ripped from: https://github.com/lmirel/MorphingClockRemix
|
||||
|
||||
const int FIREWORKS = 4; // Number of fireworks
|
||||
const int FIREWORK_PARTICLES = 32; // Number of particles per firework
|
||||
|
||||
const float GRAVITY = 0.03f;
|
||||
const float baselineSpeed = -1.2f;
|
||||
const float maxSpeed = -2.0f;
|
||||
|
||||
class Firework
|
||||
{
|
||||
public:
|
||||
float x[FIREWORK_PARTICLES];
|
||||
float y[FIREWORK_PARTICLES];
|
||||
char lx[FIREWORK_PARTICLES], ly[FIREWORK_PARTICLES];
|
||||
float xSpeed[FIREWORK_PARTICLES];
|
||||
float ySpeed[FIREWORK_PARTICLES];
|
||||
|
||||
char red;
|
||||
char blue;
|
||||
char green;
|
||||
char alpha;
|
||||
|
||||
int framesUntilLaunch;
|
||||
|
||||
char particleSize;
|
||||
bool hasExploded;
|
||||
|
||||
Firework(); // Constructor declaration
|
||||
void initialise();
|
||||
void move();
|
||||
void explode();
|
||||
};
|
||||
|
||||
// Constructor implementation
|
||||
Firework::Firework()
|
||||
{
|
||||
initialise();
|
||||
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
|
||||
{
|
||||
lx[loop] = 0;
|
||||
ly[loop] = VPANEL_H + 1; // Push the particle location down off the bottom of the screen
|
||||
}
|
||||
}
|
||||
|
||||
void Firework::initialise()
|
||||
{
|
||||
// Pick an initial x location and random x/y speeds
|
||||
float xLoc = (rand() % VPANEL_W);
|
||||
float xSpeedVal = baselineSpeed + (rand() % (int)maxSpeed);
|
||||
float ySpeedVal = baselineSpeed + (rand() % (int)maxSpeed);
|
||||
|
||||
// Set initial x/y location and speeds
|
||||
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
|
||||
{
|
||||
x[loop] = xLoc;
|
||||
y[loop] = VPANEL_H + 1; // Push the particle location down off the bottom of the screen
|
||||
xSpeed[loop] = xSpeedVal;
|
||||
ySpeed[loop] = ySpeedVal;
|
||||
//don't reset these otherwise particles won't be removed
|
||||
//lx[loop] = 0;
|
||||
//ly[loop] = LAYER_HEIGHT + 1; // Push the particle location down off the bottom of the screen
|
||||
}
|
||||
|
||||
// Assign a random colour and full alpha (i.e. particle is completely opaque)
|
||||
red = (rand() % 255);/// (float)RAND_MAX);
|
||||
green = (rand() % 255); /// (float)RAND_MAX);
|
||||
blue = (rand() % 255); /// (float)RAND_MAX);
|
||||
alpha = 50;//max particle frames
|
||||
|
||||
// Firework will launch after a random amount of frames between 0 and 400
|
||||
framesUntilLaunch = ((int)rand() % (VPANEL_H));
|
||||
|
||||
// Size of the particle (as thrown to glPointSize) - range is 1.0f to 4.0f
|
||||
particleSize = 1.0f + ((float)rand() / (float)RAND_MAX) * 3.0f;
|
||||
|
||||
// Flag to keep trackof whether the firework has exploded or not
|
||||
hasExploded = false;
|
||||
|
||||
//cout << "Initialised a firework." << endl;
|
||||
}
|
||||
|
||||
void Firework::move()
|
||||
{
|
||||
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
|
||||
{
|
||||
// Once the firework is ready to launch start moving the particles
|
||||
if (framesUntilLaunch <= 0)
|
||||
{
|
||||
//draw black on last known position
|
||||
//tl->drawPixel (x[loop], y[loop], cc_blk);
|
||||
lx[loop] = x[loop];
|
||||
ly[loop] = y[loop];
|
||||
//
|
||||
x[loop] += xSpeed[loop];
|
||||
|
||||
y[loop] += ySpeed[loop];
|
||||
|
||||
ySpeed[loop] += GRAVITY;
|
||||
}
|
||||
}
|
||||
framesUntilLaunch--;
|
||||
|
||||
// Once a fireworks speed turns positive (i.e. at top of arc) - blow it up!
|
||||
if (ySpeed[0] > 0.0f)
|
||||
{
|
||||
for (int loop2 = 0; loop2 < FIREWORK_PARTICLES; loop2++)
|
||||
{
|
||||
// Set a random x and y speed beteen -4 and + 4
|
||||
xSpeed[loop2] = -2 + (rand() / (float)RAND_MAX) * 4;
|
||||
ySpeed[loop2] = -2 + (rand() / (float)RAND_MAX) * 4;
|
||||
}
|
||||
|
||||
//cout << "Boom!" << endl;
|
||||
hasExploded = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Firework::explode()
|
||||
{
|
||||
for (int loop = 0; loop < FIREWORK_PARTICLES; loop++)
|
||||
{
|
||||
// Dampen the horizontal speed by 1% per frame
|
||||
xSpeed[loop] *= 0.99;
|
||||
|
||||
//draw black on last known position (NO LONGER USED tl->dim used instead)
|
||||
//tl->drawPixel (x[loop], y[loop], cc_blk);
|
||||
lx[loop] = x[loop];
|
||||
ly[loop] = y[loop];
|
||||
//
|
||||
// Move the particle
|
||||
x[loop] += xSpeed[loop];
|
||||
y[loop] += ySpeed[loop];
|
||||
|
||||
// Apply gravity to the particle's speed
|
||||
ySpeed[loop] += GRAVITY;
|
||||
}
|
||||
|
||||
// Fade out the particles (alpha is stored per firework, not per particle)
|
||||
if (alpha > 0)
|
||||
{
|
||||
alpha -= 1;
|
||||
}
|
||||
else // Once the alpha hits zero reset the firework
|
||||
{
|
||||
initialise();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************** */
|
||||
|
||||
|
||||
|
||||
class PatternFirework : public Drawable {
|
||||
|
||||
public:
|
||||
PatternFirework() {
|
||||
name = (char *)"PatternFirework";
|
||||
|
||||
}
|
||||
|
||||
void start();
|
||||
unsigned int drawFrame();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
// Create our array of fireworks
|
||||
Firework fw[FIREWORKS];
|
||||
|
||||
};
|
||||
|
||||
|
||||
void PatternFirework::start() { }
|
||||
|
||||
void PatternFirework::stop() { }
|
||||
|
||||
unsigned int PatternFirework::drawFrame()
|
||||
{
|
||||
|
||||
effects.DimAll(250);
|
||||
|
||||
CRGB cc_frw;
|
||||
//display.fillScreen (0);
|
||||
// Draw fireworks
|
||||
//cout << "Firework count is: " << Firework::fireworkCount << endl;
|
||||
for (int loop = 0; loop < FIREWORKS; loop++)
|
||||
{
|
||||
for (int particleLoop = 0; particleLoop < FIREWORK_PARTICLES; particleLoop++)
|
||||
{
|
||||
|
||||
// Set colour to yellow on way up, then whatever colour firework should be when exploded
|
||||
if (fw[loop].hasExploded == false)
|
||||
{
|
||||
//glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
cc_frw = CRGB (255, 255, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//glColor4f(fw[loop].red, fw[loop].green, fw[loop].blue, fw[loop].alpha);
|
||||
//glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
|
||||
cc_frw = CRGB (fw[loop].red, fw[loop].green, fw[loop].blue);
|
||||
}
|
||||
|
||||
// Draw the point
|
||||
//glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
|
||||
effects.setPixel (fw[loop].x[particleLoop], fw[loop].y[particleLoop], cc_frw);
|
||||
// effects.setPixel (fw[loop].lx[particleLoop], fw[loop].ly[particleLoop], 0);
|
||||
}
|
||||
// Move the firework appropriately depending on its explosion state
|
||||
if (fw[loop].hasExploded == false)
|
||||
{
|
||||
fw[loop].move();
|
||||
}
|
||||
else
|
||||
{
|
||||
fw[loop].explode();
|
||||
}
|
||||
//
|
||||
//delay (10);
|
||||
} // end loop
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 20;
|
||||
|
||||
} // end drawframe
|
||||
|
||||
|
||||
#endif
|
|
@ -36,17 +36,12 @@
|
|||
#define PatternFlock_H
|
||||
|
||||
class PatternFlock : public Drawable {
|
||||
|
||||
private:
|
||||
unsigned long last_update_hue_ms = 0;
|
||||
unsigned long last_update_predator_ms = 0;
|
||||
|
||||
public:
|
||||
PatternFlock() {
|
||||
name = (char *)"Flock";
|
||||
}
|
||||
|
||||
static const int boidCount = VPANEL_W-1;
|
||||
static const int boidCount = 10;
|
||||
Boid predator;
|
||||
|
||||
PVector wind;
|
||||
|
@ -95,8 +90,8 @@ class PatternFlock : public Drawable {
|
|||
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[XY16(location.x, location.y)] += color;
|
||||
effects.setPixel(location.x, location.y, color);
|
||||
// effects.leds[XY(location.x, location.y)] += color;
|
||||
effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color);
|
||||
|
||||
if (applyWind) {
|
||||
boid->applyForce(wind);
|
||||
|
@ -111,17 +106,15 @@ class PatternFlock : public Drawable {
|
|||
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[XY16(location.x, location.y)] += color;
|
||||
effects.setPixel(location.x, location.y, color);
|
||||
// effects.leds[XY(location.x, location.y)] += color;
|
||||
effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color);
|
||||
}
|
||||
|
||||
if (millis() - last_update_hue_ms > 200) {
|
||||
last_update_hue_ms = millis();
|
||||
EVERY_N_MILLIS(200) {
|
||||
hue++;
|
||||
}
|
||||
|
||||
if (millis() - last_update_predator_ms > 30000) {
|
||||
last_update_predator_ms = millis();
|
||||
EVERY_N_SECONDS(30) {
|
||||
predatorPresent = !predatorPresent;
|
||||
}
|
||||
|
92
examples/AuroraDemo/PatternFlowField.h
Normal file
|
@ -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(MATRIX_WIDTH), 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 >= MATRIX_WIDTH ||
|
||||
boid->location.y < 0 || boid->location.y >= MATRIX_HEIGHT) {
|
||||
boid->location.x = random(MATRIX_WIDTH);
|
||||
boid->location.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
EVERY_N_MILLIS(200) {
|
||||
hue++;
|
||||
}
|
||||
|
||||
x += speed;
|
||||
y += speed;
|
||||
z += speed;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 50;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
// Codetastic 2024
|
||||
// ChatGPT was used to create this.
|
||||
// It sucks.
|
||||
|
||||
#ifndef PatternTheMatrix_H
|
||||
#define PatternTheMatrix_H
|
||||
|
||||
// Function to generate a random greenish color for the digital rain
|
||||
CRGB generateRainColor() {
|
||||
return CHSV(96 + random(64), 255, 255); // Greenish colors
|
||||
}
|
||||
|
||||
|
||||
class PatternTheMatrix : public Drawable {
|
||||
|
||||
public:
|
||||
PatternTheMatrix() {
|
||||
name = (char *)"The Matrix";
|
||||
}
|
||||
|
||||
|
||||
// Function to draw the digital rain effect
|
||||
void drawDigitalRain() {
|
||||
// Shift all the LEDs down by one row
|
||||
for (int x = 0; x < VPANEL_W ; x++) {
|
||||
for (int y = VPANEL_H - 1; y > 0; y--) {
|
||||
effects.leds[XY(x, y)] = effects.leds[XY(x, y - 1)];
|
||||
}
|
||||
// Add a new drop at the top of the column randomly
|
||||
if (random(10) > 7) { // Adjust the probability to control density of rain
|
||||
effects.leds[XY(x, 0)] = generateRainColor();
|
||||
} else {
|
||||
effects.leds[XY(x, 0)] = CRGB::Black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void start()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
unsigned int drawFrame() {
|
||||
|
||||
effects.DimAll(250);
|
||||
|
||||
drawDigitalRain();
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
51
examples/AuroraDemo/PatternIncrementalDrift.h
Normal file
|
@ -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 <= MATRIX_WIDTH / 2; i++)
|
||||
{
|
||||
CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (MATRIX_WIDTH / 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
|
63
examples/AuroraDemo/PatternIncrementalDrift2.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
*
|
||||
* 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 PatternIncrementalDrift2_H
|
||||
#define PatternIncrementalDrift2_H
|
||||
|
||||
class PatternIncrementalDrift2 : public Drawable {
|
||||
public:
|
||||
PatternIncrementalDrift2() {
|
||||
name = (char *)"Incremental Drift Rose";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
uint8_t dim = beatsin8(2, 170, 250);
|
||||
effects.DimAll(dim); effects.ShowFrame();
|
||||
|
||||
for (uint8_t i = 0; i < 32; i++)
|
||||
{
|
||||
CRGB color;
|
||||
|
||||
uint8_t x = 0;
|
||||
uint8_t y = 0;
|
||||
|
||||
if (i < 16) {
|
||||
x = beatcos8((i + 1) * 2, i, MATRIX_WIDTH - i);
|
||||
y = beatsin8((i + 1) * 2, i, MATRIX_HEIGHT - i);
|
||||
color = effects.ColorFromCurrentPalette(i * 14);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = beatsin8((32 - i) * 2, MATRIX_WIDTH - i, i + 1);
|
||||
y = beatcos8((32 - i) * 2, MATRIX_HEIGHT - i, i + 1);
|
||||
color = effects.ColorFromCurrentPalette((31 - i) * 14);
|
||||
}
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -28,35 +28,30 @@ public:
|
|||
name = (char *)"Infinity";
|
||||
}
|
||||
|
||||
void start() {
|
||||
effects.ClearFrame();
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
// dim all pixels on the display slightly
|
||||
// to 250/255 (98%) of their current brightness
|
||||
//blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250);
|
||||
blur2d(effects.leds, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, 250);
|
||||
// effects.DimAll(250); effects.ShowFrame();
|
||||
|
||||
|
||||
// the EffectsLayer class has some sample oscillators
|
||||
// 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 - 4) - effects.p[1];
|
||||
int x = (MATRIX_WIDTH - 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, VPANEL_H - 8);
|
||||
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.drawTriangle(x,y,x+1,y+1,x+2,y+2,effects.ColorFromCurrentPalette(hue));
|
||||
////effects.setPixelFromPaletteIndex(x, y, hue);
|
||||
effects.Pixel(x, y, hue);
|
||||
|
||||
effects.ShowFrame();
|
||||
return 30;
|
154
examples/AuroraDemo/PatternInvaders.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Aurora: https://github.com/pixelmatix/aurora
|
||||
* Copyright (c) 2014 Jason Coon
|
||||
*
|
||||
* Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator
|
||||
*
|
||||
* 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 PatternInvaders_H
|
||||
#define PatternInvaders_H
|
||||
|
||||
class PatternInvadersSmall : public Drawable {
|
||||
private:
|
||||
uint8_t x = 1;
|
||||
uint8_t y = 1;
|
||||
|
||||
public:
|
||||
PatternInvadersSmall() {
|
||||
name = (char *)"Invaders Small";
|
||||
}
|
||||
|
||||
void start() {
|
||||
dma_display->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) color = color1;
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color);
|
||||
|
||||
if (i < 2)
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color);
|
||||
}
|
||||
}
|
||||
|
||||
x += 6;
|
||||
if (x > 25) {
|
||||
x = 1;
|
||||
y += 6;
|
||||
}
|
||||
|
||||
if (y > 25) y = x = 1;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 125;
|
||||
}
|
||||
};
|
||||
|
||||
class PatternInvadersMedium : public Drawable {
|
||||
private:
|
||||
uint8_t x = 0;
|
||||
uint8_t y = 0;
|
||||
|
||||
public:
|
||||
PatternInvadersMedium() {
|
||||
name = (char *)"Invaders Medium";
|
||||
}
|
||||
|
||||
void start() {
|
||||
dma_display->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) color = color1;
|
||||
|
||||
dma_display->fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
|
||||
|
||||
if (i < 2)
|
||||
dma_display->fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
|
||||
}
|
||||
}
|
||||
|
||||
x += 11;
|
||||
if (x > 22) {
|
||||
x = 0;
|
||||
y += 11;
|
||||
}
|
||||
|
||||
if (y > 22) y = x = 0;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 500;
|
||||
}
|
||||
};
|
||||
|
||||
class PatternInvadersLarge : public Drawable {
|
||||
private:
|
||||
|
||||
public:
|
||||
PatternInvadersLarge() {
|
||||
name = (char *)"Invaders Large";
|
||||
}
|
||||
|
||||
void start() {
|
||||
dma_display->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
dma_display->fillScreen(0);
|
||||
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int x = 0; x < 3; x++) {
|
||||
for (int y = 0; y < 5; y++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) {
|
||||
color = color1;
|
||||
}
|
||||
|
||||
dma_display->fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
|
||||
|
||||
if (x < 2)
|
||||
dma_display->fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
|
||||
}
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 2000;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,129 +0,0 @@
|
|||
#ifndef JuliaSet_H
|
||||
#define JuliaSet_H
|
||||
|
||||
// Codetastic 2024
|
||||
|
||||
#define USE_FLOATHACK // To boost float performance, comment if this doesn't work.
|
||||
|
||||
// inspired by
|
||||
// https://en.wikipedia.org/wiki/Fast_inverse_square_root
|
||||
#ifdef USE_FLOATHACK
|
||||
// cast float as int32_t
|
||||
int32_t intfloat(float n){ return *(int32_t *)&n; }
|
||||
// cast int32_t as float
|
||||
float floatint(int32_t n){ return *(float *)&n; }
|
||||
// fast approx sqrt(x)
|
||||
float floatsqrt(float n){ return floatint(0x1fbb4000+(intfloat(n)>>1)); }
|
||||
// fast approx 1/x
|
||||
float floatinv(float n){ return floatint(0x7f000000-intfloat(n)); }
|
||||
// fast approx log2(x)
|
||||
float floatlog2(float n){ return (float)((intfloat(n)<<1)-0x7f000000)*5.9604645e-08f; }
|
||||
#else
|
||||
float floatinv(float n){ return 1.f/n;}
|
||||
float floatsqrt(float n){ return std::sqrt(n); }
|
||||
float floatlog2(float n){ return std::log2f(n); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////
|
||||
// Escape time mandelbrot set function,
|
||||
// with arbitrary start point zx, zy
|
||||
// and arbitrary seed point ax, ay
|
||||
//
|
||||
// For julia set
|
||||
// zx = pos_x, zy = pos_y;
|
||||
// ax = seed_x, ay = seed_y;
|
||||
//
|
||||
// For mandelbrot set
|
||||
// zx = 0, zy = 0;
|
||||
// ax = pos_x, ay = pos_y;
|
||||
//
|
||||
const float bailOut = 4; // Escape radius
|
||||
const int32_t itmult = 1<<10; // Color speed
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/Mandelbrot_set
|
||||
int32_t iteratefloat(float ax, float ay, float zx, float zy, uint16_t mxIT) {
|
||||
float zzl = 0;
|
||||
for (int it = 0; it<mxIT; it++) {
|
||||
float zzx = zx * zx;
|
||||
float zzy = zy * zy;
|
||||
// is the point is escaped?
|
||||
if(zzx+zzy>=bailOut){
|
||||
if(it>0){
|
||||
// calculate smooth coloring
|
||||
float zza = floatlog2(zzl);
|
||||
float zzb = floatlog2(zzx+zzy);
|
||||
float zzc = floatlog2(bailOut);
|
||||
float zzd = (zzc-zza)*floatinv(zzb-zza);
|
||||
return it*itmult+zzd*itmult;
|
||||
}
|
||||
};
|
||||
// z -> z*z + c
|
||||
zy = 2.f*zx*zy+ay;
|
||||
zx = zzx-zzy+ax;
|
||||
zzl = zzx+zzy;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class PatternJuliaSet : public Drawable {
|
||||
|
||||
private:
|
||||
|
||||
float sint[256]; // precalculated sin table, for performance reasons
|
||||
|
||||
public:
|
||||
PatternJuliaSet() {
|
||||
name = (char *)"Julia Set";
|
||||
}
|
||||
|
||||
void start() {
|
||||
|
||||
for(int i=0;i<256;i++){
|
||||
sint[i] = sinf(i/256.f*2.f*PI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Palette color taken from:
|
||||
// https://editor.p5js.org/Kouzerumatsukite/sketches/DwTiq9D01
|
||||
// color palette originally made by piano_miles, written in p5js
|
||||
// hsv2rgb(IT, cos(4096*it)/2+0.5, 1-sin(2048*it)/2-0.5)
|
||||
void drawPixelPalette(int x, int y, uint32_t m){
|
||||
float r = 0.f, g = 0.f, b = 0.f;
|
||||
if(m){
|
||||
char n = m>> 4 ;
|
||||
float l =abs(sint[m>> 2&255] )*255.f ;
|
||||
float s = (sint[m &255]+ 1.f)*0.5f ;
|
||||
r = (max(min(sint[n &255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
g = (max(min(sint[n+ 85&255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
b = (max(min(sint[n+170&255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
}
|
||||
effects.setPixel(x,y,CRGB(r,g,b));
|
||||
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
uint32_t lastMicros = micros();
|
||||
double t = (double)lastMicros/8000000;
|
||||
double k = sin(t*3.212/2)*sin(t*3.212/2)/16+1;
|
||||
float cosk = (k-cos(t))/2;
|
||||
float xoff = (cos(t)*cosk+k/2-0.25);
|
||||
float yoff = (sin(t)*cosk );
|
||||
for(uint8_t y=0;y<VPANEL_H;y++){
|
||||
for(uint8_t x=0;x<VPANEL_W;x++){
|
||||
uint32_t itcount = iteratefloat(xoff,yoff,((x-64)+1)/64.f,(y)/64.f,64);
|
||||
uint32_t itcolor = itcount?floatsqrt(itcount)*4+t*1024:0;
|
||||
drawPixelPalette(x,y,itcolor);
|
||||
}
|
||||
}
|
||||
|
||||
blur2d(effects.leds, VPANEL_W, VPANEL_H, 64);
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
129
examples/AuroraDemo/PatternLife.h
Normal file
|
@ -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[MATRIX_WIDTH][MATRIX_HEIGHT];
|
||||
unsigned int density = 50;
|
||||
int generation = 0;
|
||||
|
||||
void randomFillWorld() {
|
||||
for (int i = 0; i < MATRIX_WIDTH; i++) {
|
||||
for (int j = 0; j < MATRIX_HEIGHT; 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) % MATRIX_WIDTH][y].prev) +
|
||||
(world[x][(y + 1) % MATRIX_HEIGHT].prev) +
|
||||
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][y].prev) +
|
||||
(world[x][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) +
|
||||
(world[(x + 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) +
|
||||
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) +
|
||||
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) +
|
||||
(world[(x + 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev);
|
||||
}
|
||||
|
||||
public:
|
||||
PatternLife() {
|
||||
name = (char *)"Life";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
if (generation == 0) {
|
||||
effects.ClearFrame();
|
||||
|
||||
randomFillWorld();
|
||||
}
|
||||
|
||||
// Display current generation
|
||||
for (int i = 0; i < MATRIX_WIDTH; i++) {
|
||||
for (int j = 0; j < MATRIX_HEIGHT; 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 < MATRIX_WIDTH; x++) {
|
||||
for (int y = 0; y < MATRIX_HEIGHT; 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 < MATRIX_WIDTH; x++) {
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
world[x][y].prev = world[x][y].alive;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
generation++;
|
||||
if (generation >= 256)
|
||||
generation = 0;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 60;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
264
examples/AuroraDemo/PatternMaze.h
Normal file
|
@ -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 = MATRIX_WIDTH / 2;
|
||||
static const int height = MATRIX_HEIGHT / 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 0;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void start() {
|
||||
effects.ClearFrame();
|
||||
cellCount = 0;
|
||||
hue = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
73
examples/AuroraDemo/PatternMunch.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 (uint16_t x = 0; x < MATRIX_WIDTH; x++) {
|
||||
for (uint16_t y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
effects.leds[XY16(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 >= MATRIX_WIDTH) {
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
if (flip == 0)
|
||||
flip = MATRIX_WIDTH-1;
|
||||
else
|
||||
flip = 0;
|
||||
}
|
||||
|
||||
generation++;
|
||||
|
||||
// show it ffs!
|
||||
effects.ShowFrame();
|
||||
return 60;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
338
examples/AuroraDemo/PatternNoiseSmearing.h
Normal file
|
@ -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 < MATRIX_WIDTH; x++) {
|
||||
effects.leds[XY(x, y)] += rainbow[c];
|
||||
}
|
||||
|
||||
y++;
|
||||
if (y >= MATRIX_HEIGHT)
|
||||
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
|
66
examples/AuroraDemo/PatternPendulumWave.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
*
|
||||
* 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
|
||||
|
||||
#define WAVE_BPM 25
|
||||
#define AMP_BPM 2
|
||||
#define SKEW_BPM 4
|
||||
#define WAVE_TIMEMINSKEW MATRIX_WIDTH/8
|
||||
#define WAVE_TIMEMAXSKEW MATRIX_WIDTH/2
|
||||
|
||||
class PatternPendulumWave : public Drawable {
|
||||
public:
|
||||
PatternPendulumWave() {
|
||||
name = (char *)"Pendulum Wave";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
effects.ClearFrame();
|
||||
|
||||
for (int x = 0; x < MATRIX_WIDTH; ++x)
|
||||
{
|
||||
uint16_t amp = beatsin16(AMP_BPM, MATRIX_HEIGHT/8, MATRIX_HEIGHT-1);
|
||||
uint16_t offset = (MATRIX_HEIGHT - beatsin16(AMP_BPM, 0, MATRIX_HEIGHT))/2;
|
||||
|
||||
uint8_t y = beatsin16(WAVE_BPM, 0, amp, x*beatsin16(SKEW_BPM, WAVE_TIMEMINSKEW, WAVE_TIMEMAXSKEW)) + offset;
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7));
|
||||
}
|
||||
effects.ShowFrame();
|
||||
return 20;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
66
examples/AuroraDemo/PatternPlasma.h
Normal file
|
@ -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 < MATRIX_WIDTH; x++) {
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
int16_t v = 0;
|
||||
uint8_t wibble = sin8(time);
|
||||
v += sin16(x * wibble * 2 + time);
|
||||
v += cos16(y * (128 - wibble) * 2 + time);
|
||||
v += sin16(y * x * cos8(-time) / 2);
|
||||
|
||||
effects.Pixel(x, y, (v >> 8) + 127);
|
||||
}
|
||||
}
|
||||
|
||||
time += 1;
|
||||
cycles++;
|
||||
|
||||
if (cycles >= 2048) {
|
||||
time = 0;
|
||||
cycles = 0;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 30;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
82
examples/AuroraDemo/PatternPulse.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Aurora: https://github.com/pixelmatix/aurora
|
||||
* Copyright (c) 2014 Jason Coon
|
||||
*
|
||||
* Based at least in part on someone else's work that I can no longer find.
|
||||
* Please let me know if you recognize any of this code!
|
||||
*
|
||||
* 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 PatternPulse_H
|
||||
#define PatternPulse_H
|
||||
|
||||
class PatternPulse : public Drawable {
|
||||
private:
|
||||
int hue;
|
||||
int centerX = 0;
|
||||
int centerY = 0;
|
||||
int step = -1;
|
||||
int maxSteps = 16;
|
||||
float fadeRate = 0.8;
|
||||
int diff;
|
||||
|
||||
public:
|
||||
PatternPulse() {
|
||||
name = (char *)"Pulse";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
effects.DimAll(235);
|
||||
|
||||
if (step == -1) {
|
||||
centerX = random(32);
|
||||
centerY = random(32);
|
||||
hue = random(256); // 170;
|
||||
step = 0;
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
dma_display->drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue));
|
||||
step++;
|
||||
}
|
||||
else {
|
||||
if (step < maxSteps) {
|
||||
// initial pulse
|
||||
dma_display->drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
|
||||
|
||||
// secondary pulse
|
||||
if (step > 3) {
|
||||
dma_display->drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
|
||||
}
|
||||
step++;
|
||||
}
|
||||
else {
|
||||
step = -1;
|
||||
}
|
||||
}
|
||||
|
||||
effects.standardNoiseSmearing();
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 30;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -26,7 +26,6 @@ class PatternRadar : public Drawable {
|
|||
private:
|
||||
byte theta = 0;
|
||||
byte hueoffset = 0;
|
||||
unsigned long last_update_hue_ms = 0;
|
||||
|
||||
public:
|
||||
PatternRadar() {
|
||||
|
@ -36,16 +35,15 @@ class PatternRadar : public Drawable {
|
|||
unsigned int drawFrame() {
|
||||
effects.DimAll(254); effects.ShowFrame();
|
||||
|
||||
for (int offset = 0; offset < effects.getCenterX(); offset++) {
|
||||
for (int offset = 0; offset < MATRIX_CENTER_X; offset++) {
|
||||
byte hue = 255 - (offset * 16 + hueoffset);
|
||||
CRGB color = effects.ColorFromCurrentPalette(hue);
|
||||
uint8_t x = effects.mapcos8(theta, offset, (VPANEL_W - 1) - offset);
|
||||
uint8_t y = effects.mapsin8(theta, offset, (VPANEL_H - 1) - offset);
|
||||
uint16_t xy = XY16(x, y);
|
||||
uint8_t x = mapcos8(theta, offset, (MATRIX_WIDTH - 1) - offset);
|
||||
uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset);
|
||||
uint16_t xy = XY(x, y);
|
||||
effects.leds[xy] = color;
|
||||
|
||||
if (millis() - last_update_hue_ms > 25) {
|
||||
last_update_hue_ms = millis();
|
||||
EVERY_N_MILLIS(25) {
|
||||
theta += 2;
|
||||
hueoffset += 1;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
#ifndef PatternRain_H
|
||||
#define PatternRain_H
|
||||
|
||||
// Codetastic 2024
|
||||
|
||||
struct rainDrop {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
CRGB colour;
|
||||
};
|
||||
|
||||
#define MAX_RAINDROPS 128
|
||||
|
||||
class PatternRain : public Drawable {
|
||||
|
||||
public:
|
||||
PatternRain()
|
||||
{
|
||||
name = (char *)"PatternRain";
|
||||
}
|
||||
|
||||
void start() {
|
||||
|
||||
buffer = (uint16_t *) malloc(((VPANEL_W*VPANEL_H)+1)*sizeof(uint16_t)); // always alloc an extra amount for XY
|
||||
}
|
||||
|
||||
void stop() {
|
||||
|
||||
free(buffer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned int drawFrame()
|
||||
{
|
||||
rain(32, 255, 224, 240, CRGB::Green);
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 45; // 1000/45 frames per secton
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
struct rainDrop rainDrops[MAX_RAINDROPS];
|
||||
int rainDropPos = 0;
|
||||
|
||||
uint16_t* buffer = NULL; // buffer of number
|
||||
|
||||
void rain(byte backgroundDepth, byte maxBrightness, byte spawnFreq, byte tailLength, CRGB rainColor)
|
||||
{
|
||||
CRGBPalette16 rain_p( CRGB::Black, rainColor );
|
||||
|
||||
// Dim routine
|
||||
for (int16_t i = 0; i < VPANEL_W; i++) {
|
||||
for (int16_t j = 0; j < VPANEL_H; j++) {
|
||||
uint16_t xy = XY16(i, j);
|
||||
effects.leds[xy].nscale8(tailLength);
|
||||
}
|
||||
}
|
||||
|
||||
// Genrate a new raindrop if the randomness says we should
|
||||
if (random(255) < spawnFreq) {
|
||||
|
||||
// Find a spare raindrop slot
|
||||
for (int d = 0; d < MAX_RAINDROPS; d++) {
|
||||
|
||||
// This raindrop is done with, it has... dropped
|
||||
if (rainDrops[d].y >= VPANEL_H ) // not currently in use
|
||||
{
|
||||
rainDrops[d].colour = ColorFromPalette(rain_p, random(backgroundDepth, maxBrightness));
|
||||
rainDrops[d].x = random(VPANEL_W-1);
|
||||
rainDrops[d].y = 0;
|
||||
|
||||
break; // exit until next time.
|
||||
}
|
||||
}
|
||||
} // end random spawn
|
||||
|
||||
// Iterate through all the rainDrops, draw the drop pixel on the layer
|
||||
for (int d = 0; d < MAX_RAINDROPS; d++) {
|
||||
effects.setPixel(rainDrops[d].x, rainDrops[d].y++, rainDrops[d].colour);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
79
examples/AuroraDemo/PatternSimplexNoise.h
Normal file
|
@ -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 30;
|
||||
}
|
||||
|
||||
// show just one layer
|
||||
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
|
||||
for (uint16_t i = 0; i < MATRIX_WIDTH; i++) {
|
||||
for (uint16_t j = 0; j < MATRIX_HEIGHT; j++) {
|
||||
uint8_t pixel = noise[i][j];
|
||||
|
||||
// assign a color depending on the actual palette
|
||||
effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
145
examples/AuroraDemo/PatternSnake.h
Normal file
|
@ -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) % MATRIX_HEIGHT;
|
||||
break;
|
||||
case LEFT:
|
||||
pixels[0].x = (pixels[0].x + 1) % MATRIX_WIDTH;
|
||||
break;
|
||||
case DOWN:
|
||||
pixels[0].y = pixels[0].y == 0 ? MATRIX_HEIGHT - 1 : pixels[0].y - 1;
|
||||
break;
|
||||
case RIGHT:
|
||||
pixels[0].x = pixels[0].x == 0 ? MATRIX_WIDTH - 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 = 6;
|
||||
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
|
113
examples/AuroraDemo/PatternSpark.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PatternSpark_H
|
||||
#define PatternSpark_H
|
||||
|
||||
class PatternSpark : public Drawable {
|
||||
private:
|
||||
|
||||
public:
|
||||
PatternSpark() {
|
||||
name = (char *)"Spark";
|
||||
}
|
||||
|
||||
// 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
|
||||
uint8_t 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.
|
||||
uint8_t sparking = 50;
|
||||
|
||||
unsigned int drawFrame() {
|
||||
// Add entropy to random number generator; we use a lot of it.
|
||||
random16_add_entropy( random16());
|
||||
|
||||
effects.DimAll(235); effects.ShowFrame();
|
||||
|
||||
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
|
||||
// Step 1. Cool down every cell a little
|
||||
for (int y = 0; y < MATRIX_HEIGHT; y++) {
|
||||
int xy = XY(x, y);
|
||||
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2));
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for (int y = 0; y < MATRIX_HEIGHT; 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) {
|
||||
uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3);
|
||||
|
||||
int xy = XY(xt, MATRIX_HEIGHT - 1);
|
||||
heat[xy] = qadd8(heat[xy], random8(160, 255));
|
||||
}
|
||||
|
||||
// Step 4. Map from heat cells to LED colors
|
||||
for (int y = 0; y < MATRIX_HEIGHT; 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, 240);
|
||||
|
||||
// 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(3);
|
||||
effects.MoveFractionalNoiseX(4);
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 15;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -48,7 +48,7 @@ public:
|
|||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
|
||||
effects.DimAll(190); effects.ShowFrame();
|
||||
|
||||
CRGB color = effects.ColorFromCurrentPalette(speed * 8);
|
||||
|
||||
|
@ -59,26 +59,23 @@ public:
|
|||
// target position
|
||||
float targetDegrees = degrees + speed;
|
||||
float targetRadians = radians(targetDegrees);
|
||||
int targetX = (int) (effects.getCenterX() + radius * cos(targetRadians));
|
||||
int targetY = (int) (effects.getCenterY() - radius * sin(targetRadians));
|
||||
int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians));
|
||||
int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians));
|
||||
|
||||
float tempDegrees = degrees;
|
||||
|
||||
for (int i =0; i < 16; i++)
|
||||
{
|
||||
do{
|
||||
float radians = radians(tempDegrees);
|
||||
x = (int) (effects.getCenterX() + radius * cos(radians));
|
||||
y = (int) (effects.getCenterY() - radius * sin(radians));
|
||||
x = (int) (MATRIX_CENTER_X + radius * cos(radians));
|
||||
y = (int) (MATRIX_CENTER_Y - radius * sin(radians));
|
||||
|
||||
effects.setPixel(x, y, color);
|
||||
effects.setPixel(y, x, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(y, x, color);
|
||||
|
||||
tempDegrees += 1;
|
||||
if (tempDegrees >= 360)
|
||||
tempDegrees = 0;
|
||||
|
||||
}
|
||||
|
||||
} while (x != targetX || y != targetY);
|
||||
|
||||
degrees += speed;
|
||||
|
||||
|
@ -96,8 +93,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
138
examples/AuroraDemo/PatternSpiral.h
Normal file
|
@ -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 (Oscillators)
|
||||
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 oscillators
|
||||
|
||||
unsigned long now = millis();
|
||||
|
||||
multiTimer[0].lastMillis = now;
|
||||
multiTimer[0].takt = 42; //x1
|
||||
multiTimer[0].up = MATRIX_WIDTH - 1;
|
||||
multiTimer[0].down = 0;
|
||||
multiTimer[0].count = 0;
|
||||
|
||||
multiTimer[1].lastMillis = now;
|
||||
multiTimer[1].takt = 55; //y1
|
||||
multiTimer[1].up = MATRIX_HEIGHT - 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 = MATRIX_WIDTH - 1;
|
||||
multiTimer[3].down = 0;
|
||||
multiTimer[3].count = 0;
|
||||
|
||||
multiTimer[4].lastMillis = now;
|
||||
multiTimer[4].takt = 89; //y2
|
||||
multiTimer[4].up = MATRIX_HEIGHT - 1;
|
||||
multiTimer[4].down = 0;
|
||||
multiTimer[4].count = 0;
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
// manage the Oscillators
|
||||
UpdateTimers();
|
||||
|
||||
// draw just a line defined by 5 oscillators
|
||||
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 oscillators 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
|
112
examples/AuroraDemo/PatternSpiro.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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 = MATRIX_WIDTH / 4;
|
||||
uint8_t radiusy = MATRIX_HEIGHT / 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 = true;
|
||||
|
||||
boolean handledChange = false;
|
||||
|
||||
public:
|
||||
PatternSpiro() {
|
||||
name = (char *)"Spiro";
|
||||
}
|
||||
|
||||
void start(){
|
||||
effects.ClearFrame();
|
||||
};
|
||||
|
||||
unsigned int drawFrame() {
|
||||
blur2d(effects.leds, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, 192);
|
||||
|
||||
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 >= MATRIX_WIDTH || 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;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,130 +0,0 @@
|
|||
#ifndef PatternStarfield_H
|
||||
#define PatternStarfield_H
|
||||
|
||||
struct Star
|
||||
{
|
||||
Star() {
|
||||
x = y = z = 0;
|
||||
colour = CRGB::White;
|
||||
}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
CRGB colour;
|
||||
};
|
||||
|
||||
|
||||
// Based on https://github.com/sinoia/oled-starfield/blob/master/src/starfield.cpp
|
||||
class PatternStarfield : public Drawable {
|
||||
|
||||
private:
|
||||
|
||||
const int starCount = 100; // number of stars in the star field
|
||||
const int maxDepth = 32; // maximum distance away for a star
|
||||
|
||||
// the star field - starCount stars represented as x, y and z co-ordinates
|
||||
// https://www.cplusplus.com/doc/tutorial/dynamic/
|
||||
Star * stars;
|
||||
//CRGBPalette16 currentPalette;
|
||||
|
||||
unsigned int drawFrame() { // aka drawStars
|
||||
|
||||
// Dim routine
|
||||
|
||||
for (int16_t i = 0; i < VPANEL_W; i++) {
|
||||
for (int16_t j = 0; j < VPANEL_H; j++) {
|
||||
|
||||
uint16_t xy = XY16(i, j);
|
||||
effects.leds[xy].nscale8(250);
|
||||
}
|
||||
}
|
||||
|
||||
int origin_x = VPANEL_W / 2;
|
||||
int origin_y = VPANEL_H / 2;
|
||||
|
||||
// Iterate through the stars reducing the z co-ordinate in order to move the
|
||||
// star closer.
|
||||
for (int i = 0; i < starCount; ++i) {
|
||||
stars[i].z -= 0.1;
|
||||
// if the star has moved past the screen (z < 0) reposition it far away
|
||||
// with random x and y positions.
|
||||
if (stars[i].z <= 0)
|
||||
{
|
||||
stars[i].x = getRandom(-25, 25);
|
||||
stars[i].y = getRandom(-25, 25);
|
||||
stars[i].z = maxDepth;
|
||||
}
|
||||
|
||||
// Convert the 3D coordinates to 2D using perspective projection.
|
||||
float k = VPANEL_W / stars[i].z;
|
||||
int x = static_cast<int>(stars[i].x * k + origin_x);
|
||||
int y = static_cast<int>(stars[i].y * k + origin_y);
|
||||
|
||||
// Draw the star (if it is visible in the screen).
|
||||
// Distant stars are smaller than closer stars.
|
||||
if ((0 <= x and x < VPANEL_H)
|
||||
and (0 <= y and y < VPANEL_H)) {
|
||||
|
||||
CRGB tmp = stars[i].colour;
|
||||
//CRGB tmp = CRGB::White;
|
||||
byte scale = 255 -(stars[i].z*7);
|
||||
tmp.nscale8(scale);
|
||||
|
||||
effects.setPixel(x,y, CRGB(tmp.r,tmp.g,tmp.b));
|
||||
}
|
||||
else
|
||||
{
|
||||
stars[i].z = -1; // set to -1 so it gets re-popualted
|
||||
}
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
int getRandom(int lower, int upper) {
|
||||
/* Generate and return a random number between lower and upper bound */
|
||||
return lower + static_cast<int>(rand() % (upper - lower + 1));
|
||||
}
|
||||
|
||||
/*
|
||||
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
|
||||
return ColorFromPalette(currentPalette, index, brightness, blendType);
|
||||
}
|
||||
*/
|
||||
|
||||
public:
|
||||
PatternStarfield()
|
||||
{
|
||||
name = (char *)"PatternStarfield";
|
||||
}
|
||||
|
||||
void start() {
|
||||
|
||||
//currentPalette = RainbowColors_p;
|
||||
//currentPalette = CloudColors_p;
|
||||
|
||||
// Allocate memory
|
||||
stars = new Star[starCount];
|
||||
|
||||
// Initialise the star field with random stars
|
||||
for (int i = 0; i < starCount; i++) {
|
||||
stars[i].x = getRandom(-25, 25);
|
||||
stars[i].y = getRandom(-25, 25);
|
||||
stars[i].z = getRandom(0, maxDepth);
|
||||
//stars[i].colour = ColorFromCurrentPalette(random(0, 128));
|
||||
stars[i].colour = effects.ColorFromCurrentPalette(random(0, 128));
|
||||
}
|
||||
} // end start
|
||||
|
||||
void stop() {
|
||||
delete[] stars;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
79
examples/AuroraDemo/PatternSwirl.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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() {
|
||||
effects.ClearFrame();
|
||||
}
|
||||
|
||||
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, MATRIX_WIDTH > 255 ? 255 : MATRIX_WIDTH, MATRIX_HEIGHT > 255 ? 255 : MATRIX_HEIGHT, blurAmount);
|
||||
#else
|
||||
effects.DimAll(blurAmount);
|
||||
#endif
|
||||
|
||||
// Use two out-of-sync sine waves
|
||||
uint8_t i = beatsin8(256/MATRIX_HEIGHT, borderWidth, MATRIX_WIDTH - borderWidth);
|
||||
uint8_t j = beatsin8(2048/MATRIX_WIDTH, borderWidth, MATRIX_HEIGHT - borderWidth);
|
||||
|
||||
// Also calculate some reflections
|
||||
uint8_t ni = (MATRIX_WIDTH - 1) - i;
|
||||
uint8_t nj = (MATRIX_HEIGHT - 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); // this doesn't work for non-square matrices
|
||||
effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17);
|
||||
//effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrices
|
||||
effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37);
|
||||
effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41);
|
||||
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
20
examples/AuroraDemo/PatternTest.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef PatternTest_H
|
||||
#define PatternTest_H
|
||||
|
||||
class PatternTest : public Drawable {
|
||||
private:
|
||||
|
||||
public:
|
||||
PatternTest() {
|
||||
name = (char *)"Test Pattern";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
|
||||
dma_display->fillScreen(dma_display->color565(128, 0, 0));
|
||||
return 1000;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
120
examples/AuroraDemo/PatternWave.h
Normal file
|
@ -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 / MATRIX_WIDTH;
|
||||
|
||||
uint8_t maxX = MATRIX_WIDTH - 1;
|
||||
uint8_t maxY = MATRIX_HEIGHT - 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 < MATRIX_WIDTH; 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 < MATRIX_HEIGHT; 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 < MATRIX_WIDTH; 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 < MATRIX_HEIGHT; 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
|
299
examples/AuroraDemo/Patterns.h
Normal file
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "PatternTest.h"
|
||||
//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSpiro.h"
|
||||
#include "PatternRadar.h"
|
||||
#include "PatternSwirl.h"
|
||||
#include "PatternPendulumWave.h"
|
||||
#include "PatternFlowField.h"
|
||||
#include "PatternIncrementalDrift.h"
|
||||
//#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternMunch.h"
|
||||
#include "PatternElectricMandala.h"
|
||||
//#include "PatternSpin.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSimplexNoise.h"
|
||||
#include "PatternWave.h"
|
||||
#include "PatternAttract.h"
|
||||
//#include "PatternBounce.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternFlock.h"
|
||||
#include "PatternInfinity.h"
|
||||
#include "PatternPlasma.h"
|
||||
#include "PatternSnake.h"
|
||||
#include "PatternInvaders.h"
|
||||
//#include "PatternCube.h" // Doesn't seem to work, omitting.
|
||||
//#include "PatternFire.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternLife.h"
|
||||
#include "PatternMaze.h"
|
||||
//#include "PatternPulse.h" // Doesn't seem to work, omitting.
|
||||
//#include "PatternSpark.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSpiral.h"
|
||||
|
||||
class Patterns : public Playlist {
|
||||
private:
|
||||
PatternTest patternTest;
|
||||
// PatternRainbowFlag rainbowFlag; // doesn't work
|
||||
// PatternPaletteSmear paletteSmear;
|
||||
// PatternMultipleStream multipleStream; // doesn't work
|
||||
// PatternMultipleStream2 multipleStream2; // doesn't work
|
||||
// PatternMultipleStream3 multipleStream3; // doesn't work
|
||||
// PatternMultipleStream4 multipleStream4; // doesn't work
|
||||
// PatternMultipleStream5 multipleStream5; // doesn't work
|
||||
// PatternMultipleStream8 multipleStream8; // doesn't work
|
||||
PatternSpiro spiro;
|
||||
// PatternRadar radar;
|
||||
PatternSwirl swirl;
|
||||
PatternPendulumWave pendulumWave;
|
||||
PatternFlowField flowField;
|
||||
PatternIncrementalDrift incrementalDrift;
|
||||
// PatternIncrementalDrift2 incrementalDrift2;
|
||||
PatternMunch munch;
|
||||
PatternElectricMandala electricMandala;
|
||||
// PatternSpin spin;
|
||||
PatternSimplexNoise simplexNoise;
|
||||
PatternWave wave;
|
||||
PatternAttract attract;
|
||||
// PatternBounce bounce;
|
||||
PatternFlock flock;
|
||||
PatternInfinity infinity;
|
||||
PatternPlasma plasma;
|
||||
PatternInvadersSmall invadersSmall;
|
||||
// PatternInvadersMedium invadersMedium;
|
||||
// PatternInvadersLarge invadersLarge;
|
||||
PatternSnake snake;
|
||||
// PatternCube cube;
|
||||
// PatternFire fire;
|
||||
PatternLife life;
|
||||
PatternMaze maze;
|
||||
// PatternPulse pulse;
|
||||
// PatternSpark spark;
|
||||
PatternSpiral spiral;
|
||||
|
||||
int currentIndex = 0;
|
||||
Drawable* currentItem;
|
||||
|
||||
int getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
//const static int PATTERN_COUNT = 37;
|
||||
|
||||
const static int PATTERN_COUNT = 17;
|
||||
|
||||
Drawable* shuffledItems[PATTERN_COUNT];
|
||||
|
||||
Drawable* items[PATTERN_COUNT] = {
|
||||
// &patternTest, // ok
|
||||
&spiro, // cool
|
||||
// &paletteSmear, // fail
|
||||
// &multipleStream, // fail
|
||||
// &multipleStream8,// fail
|
||||
// &multipleStream5,// fail
|
||||
// &multipleStream3,// fail
|
||||
// &radar, // fail
|
||||
// &multipleStream4, // fail
|
||||
// &multipleStream2, // fail
|
||||
&life, // ok
|
||||
&flowField,
|
||||
&pendulumWave, //11 ok
|
||||
|
||||
&incrementalDrift, //12 ok
|
||||
// &incrementalDrift2, // 13 fail
|
||||
&munch, // 14 ok
|
||||
&electricMandala, // 15 ok
|
||||
// &spin, // 16 ok but repetitive
|
||||
&simplexNoise, // 17 - cool!
|
||||
// &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars)
|
||||
// &rainbowFlag, //20 // fail
|
||||
&attract, // 21 ok
|
||||
&swirl, // 22
|
||||
// &bounce, // bouncing line crap
|
||||
&flock, // works
|
||||
&infinity, // works
|
||||
&plasma, // works
|
||||
&invadersSmall, // works ish
|
||||
// &invadersMedium, // fail
|
||||
// &invadersLarge, // fail
|
||||
&snake, // ok
|
||||
// &cube, // works ish
|
||||
// &fire, // ok ish
|
||||
&maze, // ok
|
||||
// &pulse,// fail
|
||||
// &spark, // same as fire
|
||||
&spiral, // ok
|
||||
};
|
||||
|
||||
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("}");
|
||||
}
|
||||
|
||||
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
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
* Aurora: https://github.com/pixelmatix/aurora
|
||||
* Original Copyright (c) 2014 Jason Coon
|
||||
*
|
||||
* Modified by Codetastic 2024
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef Patterns_H
|
||||
#define Patterns_H
|
||||
|
||||
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
|
||||
|
||||
#include "Vector2.hpp"
|
||||
#include "Boid.hpp"
|
||||
#include "Attractor.hpp"
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "PatternStarfield.hpp" // new 2024
|
||||
#include "PatternAttract.hpp"
|
||||
#include "PatternBounce.hpp" // Doesn't seem to work, omitting.
|
||||
#include "PatternCube.hpp" // Doesn't seem to work, omitting.
|
||||
#include "PatternElectricMandala.hpp"
|
||||
#include "PatternFireKoz.hpp" // Doesn't seem to work, omitting.
|
||||
#include "PatternFlock.hpp"
|
||||
#include "PatternFlowField.hpp"
|
||||
#include "PatternIncrementalDrift.hpp"
|
||||
#include "PatternIncrementalDrift2.hpp" // Doesn't seem to work, omitting.
|
||||
#include "PatternInfinity.hpp"
|
||||
#include "PatternMaze.hpp" // ??
|
||||
#include "PatternMunch.hpp"
|
||||
//#include "PatternNoiseSmearing.hpp"
|
||||
#include "PatternPendulumWave.hpp"
|
||||
#include "PatternPlasma.hpp"
|
||||
#include "PatternRadar.hpp"
|
||||
#include "PatternSimplexNoise.hpp"
|
||||
#include "PatternSnake.hpp"
|
||||
#include "PatternSpiral.hpp"
|
||||
#include "PatternSpiro.hpp"
|
||||
#include "PatternWave.hpp"
|
||||
#include "PatternRain.hpp"
|
||||
#include "PatternJuliaSetFractal.hpp"
|
||||
#include "PatternRain.hpp"
|
||||
#include "PatternFireworks.hpp"
|
||||
|
||||
|
||||
|
||||
class Patterns {
|
||||
private:
|
||||
|
||||
PatternStarfield starfield;
|
||||
PatternAttract attract;
|
||||
PatternBounce bounce;
|
||||
PatternCube cube;
|
||||
PatternElectricMandala electricMandala;
|
||||
PatternFireKoz fire;
|
||||
PatternFlock flock;
|
||||
PatternFlowField flowField;
|
||||
PatternIncrementalDrift incrementalDrift;
|
||||
PatternIncrementalDrift2 incrementalDrift2;
|
||||
PatternInfinity infinity;
|
||||
PatternMaze maze;
|
||||
PatternMunch munch;
|
||||
PatternPendulumWave pendwave;
|
||||
PatternPlasma plasma;
|
||||
PatternRadar radar;
|
||||
PatternSimplexNoise simpnoise;
|
||||
PatternSnake snake;
|
||||
PatternSpiral spiral;
|
||||
PatternSpiro spiro;
|
||||
PatternWave wave;
|
||||
PatternJuliaSet juliaSet;
|
||||
|
||||
PatternRain rain;
|
||||
PatternFirework fireworks;
|
||||
|
||||
|
||||
std::vector<Drawable*> availablePatterns = {
|
||||
&juliaSet,
|
||||
&starfield,
|
||||
&attract,
|
||||
&bounce,
|
||||
&cube,
|
||||
&electricMandala,
|
||||
&fire,
|
||||
&flock,
|
||||
&spiro,
|
||||
&radar,
|
||||
&flowField,
|
||||
&incrementalDrift,
|
||||
&incrementalDrift2,
|
||||
&infinity,
|
||||
&maze,
|
||||
&munch,
|
||||
&pendwave,
|
||||
&plasma,
|
||||
&radar,
|
||||
&simpnoise,
|
||||
&spiro,
|
||||
&wave,
|
||||
&rain,
|
||||
&fireworks
|
||||
};
|
||||
|
||||
int currentIndex = 0;
|
||||
Drawable* currentItem;
|
||||
|
||||
int getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
Patterns() {
|
||||
this->currentItem = availablePatterns[0];
|
||||
this->currentItem->start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (currentItem)
|
||||
currentItem->stop();
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (currentItem)
|
||||
currentItem->start();
|
||||
}
|
||||
|
||||
void moveTo(int index)
|
||||
{
|
||||
index = ((index >= availablePatterns.size()) || (index < 0)) ? 0 : index;
|
||||
|
||||
if (currentItem)
|
||||
currentItem->stop();
|
||||
|
||||
currentIndex = index;
|
||||
currentItem = availablePatterns[currentIndex];
|
||||
|
||||
Serial.print("Changing pattern to: ");
|
||||
Serial.println(getCurrentPatternName());
|
||||
|
||||
if (currentItem)
|
||||
currentItem->start();
|
||||
|
||||
} // index
|
||||
|
||||
|
||||
void move(int step) {
|
||||
|
||||
currentIndex += step;
|
||||
|
||||
if (currentIndex >= availablePatterns.size()) currentIndex = 0;
|
||||
else if (currentIndex < 0) currentIndex = 0;
|
||||
|
||||
moveTo(currentIndex);
|
||||
}
|
||||
|
||||
void moveRandom(int step) {
|
||||
int rand_index = random(0, availablePatterns.size()-1);
|
||||
moveTo(rand_index);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
return currentItem->drawFrame();
|
||||
}
|
||||
|
||||
void listPatterns() {
|
||||
Serial.println(F("{"));
|
||||
Serial.print(F(" \"count\": "));
|
||||
Serial.print(availablePatterns.size());
|
||||
Serial.println(",");
|
||||
Serial.println(F(" \"results\": ["));
|
||||
|
||||
for (size_t i = 0; i < availablePatterns.size(); i++) {
|
||||
Serial.print(F(" \""));
|
||||
Serial.print(i, DEC);
|
||||
Serial.print(F(": "));
|
||||
Serial.print(availablePatterns[i]->name);
|
||||
if (i == availablePatterns.size() - 1)
|
||||
Serial.println(F("\""));
|
||||
else
|
||||
Serial.println(F("\","));
|
||||
}
|
||||
|
||||
Serial.println(" ]");
|
||||
Serial.println("}");
|
||||
}
|
||||
|
||||
char * getCurrentPatternName()
|
||||
{
|
||||
return currentItem->name;
|
||||
}
|
||||
/*
|
||||
bool setPattern(String name) {
|
||||
|
||||
for (size_t i = 0; i < availablePatterns.size(); i++) {
|
||||
if (name.compareTo(availablePatterns[i]->name) == 0) {
|
||||
moveTo(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
bool setPattern(int index) {
|
||||
if (index >= availablePatterns.size() || index < 0)
|
||||
return false;
|
||||
|
||||
moveTo(index);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
39
examples/AuroraDemo/Playlist.h
Normal file
|
@ -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
|
|
@ -1,9 +1,6 @@
|
|||
## Aurora Demo
|
||||
* This demonstrates a combination of the following libraries:
|
||||
- "ESP32-HUB75-MatrixPanel-DMA" to send pixel data to the physical panels in combination with its in-built "VirtualMatrix" class to create a virtual display of chained panels, so the graphical effects of the Aurora demonstrations can be shown over a 'bigger' grid of physical panels acting as one big display.
|
||||
- "GFX_Lite" to provide a simple graphics library for drawing on the virtual display.
|
||||
- Note: GFX_Lite is a fork of AdaFruitGFX and FastLED library combined together, with a focus on simplicity and ease of use.
|
||||
A port of Aurora visualisations
|
||||
======
|
||||
|
||||
## Instructions
|
||||
* Use the serial input to advance through the patterns, or to toggle auto advance.
|
||||
* Sending 'n' will advance to the next pattern, 'p' will go to the previous pattern. Sending 'a' will toggle auto advance on and off.
|
||||
Not all of the visualisations have been ported. About 17 of 37 work, or have been included as I think they look best.
|
||||
|
||||
Original source: https://github.com/pixelmatix/aurora
|
50
examples/ChainedPanelsAuroraDemo/Attractor.h
Normal file
|
@ -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 = 10;
|
||||
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 gravitational force magnitude
|
||||
force *= strength; // Get force vector --> magnitude * direction
|
||||
return force;
|
||||
}
|
||||
};
|
|
@ -322,5 +322,5 @@ class Boid {
|
|||
}
|
||||
};
|
||||
|
||||
static const uint8_t AVAILABLE_BOID_COUNT = VPANEL_W;
|
||||
static const uint8_t AVAILABLE_BOID_COUNT = 40;
|
||||
Boid boids[AVAILABLE_BOID_COUNT];
|
209
examples/ChainedPanelsAuroraDemo/ChainedPanelsAuroraDemo.ino
Normal file
|
@ -0,0 +1,209 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
/* Default library pin configuration for the reference
|
||||
you can redefine only ones you need later on object creation
|
||||
|
||||
#define R1 25
|
||||
#define G1 26
|
||||
#define BL1 27
|
||||
#define R2 14
|
||||
#define G2 12
|
||||
#define BL2 13
|
||||
#define CH_A 23
|
||||
#define CH_B 19
|
||||
#define CH_C 5
|
||||
#define CH_D 17
|
||||
#define CH_E -1 // assign to any available pin if using two panels or 64x64 panels with 1/32 scan
|
||||
#define CLK 16
|
||||
#define LAT 4
|
||||
#define OE 15
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------- Display Config Initialisation -------------------- */
|
||||
// Assume we have four 64x32 panels daisy-chained and ESP32 attached to the bottom right corner
|
||||
#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 2 // Number of INDIVIDUAL PANELS per ROW
|
||||
#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another
|
||||
|
||||
// Change this to your needs, for details on VirtualPanel pls see ChainedPanels example
|
||||
#define SERPENT false
|
||||
#define TOPDOWN false
|
||||
|
||||
// Virtual Panel dimensions - our combined panel would be a square 4x4 modules with a combined resolution of 128x128 pixels
|
||||
#define VPANEL_W PANEL_RES_X*NUM_COLS // Kosso: All Pattern files have had the MATRIX_WIDTH and MATRIX_HEIGHT replaced by these.
|
||||
#define VPANEL_H PANEL_RES_Y*NUM_ROWS //
|
||||
|
||||
// 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.h>
|
||||
Preferences preferences;
|
||||
int lastPattern = 0;
|
||||
|
||||
|
||||
/* -------------------------- Class Initialisation -------------------------- */
|
||||
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>
|
||||
#include <FastLED.h> // Used for some mathematics calculations and effects.
|
||||
|
||||
// placeholder for the matrix object
|
||||
MatrixPanel_I2S_DMA *matrix = nullptr;
|
||||
|
||||
// placeholder for the virtual display object
|
||||
VirtualMatrixPanel *virtualDisp = nullptr;
|
||||
|
||||
// Aurora related
|
||||
#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 = 20000; // 10 seconds
|
||||
unsigned long next_frame = 0;
|
||||
|
||||
void listPatterns();
|
||||
|
||||
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);
|
||||
|
||||
// Configure your matrix setup here
|
||||
HUB75_I2S_CFG mxconfig(PANEL_RES_X, PANEL_RES_Y, PANEL_CHAIN);
|
||||
|
||||
// custom pin mapping (if required)
|
||||
//HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK};
|
||||
//mxconfig.gpio = _pins;
|
||||
|
||||
// in case that we use panels based on FM6126A chip, we can change that
|
||||
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
|
||||
|
||||
// FM6126A panels could be cloked at 20MHz with no visual artefacts
|
||||
// mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;
|
||||
|
||||
// OK, now we can create our matrix object
|
||||
matrix = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
|
||||
// Allocate memory and start DMA display
|
||||
if( not matrix->begin() )
|
||||
Serial.println("****** !KABOOM! I2S memory allocation failed ***********");
|
||||
|
||||
// let's adjust default brightness to about 75%
|
||||
matrix->setBrightness8(96); // range is 0-255, 0 - 0%, 255 - 100%
|
||||
|
||||
// create VirtualDisplay object based on our newly created dma_display object
|
||||
virtualDisp = new VirtualMatrixPanel((*matrix), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, CHAIN_TOP_LEFT_DOWN);
|
||||
|
||||
Serial.println("**************** Starting Aurora Effects Demo ****************");
|
||||
|
||||
Serial.print("MATRIX_WIDTH: "); Serial.println(PANEL_RES_X*PANEL_CHAIN);
|
||||
Serial.print("MATRIX_HEIGHT: "); Serial.println(PANEL_RES_Y);
|
||||
|
||||
#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.moveRandom(1);
|
||||
//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();
|
||||
}
|
|
@ -7,8 +7,6 @@
|
|||
* 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
|
||||
*
|
||||
* Modified by Codetastic 2024
|
||||
*
|
||||
* 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
|
||||
|
@ -31,79 +29,106 @@
|
|||
#ifndef Effects_H
|
||||
#define Effects_H
|
||||
|
||||
/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */
|
||||
|
||||
const int MATRIX_CENTER_X = VPANEL_W / 2;
|
||||
const int MATRIX_CENTER_Y = VPANEL_H / 2;
|
||||
// US vs GB, huh? :)
|
||||
//const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
|
||||
//const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
|
||||
#define MATRIX_CENTRE_X MATRIX_CENTER_X
|
||||
#define MATRIX_CENTRE_Y MATRIX_CENTER_Y
|
||||
|
||||
|
||||
/**
|
||||
* The one for 256+ matrices
|
||||
* otherwise this:
|
||||
* for (uint8_t i = 0; i < VPANEL_W; i++) {}
|
||||
* turns into an infinite loop
|
||||
*/
|
||||
uint16_t XY16( uint16_t x, uint16_t y)
|
||||
{
|
||||
if( x >= VPANEL_W) return 0;
|
||||
if( y >= VPANEL_H) return 0;
|
||||
const uint16_t NUM_LEDS = (VPANEL_W * VPANEL_H) + 1; // one led spare to capture out of bounds
|
||||
|
||||
return (y * VPANEL_W) + x;
|
||||
}
|
||||
// forward declaration
|
||||
uint16_t XY16( uint16_t x, uint16_t y);
|
||||
|
||||
/* 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: VPANEL_W-1 etc.
|
||||
* Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrices :(
|
||||
*/
|
||||
uint16_t XY( uint8_t x, uint8_t y)
|
||||
{
|
||||
return XY16(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* The one for 256+ matrices
|
||||
* otherwise this:
|
||||
* for (uint8_t i = 0; i < VPANEL_W; i++) {}
|
||||
* turns into an infinite loop
|
||||
*/
|
||||
uint16_t XY16( uint16_t x, uint16_t y)
|
||||
{
|
||||
if( x >= VPANEL_W) return 0;
|
||||
if( y >= VPANEL_H) return 0;
|
||||
|
||||
return (y * VPANEL_W) + x + 1; // everything offset by one to compute out of bounds stuff - never displayed by ShowFrame()
|
||||
}
|
||||
|
||||
|
||||
/* 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: VPANEL_W-1 etc.
|
||||
* Ugh... uint8_t - really??? this weak method can't cope with 256+ pixel matrices :(
|
||||
*/
|
||||
uint16_t XY( uint16_t x, uint16_t y)
|
||||
{
|
||||
return XY16(x, y);
|
||||
}
|
||||
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]; // none of the currently enabled effects uses this
|
||||
|
||||
class EffectsLayer : public GFX {
|
||||
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 **noise = nullptr; // we will allocate mem later
|
||||
uint8_t noisesmoothing;
|
||||
|
||||
class Effects {
|
||||
public:
|
||||
|
||||
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 = nullptr; // we will allocate mem later
|
||||
uint8_t noisesmoothing;
|
||||
|
||||
|
||||
CRGB *leds;
|
||||
int width;
|
||||
int height;
|
||||
int num_leds = 0;
|
||||
|
||||
EffectsLayer(int w, int h) : GFX(w, h), width(w), height(h) {
|
||||
|
||||
Effects(){
|
||||
// we do dynamic allocation for leds buffer, otherwise esp32 toolchain can't link static arrays of such a big size for 256+ matrices
|
||||
leds = (CRGB *)malloc((width * height + 1) * sizeof(CRGB));
|
||||
num_leds = width * height;
|
||||
leds = (CRGB *)malloc(NUM_LEDS * sizeof(CRGB));
|
||||
|
||||
// allocate mem for noise effect
|
||||
// (there should be some guards for malloc errors eventually)
|
||||
noise = (uint8_t **)malloc(width * sizeof(uint8_t *));
|
||||
for (int i = 0; i < width; ++i) {
|
||||
noise[i] = (uint8_t *)malloc(height * sizeof(uint8_t));
|
||||
noise = (uint8_t **)malloc(VPANEL_W * sizeof(uint8_t *));
|
||||
for (int i = 0; i < VPANEL_W; ++i) {
|
||||
noise[i] = (uint8_t *)malloc(VPANEL_H * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
// Set starting palette
|
||||
currentPalette = RainbowColors_p;
|
||||
loadPalette(0);
|
||||
NoiseVariablesSetup();
|
||||
|
||||
ClearFrame();
|
||||
}
|
||||
|
||||
~EffectsLayer(){
|
||||
~Effects(){
|
||||
free(leds);
|
||||
for (int i = 0; i < width; ++i) {
|
||||
for (int i = 0; i < VPANEL_W; ++i) {
|
||||
free(noise[i]);
|
||||
}
|
||||
free(noise);
|
||||
|
@ -116,78 +141,91 @@ public:
|
|||
* 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 setPixel(int16_t x, int16_t y, CRGB color)
|
||||
void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color)
|
||||
{
|
||||
leds[XY16(x, y)] = color;
|
||||
leds[XY(x, y)] = color;
|
||||
//matrix.drawPixelRGB888(x, y, color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
// write one pixel with the specified color from the current palette to coordinates
|
||||
void setPixelFromPaletteIndex(int x, int y, uint8_t colorIndex) {
|
||||
leds[XY16(x, y)] = ColorFromCurrentPalette(colorIndex);
|
||||
void Pixel(int x, int y, uint8_t colorIndex) {
|
||||
leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex);
|
||||
//matrix.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it?
|
||||
}
|
||||
|
||||
void PrepareFrame() { }
|
||||
void PrepareFrame() {
|
||||
// leds = (CRGB*) backgroundLayer.backBuffer();
|
||||
}
|
||||
|
||||
void ShowFrame() { // send to display
|
||||
void ShowFrame() {
|
||||
//#if (FASTLED_VERSION >= 3001000)
|
||||
// nblendPaletteTowardPalette(currentPalette, targetPalette, 24);
|
||||
//#else
|
||||
currentPalette = targetPalette;
|
||||
|
||||
for (int y=0; y<height; ++y){
|
||||
for (int x=0; x<width; ++x){
|
||||
uint16_t _pixel = XY16(x,y);
|
||||
virtualDisp->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].b);
|
||||
} // end loop to copy fast led to the dma matrix
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
|
||||
uint16_t getCenterX() {
|
||||
return width / 2;
|
||||
}
|
||||
// backgroundLayer.swapBuffers();
|
||||
// leds = (CRGB*) backgroundLayer.backBuffer();
|
||||
// LEDS.countFPS();
|
||||
|
||||
uint16_t getCenterY() {
|
||||
return height / 2;
|
||||
for (int y=0; y<VPANEL_H; ++y){
|
||||
for (int x=0; x<VPANEL_W; ++x){
|
||||
//Serial.printf("Flushing x, y coord %d, %d\n", x, y);
|
||||
uint16_t _pixel = XY16(x,y);
|
||||
virtualDisp->drawPixelRGB888( x, y, leds[_pixel].r, leds[_pixel].g, leds[_pixel].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 DimAll(byte value)
|
||||
{
|
||||
for (int i = 0; i < NUM_LEDS; i++)
|
||||
{
|
||||
leds[i].nscale8(value);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearFrame() {
|
||||
for (int i = 0; i < num_leds; i++)
|
||||
leds[i]= CRGB(0,0,0);
|
||||
|
||||
void ClearFrame()
|
||||
{
|
||||
memset(leds, 0x00, NUM_LEDS * sizeof(CRGB)); // flush
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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;
|
||||
|
@ -200,6 +238,11 @@ public:
|
|||
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);
|
||||
|
@ -351,7 +394,7 @@ public:
|
|||
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, width - 1); //why? to keep the result in the range of 0-VPANEL_W (matrix size)
|
||||
p[i] = map8(sin8(osci[i]), 0, VPANEL_W - 1); //why? to keep the result in the range of 0-VPANEL_W (matrix size)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,11 +404,11 @@ public:
|
|||
|
||||
// rotates the first 16x16 quadrant 3 times onto a 32x32 (+90 degrees rotation for each one)
|
||||
void Caleidoscope1() {
|
||||
for (int x = 0; x < width / 2; x++) {
|
||||
for (int y = 0; y < height / 2; y++) {
|
||||
leds[XY16(width - 1 - x, y)] = leds[XY16(x, y)];
|
||||
leds[XY16(width - 1 - x, height - 1 - y)] = leds[XY16(x, y)];
|
||||
leds[XY16(x, height - 1 - y)] = leds[XY16(x, y)];
|
||||
for (int x = 0; x < MATRIX_CENTER_X; x++) {
|
||||
for (int y = 0; y < MATRIX_CENTER_Y; y++) {
|
||||
leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(x, y)];
|
||||
leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
|
||||
leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -373,19 +416,19 @@ public:
|
|||
|
||||
// mirror the first 16x16 quadrant 3 times onto a 32x32
|
||||
void Caleidoscope2() {
|
||||
for (int x = 0; x < width / 2; x++) {
|
||||
for (int y = 0; y < height / 2; y++) {
|
||||
leds[XY16(width - 1 - x, y)] = leds[XY16(y, x)];
|
||||
leds[XY16(x, height - 1 - y)] = leds[XY16(y, x)];
|
||||
leds[XY16(width - 1 - x, height - 1 - y)] = leds[XY16(x, y)];
|
||||
for (int x = 0; x < MATRIX_CENTER_X; x++) {
|
||||
for (int y = 0; y < MATRIX_CENTER_Y; y++) {
|
||||
leds[XY16(VPANEL_W - 1 - x, y)] = leds[XY16(y, x)];
|
||||
leds[XY16(x, VPANEL_H - 1 - y)] = leds[XY16(y, x)];
|
||||
leds[XY16(VPANEL_W - 1 - x, VPANEL_H - 1 - y)] = leds[XY16(x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy one diagonal triangle into the other one within a 16x16
|
||||
void Caleidoscope3() {
|
||||
for (int x = 0; x <= width / 2 - 1 && x < height; x++) {
|
||||
for (int y = 0; y <= x && y<height; y++) {
|
||||
for (int x = 0; x <= MATRIX_CENTRE_X && x < VPANEL_H; x++) {
|
||||
for (int y = 0; y <= x && y<VPANEL_H; y++) {
|
||||
leds[XY16(x, y)] = leds[XY16(y, x)];
|
||||
}
|
||||
}
|
||||
|
@ -393,48 +436,48 @@ public:
|
|||
|
||||
// copy one diagonal triangle into the other one within a 16x16 (90 degrees rotated compared to Caleidoscope3)
|
||||
void Caleidoscope4() {
|
||||
for (int x = 0; x <= width / 2 - 1; x++) {
|
||||
for (int y = 0; y <= height / 2 - 1 - x; y++) {
|
||||
leds[XY16(height / 2 - 1 - y, width / 2 - 1 - x)] = leds[XY16(x, y)];
|
||||
for (int x = 0; x <= MATRIX_CENTRE_X; x++) {
|
||||
for (int y = 0; y <= MATRIX_CENTRE_Y - x; y++) {
|
||||
leds[XY16(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY16(x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy one diagonal triangle into the other one within a 8x8
|
||||
void Caleidoscope5() {
|
||||
for (int x = 0; x < width / 4; x++) {
|
||||
for (int y = 0; y <= x && y<=height; y++) {
|
||||
for (int x = 0; x < VPANEL_W / 4; x++) {
|
||||
for (int y = 0; y <= x && y<=VPANEL_H; y++) {
|
||||
leds[XY16(x, y)] = leds[XY16(y, x)];
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = width / 4; x < width / 2; x++) {
|
||||
for (int y = height / 4; y >= 0; y--) {
|
||||
for (int x = VPANEL_W / 4; x < VPANEL_W / 2; x++) {
|
||||
for (int y = VPANEL_H / 4; y >= 0; y--) {
|
||||
leds[XY16(x, y)] = leds[XY16(y, x)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Caleidoscope6() {
|
||||
for (int x = 1; x < width / 2; x++) {
|
||||
for (int x = 1; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 7)] = leds[XY16(x, 0)];
|
||||
} //a
|
||||
for (int x = 2; x < width / 2; x++) {
|
||||
for (int x = 2; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 6)] = leds[XY16(x, 1)];
|
||||
} //b
|
||||
for (int x = 3; x < width / 2; x++) {
|
||||
for (int x = 3; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 5)] = leds[XY16(x, 2)];
|
||||
} //c
|
||||
for (int x = 4; x < width / 2; x++) {
|
||||
for (int x = 4; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 4)] = leds[XY16(x, 3)];
|
||||
} //d
|
||||
for (int x = 5; x < width / 2; x++) {
|
||||
for (int x = 5; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 3)] = leds[XY16(x, 4)];
|
||||
} //e
|
||||
for (int x = 6; x < width / 2; x++) {
|
||||
for (int x = 6; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 2)] = leds[XY16(x, 5)];
|
||||
} //f
|
||||
for (int x = 7; x < width / 2; x++) {
|
||||
for (int x = 7; x < MATRIX_CENTER_X; x++) {
|
||||
leds[XY16(7 - x, 1)] = leds[XY16(x, 6)];
|
||||
} //g
|
||||
}
|
||||
|
@ -523,7 +566,7 @@ public:
|
|||
}
|
||||
|
||||
// give it a linear tail to the right
|
||||
void StreamRight(byte scale, int fromX = 0, int toX = 0, int fromY = 0, int toY = 0)
|
||||
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++) {
|
||||
|
@ -536,7 +579,7 @@ public:
|
|||
}
|
||||
|
||||
// give it a linear tail to the left
|
||||
void StreamLeft(byte scale, int fromX = 0, int toX = 0, int fromY = 0, int toY = 0)
|
||||
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++) {
|
||||
|
@ -551,66 +594,66 @@ public:
|
|||
// give it a linear tail downwards
|
||||
void StreamDown(byte scale)
|
||||
{
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 1; y < height; y++) {
|
||||
for (int x = 0; x < VPANEL_W; x++) {
|
||||
for (int y = 1; y < VPANEL_H; y++) {
|
||||
leds[XY16(x, y)] += leds[XY16(x, y - 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < width; x++)
|
||||
for (int x = 0; x < VPANEL_W; x++)
|
||||
leds[XY16(x, 0)].nscale8(scale);
|
||||
}
|
||||
|
||||
// give it a linear tail upwards
|
||||
void StreamUp(byte scale)
|
||||
{
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = height - 2; y >= 0; y--) {
|
||||
for (int x = 0; x < VPANEL_W; x++) {
|
||||
for (int y = VPANEL_H - 2; y >= 0; y--) {
|
||||
leds[XY16(x, y)] += leds[XY16(x, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < width; x++)
|
||||
leds[XY16(x, height - 1)].nscale8(scale);
|
||||
for (int x = 0; x < VPANEL_W; x++)
|
||||
leds[XY16(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 < width - 1; x++) {
|
||||
for (int y = height - 2; y >= 0; y--) {
|
||||
for (int x = 0; x < VPANEL_W - 1; x++) {
|
||||
for (int y = VPANEL_H - 2; y >= 0; y--) {
|
||||
leds[XY16(x, y)] += leds[XY16(x + 1, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < width; x++)
|
||||
leds[XY16(x, height - 1)].nscale8(scale);
|
||||
for (int y = 0; y < height; y++)
|
||||
leds[XY16(width - 1, y)].nscale8(scale);
|
||||
for (int x = 0; x < VPANEL_W; x++)
|
||||
leds[XY16(x, VPANEL_H - 1)].nscale8(scale);
|
||||
for (int y = 0; y < VPANEL_H; y++)
|
||||
leds[XY16(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 < width - 1; x++) {
|
||||
for (int y = height - 2; y >= 0; y--) {
|
||||
for (int x = 0; x < VPANEL_W - 1; x++) {
|
||||
for (int y = VPANEL_H - 2; y >= 0; y--) {
|
||||
leds[XY16(x + 1, y)] += leds[XY16(x, y + 1)];
|
||||
leds[XY16(x, y)].nscale8(scale);
|
||||
}
|
||||
}
|
||||
// fade the bottom row
|
||||
for (int x = 0; x < width; x++)
|
||||
leds[XY16(x, height - 1)].nscale8(scale);
|
||||
for (int x = 0; x < VPANEL_W; x++)
|
||||
leds[XY16(x, VPANEL_H - 1)].nscale8(scale);
|
||||
|
||||
// fade the right column
|
||||
for (int y = 0; y < height; y++)
|
||||
leds[XY16(width - 1, y)].nscale8(scale);
|
||||
for (int y = 0; y < VPANEL_H; y++)
|
||||
leds[XY16(VPANEL_W - 1, y)].nscale8(scale);
|
||||
}
|
||||
|
||||
// just move everything one line down
|
||||
void MoveDown() {
|
||||
for (int y = height - 1; y > 0; y--) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = VPANEL_H - 1; y > 0; y--) {
|
||||
for (int x = 0; x < VPANEL_W; x++) {
|
||||
leds[XY16(x, y)] = leds[XY16(x, y - 1)];
|
||||
}
|
||||
}
|
||||
|
@ -619,7 +662,7 @@ public:
|
|||
// just move everything one line down
|
||||
void VerticalMoveFrom(int start, int end) {
|
||||
for (int y = end; y > start; y--) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int x = 0; x < VPANEL_W; x++) {
|
||||
leds[XY16(x, y)] = leds[XY16(x, y - 1)];
|
||||
}
|
||||
}
|
||||
|
@ -637,18 +680,18 @@ public:
|
|||
|
||||
// rotate + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X)
|
||||
void RotateTriangle() {
|
||||
for (int x = 1; x < width / 2; x++) {
|
||||
for (int x = 1; x < MATRIX_CENTER_X; x++) {
|
||||
for (int y = 0; y < x; y++) {
|
||||
leds[XY16(x, height / 2 - 1 - y)] = leds[XY16(width / 2 - 1 - x, y)];
|
||||
leds[XY16(x, 7 - y)] = leds[XY16(7 - x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mirror + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X)
|
||||
void MirrorTriangle() {
|
||||
for (int x = 1; x < width / 2; x++) {
|
||||
for (int x = 1; x < MATRIX_CENTER_X; x++) {
|
||||
for (int y = 0; y < x; y++) {
|
||||
leds[XY16(height / 2 - 1 - y, x)] = leds[XY16(width / 2 - 1 - x, y)];
|
||||
leds[XY16(7 - y, x)] = leds[XY16(7 - x, y)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -656,9 +699,9 @@ public:
|
|||
// draw static rainbow triangle pattern (MATRIX_CENTER_XxWIDTH / 2)
|
||||
// (just for debugging)
|
||||
void RainbowTriangle() {
|
||||
for (int i = 0; i < width / 2; i++) {
|
||||
for (int i = 0; i < MATRIX_CENTER_X; i++) {
|
||||
for (int j = 0; j <= i; j++) {
|
||||
setPixelFromPaletteIndex(height / 2 - 1 - i, j, i * j * 4);
|
||||
Pixel(7 - i, j, i * j * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -688,6 +731,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -711,11 +761,11 @@ public:
|
|||
}
|
||||
|
||||
void FillNoise() {
|
||||
for (uint16_t i = 0; i < width; i++) {
|
||||
uint32_t ioffset = noise_scale_x * (i - width / 2);
|
||||
for (uint16_t i = 0; i < VPANEL_W; i++) {
|
||||
uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y);
|
||||
|
||||
for (uint16_t j = 0; j < height; j++) {
|
||||
uint32_t joffset = noise_scale_y * (j - height / 2);
|
||||
for (uint16_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;
|
||||
|
||||
|
@ -734,7 +784,7 @@ public:
|
|||
|
||||
CRGB tmp = 0;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
for (int y = 0; y < VPANEL_H; y++)
|
||||
{
|
||||
|
||||
// Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/
|
||||
|
@ -744,24 +794,24 @@ public:
|
|||
for (int m = 0; m < delta; m++)
|
||||
{
|
||||
// Do this delta time for each row... computationally expensive potentially.
|
||||
for(int x = 0; x < width; x++)
|
||||
for(int x = 0; x < VPANEL_W; x++)
|
||||
{
|
||||
leds[XY16(x, y)] = leds [XY16(x+1, y)];
|
||||
}
|
||||
|
||||
leds[XY16(width-1, y)] = tmp;
|
||||
leds[XY16(VPANEL_W-1, y)] = tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Shift
|
||||
for (int x = 0; x < VPANEL_W - delta; x++) {
|
||||
leds2[XY16(x, y)] = leds[XY16(x + delta, y)];
|
||||
leds2[XY(x, y)] = leds[XY(x + delta, y)];
|
||||
}
|
||||
|
||||
// Wrap around
|
||||
for (int x = VPANEL_W - delta; x < VPANEL_W; x++) {
|
||||
leds2[XY16(x, y)] = leds[XY16(x + delta - VPANEL_W, y)];
|
||||
leds2[XY(x, y)] = leds[XY(x + delta - VPANEL_W, y)];
|
||||
}
|
||||
*/
|
||||
} // end row loop
|
||||
|
@ -770,7 +820,7 @@ public:
|
|||
// write back to leds
|
||||
for (uint8_t y = 0; y < VPANEL_H; y++) {
|
||||
for (uint8_t x = 0; x < VPANEL_W; x++) {
|
||||
leds[XY16(x, y)] = leds2[XY16(x, y)];
|
||||
leds[XY(x, y)] = leds2[XY(x, y)];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -780,38 +830,23 @@ public:
|
|||
{
|
||||
|
||||
CRGB tmp = 0;
|
||||
for (int x = 0; x < width; x++)
|
||||
for (int x = 0; x < VPANEL_W; x++)
|
||||
{
|
||||
tmp = leds[XY16(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 < height; y++)
|
||||
for(int y = 0; y < VPANEL_H; y++)
|
||||
{
|
||||
leds[XY16(x, y)] = leds [XY16(x, y+1)];
|
||||
}
|
||||
|
||||
leds[XY16(x, height-1)] = tmp;
|
||||
leds[XY16(x, VPANEL_H-1)] = tmp;
|
||||
}
|
||||
} // end column loop
|
||||
} /// MoveY
|
||||
|
||||
// Override GFX methods
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color) override {
|
||||
setPixel(x, y, CRGB(color));
|
||||
}
|
||||
|
||||
// Override GFX methods
|
||||
void drawPixel(int16_t x, int16_t y, CRGB color) override {
|
||||
setPixel(x, y, color);
|
||||
}
|
||||
|
||||
void fillScreen(uint16_t color) override {
|
||||
ClearFrame();
|
||||
}
|
||||
|
||||
// Add any other GFX methods you want to override
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
150
examples/ChainedPanelsAuroraDemo/Geometry.h
Normal file
|
@ -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
|
|
@ -1,117 +1,3 @@
|
|||
/*
|
||||
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
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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 EffectsLayer.h
|
||||
uint8_t fireBuffer[VPANEL_W][VPANEL_H][2];
|
||||
|
||||
public:
|
||||
PatternFireKoz() {
|
||||
name = (char *)"FireKoz";
|
||||
}
|
||||
|
||||
void start(){
|
||||
effects.ClearFrame();
|
||||
}
|
||||
|
||||
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.setPixel(x, y, CRGB(0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
effects.setPixel(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
|
74
examples/ChainedPanelsAuroraDemo/PatternAttract.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
class PatternBounce : public Drawable {
|
||||
private:
|
||||
static const int count = VPANEL_W-1;
|
||||
static const int count = 32;
|
||||
PVector gravity = PVector(0, 0.0125);
|
||||
|
||||
public:
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
boid.update();
|
||||
|
||||
effects.setPixel(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
|
||||
|
||||
if (boid.location.y >= VPANEL_H - 1) {
|
||||
boid.location.y = VPANEL_H - 1;
|
|
@ -35,7 +35,7 @@ class PatternCube : public Drawable {
|
|||
int cubeWidth = 28; // Cube size
|
||||
float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis
|
||||
float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis
|
||||
float Ox = VPANEL_W/2, Oy = VPANEL_H/2; // position (x,y) of the frame center
|
||||
float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center
|
||||
int zCamera = 110; // distance from cube to the eye of the camera
|
||||
|
||||
// Local vertices
|
||||
|
@ -151,11 +151,11 @@ class PatternCube : public Drawable {
|
|||
public:
|
||||
PatternCube() {
|
||||
name = (char *)"Cube";
|
||||
make(VPANEL_W);
|
||||
make(cubeWidth);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
uint8_t blurAmount = beatsin8(2, 10, 128);
|
||||
uint8_t blurAmount = beatsin8(2, 10, 255);
|
||||
|
||||
#if FASTLED_VERSION >= 3001000
|
||||
blur2d(effects.leds, VPANEL_W, VPANEL_H, blurAmount);
|
||||
|
@ -164,8 +164,8 @@ class PatternCube : public Drawable {
|
|||
#endif
|
||||
|
||||
zCamera = beatsin8(2, 100, 140);
|
||||
AngxSpeed = beatsin8(3, 1, 6) / 100.0f;
|
||||
AngySpeed = effects.beatcos8(5, 1, 6) / 100.0f;
|
||||
AngxSpeed = beatsin8(3, 1, 10) / 100.0f;
|
||||
AngySpeed = beatcos8(5, 1, 10) / 100.0f;
|
||||
|
||||
// Update values
|
||||
Angx += AngxSpeed;
|
||||
|
@ -188,7 +188,7 @@ class PatternCube : public Drawable {
|
|||
{
|
||||
e = edge + i;
|
||||
if (!e->visible) {
|
||||
effects.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ class PatternCube : public Drawable {
|
|||
e = edge + i;
|
||||
if (e->visible)
|
||||
{
|
||||
effects.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -39,9 +39,6 @@ class PatternElectricMandala : public Drawable {
|
|||
int16_t dsx;
|
||||
int16_t dsy;
|
||||
|
||||
|
||||
unsigned int last_parameter_change_ms = 0;
|
||||
|
||||
public:
|
||||
PatternElectricMandala() {
|
||||
name = (char *)"ElectricMandala";
|
||||
|
@ -49,18 +46,18 @@ class PatternElectricMandala : public Drawable {
|
|||
|
||||
void start() {
|
||||
// set to reasonable values to avoid a black out
|
||||
effects.noisesmoothing = 200;
|
||||
noisesmoothing = 200;
|
||||
|
||||
// just any free input pin
|
||||
//random16_add_entropy(analogRead(18));
|
||||
|
||||
// fill coordinates with random values
|
||||
// set zoom levels
|
||||
effects.noise_x = random16();
|
||||
effects.noise_y = random16();
|
||||
effects.noise_z = random16();
|
||||
effects.noise_scale_x = 6000;
|
||||
effects.noise_scale_y = 6000;
|
||||
noise_x = random16();
|
||||
noise_y = random16();
|
||||
noise_z = random16();
|
||||
noise_scale_x = 6000;
|
||||
noise_scale_y = 6000;
|
||||
|
||||
// for the random movement
|
||||
dx = random8();
|
||||
|
@ -73,20 +70,19 @@ class PatternElectricMandala : public Drawable {
|
|||
unsigned int drawFrame() {
|
||||
#if FASTLED_VERSION >= 3001000
|
||||
// a new parameter set every 15 seconds
|
||||
if(millis() - last_parameter_change_ms > 15000) {
|
||||
last_parameter_change_ms = millis();
|
||||
EVERY_N_SECONDS(15) {
|
||||
//SetupRandomPalette3();
|
||||
dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too
|
||||
dx = random16(500) - 250;
|
||||
dz = random16(500) - 250;
|
||||
effects.noise_scale_x = random16(10000) + 2000;
|
||||
effects.noise_scale_y = random16(10000) + 2000;
|
||||
noise_scale_x = random16(10000) + 2000;
|
||||
noise_scale_y = random16(10000) + 2000;
|
||||
}
|
||||
#endif
|
||||
|
||||
effects.noise_y += dy;
|
||||
effects.noise_x += dx;
|
||||
effects.noise_z += dz;
|
||||
noise_y += dy;
|
||||
noise_x += dx;
|
||||
noise_z += dz;
|
||||
|
||||
effects.FillNoise();
|
||||
ShowNoiseLayer(0, 1, 0);
|
||||
|
@ -104,7 +100,7 @@ class PatternElectricMandala : public Drawable {
|
|||
for (uint16_t i = 0; i < VPANEL_W; i++) {
|
||||
for (uint16_t j = 0; j < VPANEL_H; j++) {
|
||||
|
||||
uint8_t color = effects.noise[i][j];
|
||||
uint8_t color = noise[i][j];
|
||||
|
||||
uint8_t bri = color;
|
||||
|
118
examples/ChainedPanelsAuroraDemo/PatternFire.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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
|
109
examples/ChainedPanelsAuroraDemo/PatternFireKoz.h
Normal file
|
@ -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
|
125
examples/ChainedPanelsAuroraDemo/PatternFlock.h
Normal file
|
@ -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 <http://www.shiffman.net>
|
||||
// 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
|
|
@ -37,7 +37,6 @@ class PatternFlowField : public Drawable {
|
|||
|
||||
static const int count = 40;
|
||||
|
||||
unsigned long last_update_hue_ms = 0;
|
||||
byte hue = 0;
|
||||
|
||||
void start() {
|
||||
|
@ -67,7 +66,7 @@ class PatternFlowField : public Drawable {
|
|||
boid->velocity.y = -((float)cos8(angle) * 0.0078125 - 1.0);
|
||||
boid->update();
|
||||
|
||||
effects.setPixel(boid->location.x, boid->location.y, effects.ColorFromCurrentPalette(angle + hue)); // color
|
||||
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) {
|
||||
|
@ -76,8 +75,7 @@ class PatternFlowField : public Drawable {
|
|||
}
|
||||
}
|
||||
|
||||
if (millis() - last_update_hue_ms > 200) {
|
||||
last_update_hue_ms = millis();
|
||||
EVERY_N_MILLIS(200) {
|
||||
hue++;
|
||||
}
|
||||
|
|
@ -31,21 +31,19 @@ class PatternIncrementalDrift : public Drawable {
|
|||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
//uint8_t dim = beatsin8(2, 230, 250);
|
||||
effects.DimAll(250);
|
||||
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 = effects.beatcos8((17 - i) * 2, effects.getCenterX() - i, effects.getCenterX() + i);
|
||||
uint8_t y = beatsin8((17 - i) * 2, effects.getCenterY() - i, effects.getCenterY() + i);
|
||||
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.setPixel(x, y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
|
@ -43,18 +43,18 @@ class PatternIncrementalDrift2 : public Drawable {
|
|||
uint8_t y = 0;
|
||||
|
||||
if (i < 16) {
|
||||
x = effects.beatcos8((i + 1) * 2, i, VPANEL_W - i);
|
||||
x = beatcos8((i + 1) * 2, i, VPANEL_W - i);
|
||||
y = beatsin8((i + 1) * 2, i, VPANEL_H - i);
|
||||
color = effects.ColorFromCurrentPalette(i * 14);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = beatsin8((32 - i) * 2, VPANEL_W - i, i + 1);
|
||||
y = effects.beatcos8((32 - i) * 2, VPANEL_H - i, i + 1);
|
||||
y = beatcos8((32 - i) * 2, VPANEL_H - i, i + 1);
|
||||
color = effects.ColorFromCurrentPalette((31 - i) * 14);
|
||||
}
|
||||
|
||||
effects.setPixel(x, y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
|
||||
}
|
||||
|
||||
return 0;
|
61
examples/ChainedPanelsAuroraDemo/PatternInfinity.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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
|
||||
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 250);
|
||||
// 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);
|
||||
|
||||
effects.ShowFrame();
|
||||
return 30;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
154
examples/ChainedPanelsAuroraDemo/PatternInvaders.h
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Aurora: https://github.com/pixelmatix/aurora
|
||||
* Copyright (c) 2014 Jason Coon
|
||||
*
|
||||
* Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator
|
||||
*
|
||||
* 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 PatternInvaders_H
|
||||
#define PatternInvaders_H
|
||||
|
||||
class PatternInvadersSmall : public Drawable {
|
||||
private:
|
||||
uint8_t x = 1;
|
||||
uint8_t y = 1;
|
||||
|
||||
public:
|
||||
PatternInvadersSmall() {
|
||||
name = (char *)"Invaders Small";
|
||||
}
|
||||
|
||||
void start() {
|
||||
matrix->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) color = color1;
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color);
|
||||
|
||||
if (i < 2)
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color);
|
||||
}
|
||||
}
|
||||
|
||||
x += 6;
|
||||
if (x > 25) {
|
||||
x = 1;
|
||||
y += 6;
|
||||
}
|
||||
|
||||
if (y > 25) y = x = 1;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 125;
|
||||
}
|
||||
};
|
||||
|
||||
class PatternInvadersMedium : public Drawable {
|
||||
private:
|
||||
uint8_t x = 0;
|
||||
uint8_t y = 0;
|
||||
|
||||
public:
|
||||
PatternInvadersMedium() {
|
||||
name = (char *)"Invaders Medium";
|
||||
}
|
||||
|
||||
void start() {
|
||||
matrix->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) color = color1;
|
||||
|
||||
matrix->fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
|
||||
|
||||
if (i < 2)
|
||||
matrix->fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
|
||||
}
|
||||
}
|
||||
|
||||
x += 11;
|
||||
if (x > 22) {
|
||||
x = 0;
|
||||
y += 11;
|
||||
}
|
||||
|
||||
if (y > 22) y = x = 0;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 500;
|
||||
}
|
||||
};
|
||||
|
||||
class PatternInvadersLarge : public Drawable {
|
||||
private:
|
||||
|
||||
public:
|
||||
PatternInvadersLarge() {
|
||||
name = (char *)"Invaders Large";
|
||||
}
|
||||
|
||||
void start() {
|
||||
matrix->fillScreen(0);
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
matrix->fillScreen(0);
|
||||
|
||||
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
|
||||
|
||||
for (int x = 0; x < 3; x++) {
|
||||
for (int y = 0; y < 5; y++) {
|
||||
CRGB color = CRGB::Black;
|
||||
|
||||
if (random(0, 2) == 1) {
|
||||
color = color1;
|
||||
}
|
||||
|
||||
matrix->fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
|
||||
|
||||
if (x < 2)
|
||||
matrix->fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
|
||||
}
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 2000;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
129
examples/ChainedPanelsAuroraDemo/PatternLife.h
Normal file
|
@ -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
|
|
@ -175,7 +175,7 @@ private:
|
|||
|
||||
Point imagePoint = createPoint(point.x * 2, point.y * 2);
|
||||
|
||||
//effects.setPixel(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray));
|
||||
//effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray));
|
||||
|
||||
shuffleDirections();
|
||||
|
||||
|
@ -191,7 +191,7 @@ private:
|
|||
|
||||
Point newImagePoint = imagePoint.Move(direction);
|
||||
|
||||
effects.setPixel(newImagePoint.x, newImagePoint.y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(newImagePoint.x, newImagePoint.y, color);
|
||||
|
||||
cellCount++;
|
||||
cells[cellCount - 1] = newPoint;
|
||||
|
@ -204,7 +204,7 @@ private:
|
|||
if (index > -1) {
|
||||
Point finishedPoint = cells[index];
|
||||
imagePoint = createPoint(finishedPoint.x * 2, finishedPoint.y * 2);
|
||||
effects.setPixel(imagePoint.x, imagePoint.y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, color);
|
||||
|
||||
removeCell(index);
|
||||
}
|
|
@ -45,7 +45,7 @@ public:
|
|||
effects.leds[XY16(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black;
|
||||
|
||||
// The below is more pleasant
|
||||
// effects.leds[XY16(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ;
|
||||
// effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,8 +54,8 @@ public:
|
|||
byte x2 = 8 + sin8(counter * 2) / 16;
|
||||
byte y2 = 8 + cos8((counter * 2) / 3) / 16;
|
||||
|
||||
effects.leds[XY16(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
effects.leds[XY16(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128);
|
||||
effects.leds[XY(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
effects.leds[XY(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128);
|
||||
|
||||
// Noise
|
||||
noise_x += 1000;
|
||||
|
@ -87,13 +87,13 @@ public:
|
|||
|
||||
byte xx = 4 + sin8(millis() / 9) / 10;
|
||||
byte yy = 4 + cos8(millis() / 10) / 10;
|
||||
effects.leds[XY16(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
|
||||
xx = 8 + sin8(millis() / 10) / 16;
|
||||
yy = 8 + cos8(millis() / 7) / 16;
|
||||
effects.leds[XY16(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80);
|
||||
effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80);
|
||||
|
||||
effects.leds[XY16(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160);
|
||||
effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160);
|
||||
|
||||
noise_x += 1000;
|
||||
noise_y += 1000;
|
||||
|
@ -125,7 +125,7 @@ public:
|
|||
effects.DimAll(235); effects.ShowFrame();
|
||||
|
||||
for (uint8_t i = 3; i < 32; i = i + 4) {
|
||||
effects.leds[XY16(i, 15)] += effects.ColorFromCurrentPalette(i * 8);
|
||||
effects.leds[XY(i, 15)] += effects.ColorFromCurrentPalette(i * 8);
|
||||
}
|
||||
|
||||
// Noise
|
||||
|
@ -159,7 +159,7 @@ public:
|
|||
//CLS();
|
||||
effects.DimAll(235); effects.ShowFrame();
|
||||
|
||||
effects.leds[XY16(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
|
||||
|
||||
|
||||
// Noise
|
||||
|
@ -194,7 +194,7 @@ public:
|
|||
|
||||
|
||||
for (uint8_t i = 3; i < 32; i = i + 4) {
|
||||
effects.leds[XY16(i, 31)] += effects.ColorFromCurrentPalette(i * 8);
|
||||
effects.leds[XY(i, 31)] += effects.ColorFromCurrentPalette(i * 8);
|
||||
}
|
||||
|
||||
// Noise
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
for (uint8_t y = 1; y < 32; y = y + 6) {
|
||||
for (uint8_t x = 1; x < 32; x = x + 6) {
|
||||
|
||||
effects.leds[XY16(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4);
|
||||
effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
// draw a rainbow color palette
|
||||
for (uint8_t y = 0; y < VPANEL_H; y++) {
|
||||
for (uint8_t x = 0; x < VPANEL_W; x++) {
|
||||
effects.leds[XY16(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7);
|
||||
effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ public:
|
|||
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[XY16(x, y)] += rainbow[c];
|
||||
effects.leds[XY(x, y)] += rainbow[c];
|
||||
}
|
||||
|
||||
y++;
|
|
@ -38,7 +38,7 @@
|
|||
#define AMP_BPM 2
|
||||
#define SKEW_BPM 4
|
||||
#define WAVE_TIMEMINSKEW VPANEL_W/8
|
||||
#define WAVE_TIMEMAXSKEW effects.getCenterX()
|
||||
#define WAVE_TIMEMAXSKEW VPANEL_W/2
|
||||
|
||||
class PatternPendulumWave : public Drawable {
|
||||
public:
|
||||
|
@ -46,9 +46,8 @@ class PatternPendulumWave : public Drawable {
|
|||
name = (char *)"Pendulum Wave";
|
||||
}
|
||||
|
||||
unsigned int drawFrame()
|
||||
{
|
||||
effects.DimAll(192);
|
||||
unsigned int drawFrame() {
|
||||
effects.ClearFrame();
|
||||
|
||||
for (int x = 0; x < VPANEL_W; ++x)
|
||||
{
|
||||
|
@ -57,7 +56,7 @@ class PatternPendulumWave : public Drawable {
|
|||
|
||||
uint8_t y = beatsin16(WAVE_BPM, 0, amp, x*beatsin16(SKEW_BPM, WAVE_TIMEMINSKEW, WAVE_TIMEMAXSKEW)) + offset;
|
||||
|
||||
effects.setPixel(x, y, effects.ColorFromCurrentPalette(x * 7));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7));
|
||||
}
|
||||
effects.ShowFrame();
|
||||
return 20;
|
|
@ -45,7 +45,7 @@ public:
|
|||
v += cos16(y * (128 - wibble) * 6 + time);
|
||||
v += sin16(y * x * cos8(-time) / 8);
|
||||
|
||||
effects.setPixelFromPaletteIndex(x, y, (v >> 8) + 127);
|
||||
effects.Pixel(x, y, (v >> 8) + 127);
|
||||
}
|
||||
}
|
||||
|
82
examples/ChainedPanelsAuroraDemo/PatternPulse.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Aurora: https://github.com/pixelmatix/aurora
|
||||
* Copyright (c) 2014 Jason Coon
|
||||
*
|
||||
* Based at least in part on someone else's work that I can no longer find.
|
||||
* Please let me know if you recognize any of this code!
|
||||
*
|
||||
* 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 PatternPulse_H
|
||||
#define PatternPulse_H
|
||||
|
||||
class PatternPulse : public Drawable {
|
||||
private:
|
||||
int hue;
|
||||
int centerX = 0;
|
||||
int centerY = 0;
|
||||
int step = -1;
|
||||
int maxSteps = 16;
|
||||
float fadeRate = 0.8;
|
||||
int diff;
|
||||
|
||||
public:
|
||||
PatternPulse() {
|
||||
name = (char *)"Pulse";
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
effects.DimAll(235);
|
||||
|
||||
if (step == -1) {
|
||||
centerX = random(32);
|
||||
centerY = random(32);
|
||||
hue = random(256); // 170;
|
||||
step = 0;
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue));
|
||||
step++;
|
||||
}
|
||||
else {
|
||||
if (step < maxSteps) {
|
||||
// initial pulse
|
||||
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
|
||||
|
||||
// secondary pulse
|
||||
if (step > 3) {
|
||||
matrix.drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
|
||||
}
|
||||
step++;
|
||||
}
|
||||
else {
|
||||
step = -1;
|
||||
}
|
||||
}
|
||||
|
||||
effects.standardNoiseSmearing();
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 30;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
56
examples/ChainedPanelsAuroraDemo/PatternRadar.h
Normal file
|
@ -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
|
|
@ -27,10 +27,6 @@
|
|||
#define PatternSimplexNoise_H
|
||||
|
||||
class PatternSimplexNoise : public Drawable {
|
||||
|
||||
private:
|
||||
|
||||
unsigned int last_update_ms = 0;
|
||||
public:
|
||||
PatternSimplexNoise() {
|
||||
name = (char *)"Noise";
|
||||
|
@ -38,19 +34,18 @@ class PatternSimplexNoise : public Drawable {
|
|||
|
||||
void start() {
|
||||
// Initialize our coordinates to some random values
|
||||
effects.noise_x = random16();
|
||||
effects.noise_y = random16();
|
||||
effects.noise_z = random16();
|
||||
noise_x = random16();
|
||||
noise_y = random16();
|
||||
noise_z = random16();
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
#if FASTLED_VERSION >= 3001000
|
||||
// a new parameter set every 15 seconds
|
||||
if(millis() - last_update_ms > 15000) {
|
||||
last_update_ms = millis();
|
||||
effects.noise_x = random16();
|
||||
effects.noise_y = random16();
|
||||
effects.noise_z = random16();
|
||||
EVERY_N_SECONDS(15) {
|
||||
noise_x = random16();
|
||||
noise_y = random16();
|
||||
noise_z = random16();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -60,8 +55,8 @@ class PatternSimplexNoise : public Drawable {
|
|||
ShowNoiseLayer(0, 1, 0);
|
||||
|
||||
// noise_x += speed;
|
||||
effects.noise_y += speed;
|
||||
effects.noise_z += speed;
|
||||
noise_y += speed;
|
||||
noise_z += speed;
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
|
@ -72,7 +67,7 @@ class PatternSimplexNoise : public Drawable {
|
|||
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
|
||||
for (uint16_t i = 0; i < VPANEL_W; i++) {
|
||||
for (uint16_t j = 0; j < VPANEL_H; j++) {
|
||||
uint8_t pixel = effects.noise[i][j];
|
||||
uint8_t pixel = noise[i][j];
|
||||
|
||||
// assign a color depending on the actual palette
|
||||
effects.leds[XY16(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel);
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class PatternSnake : public Drawable {
|
||||
private:
|
||||
static const byte SNAKE_LENGTH = 8;
|
||||
static const byte SNAKE_LENGTH = 16;
|
||||
|
||||
CRGB colors[SNAKE_LENGTH];
|
||||
uint8_t initialHue;
|
||||
|
@ -96,7 +96,7 @@ private:
|
|||
|
||||
void draw(CRGB colors[SNAKE_LENGTH]) {
|
||||
for (byte i = 0; i < SNAKE_LENGTH; i++) {
|
||||
effects.leds[XY16(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH));
|
||||
effects.leds[XY(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH));
|
||||
}
|
||||
}
|
||||
};
|
113
examples/ChainedPanelsAuroraDemo/PatternSpark.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PatternSpark_H
|
||||
#define PatternSpark_H
|
||||
|
||||
class PatternSpark : public Drawable {
|
||||
private:
|
||||
|
||||
public:
|
||||
PatternSpark() {
|
||||
name = (char *)"Spark";
|
||||
}
|
||||
|
||||
// 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
|
||||
uint8_t 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.
|
||||
uint8_t sparking = 50;
|
||||
|
||||
unsigned int drawFrame() {
|
||||
// Add entropy to random number generator; we use a lot of it.
|
||||
random16_add_entropy( random16());
|
||||
|
||||
effects.DimAll(235); effects.ShowFrame();
|
||||
|
||||
for (uint8_t 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) {
|
||||
uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3);
|
||||
|
||||
int xy = XY(xt, 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, 240);
|
||||
|
||||
// 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(3);
|
||||
effects.MoveFractionalNoiseX(4);
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 15;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
100
examples/ChainedPanelsAuroraDemo/PatternSpin.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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 PatternSpin_H
|
||||
|
||||
|
||||
|
||||
class PatternSpin : public Drawable {
|
||||
public:
|
||||
PatternSpin() {
|
||||
name = (char *)"Spin";
|
||||
}
|
||||
|
||||
float degrees = 0;
|
||||
float radius = 16;
|
||||
|
||||
float speedStart = 1;
|
||||
float velocityStart = 0.6;
|
||||
|
||||
float maxSpeed = 30;
|
||||
|
||||
float speed = speedStart;
|
||||
float velocity = velocityStart;
|
||||
|
||||
void start() {
|
||||
speed = speedStart;
|
||||
velocity = velocityStart;
|
||||
degrees = 0;
|
||||
}
|
||||
|
||||
unsigned int drawFrame() {
|
||||
effects.DimAll(190); effects.ShowFrame();
|
||||
|
||||
CRGB color = effects.ColorFromCurrentPalette(speed * 8);
|
||||
|
||||
// start position
|
||||
int x;
|
||||
int y;
|
||||
|
||||
// target position
|
||||
float targetDegrees = degrees + speed;
|
||||
float targetRadians = radians(targetDegrees);
|
||||
int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians));
|
||||
int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians));
|
||||
|
||||
float tempDegrees = degrees;
|
||||
|
||||
do{
|
||||
float radians = radians(tempDegrees);
|
||||
x = (int) (MATRIX_CENTER_X + radius * cos(radians));
|
||||
y = (int) (MATRIX_CENTER_Y - radius * sin(radians));
|
||||
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
|
||||
effects.drawBackgroundFastLEDPixelCRGB(y, x, color);
|
||||
|
||||
tempDegrees += 1;
|
||||
if (tempDegrees >= 360)
|
||||
tempDegrees = 0;
|
||||
} while (x != targetX || y != targetY);
|
||||
|
||||
degrees += speed;
|
||||
|
||||
// add velocity to the particle each pass around the accelerator
|
||||
if (degrees >= 360) {
|
||||
degrees = 0;
|
||||
speed += velocity;
|
||||
if (speed <= speedStart) {
|
||||
speed = speedStart;
|
||||
velocity *= -1;
|
||||
}
|
||||
else if (speed > maxSpeed){
|
||||
speed = maxSpeed - velocity;
|
||||
velocity *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -30,21 +30,17 @@ class PatternSpiro : public Drawable {
|
|||
|
||||
uint8_t radiusx = VPANEL_W / 4;
|
||||
uint8_t radiusy = VPANEL_H / 4;
|
||||
uint8_t minx = effects.getCenterX() - radiusx;
|
||||
uint8_t maxx = effects.getCenterX() + radiusx + 1;
|
||||
uint8_t miny = effects.getCenterY() - radiusy;
|
||||
uint8_t maxy = effects.getCenterY() + radiusy + 1;
|
||||
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 = 64;
|
||||
uint8_t spirocount = 1;
|
||||
uint8_t spirooffset = 256 / spirocount;
|
||||
boolean spiroincrement = true;
|
||||
|
||||
boolean handledChange = false;
|
||||
|
||||
unsigned long last_update_theta1_ms = 0;
|
||||
unsigned long last_update_hue_ms = 0;
|
||||
unsigned long last_update_frame_ms = 0;
|
||||
|
||||
public:
|
||||
PatternSpiro() {
|
||||
name = (char *)"Spiro";
|
||||
|
@ -55,34 +51,31 @@ class PatternSpiro : public Drawable {
|
|||
};
|
||||
|
||||
unsigned int drawFrame() {
|
||||
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 64);
|
||||
blur2d(effects.leds, VPANEL_W > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, 192);
|
||||
|
||||
boolean change = false;
|
||||
|
||||
for (int i = 0; i < spirocount; i++) {
|
||||
uint8_t x = effects.mapsin8(theta1 + i * spirooffset, minx, maxx);
|
||||
uint8_t y = effects.mapcos8(theta1 + i * spirooffset, miny, maxy);
|
||||
uint8_t x = mapsin8(theta1 + i * spirooffset, minx, maxx);
|
||||
uint8_t y = mapcos8(theta1 + i * spirooffset, miny, maxy);
|
||||
|
||||
uint8_t x2 = effects.mapsin8(theta2 + i * spirooffset, x - radiusx, x + radiusx);
|
||||
uint8_t y2 = effects.mapcos8(theta2 + i * spirooffset, y - radiusy, y + radiusy);
|
||||
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[XY16(x2, y2)] += color;
|
||||
effects.leds[XY(x2, y2)] += color;
|
||||
|
||||
if((x2 == effects.getCenterX() && y2 == effects.getCenterY()) ||
|
||||
(x2 == effects.getCenterX() && y2 == effects.getCenterY())) change = true;
|
||||
if((x2 == MATRIX_CENTER_X && y2 == MATRIX_CENTER_Y) ||
|
||||
(x2 == MATRIX_CENTRE_X && y2 == MATRIX_CENTRE_Y)) change = true;
|
||||
}
|
||||
|
||||
theta2 += 1;
|
||||
|
||||
if (millis() - last_update_theta1_ms > 25) {
|
||||
last_update_theta1_ms = millis();
|
||||
EVERY_N_MILLIS(25) {
|
||||
theta1 += 1;
|
||||
}
|
||||
|
||||
if (millis() - last_update_frame_ms > 100) {
|
||||
last_update_frame_ms = millis();
|
||||
|
||||
EVERY_N_MILLIS(100) {
|
||||
if (change && !handledChange) {
|
||||
handledChange = true;
|
||||
|
||||
|
@ -107,8 +100,7 @@ class PatternSpiro : public Drawable {
|
|||
if(!change) handledChange = false;
|
||||
}
|
||||
|
||||
if (millis() - last_update_hue_ms > 33) {
|
||||
last_update_hue_ms = millis();
|
||||
EVERY_N_MILLIS(33) {
|
||||
hueoffset += 1;
|
||||
}
|
||||
|
79
examples/ChainedPanelsAuroraDemo/PatternSwirl.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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() {
|
||||
effects.ClearFrame();
|
||||
}
|
||||
|
||||
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 > 255 ? 255 : VPANEL_W, VPANEL_H > 255 ? 255 : VPANEL_H, blurAmount);
|
||||
#else
|
||||
effects.DimAll(blurAmount);
|
||||
#endif
|
||||
|
||||
// Use two out-of-sync sine waves
|
||||
uint8_t i = beatsin8(256/VPANEL_H, borderWidth, VPANEL_W - borderWidth);
|
||||
uint8_t j = beatsin8(2048/VPANEL_W, borderWidth, VPANEL_H - borderWidth);
|
||||
|
||||
// Also calculate some reflections
|
||||
uint8_t ni = (VPANEL_W - 1) - i;
|
||||
uint8_t nj = (VPANEL_H - 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); // this doesn't work for non-square matrices
|
||||
effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17);
|
||||
//effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29); // this doesn't work for non-square matrices
|
||||
effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37);
|
||||
effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41);
|
||||
|
||||
|
||||
effects.ShowFrame();
|
||||
return 0;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -60,42 +60,42 @@ public:
|
|||
case 0:
|
||||
for (int x = 0; x < VPANEL_W; x++) {
|
||||
n = quadwave8(x * 2 + theta) / scale;
|
||||
effects.setPixel(x, n, effects.ColorFromCurrentPalette(x + hue));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue));
|
||||
if (waveCount == 2)
|
||||
effects.setPixel(x, maxY - n, effects.ColorFromCurrentPalette(x + hue));
|
||||
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.setPixel(n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
if (waveCount == 2)
|
||||
effects.setPixel(maxX - n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
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.setPixel(x, n, effects.ColorFromCurrentPalette(x + hue));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue));
|
||||
if (waveCount == 2)
|
||||
effects.setPixel(x, maxY - n, effects.ColorFromCurrentPalette(x + hue));
|
||||
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.setPixel(n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
if (waveCount == 2)
|
||||
effects.setPixel(maxX - n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
effects.DimAll(220);
|
||||
|
||||
effects.DimAll(254);
|
||||
effects.ShowFrame();
|
||||
|
||||
if (thetaUpdate >= thetaUpdateFrequency) {
|
||||
thetaUpdate = 0;
|
||||
|
@ -113,8 +113,6 @@ public:
|
|||
hueUpdate++;
|
||||
}
|
||||
|
||||
effects.ShowFrame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
297
examples/ChainedPanelsAuroraDemo/Patterns.h
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "PatternTest.h"
|
||||
//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSpiro.h"
|
||||
#include "PatternRadar.h"
|
||||
#include "PatternSwirl.h"
|
||||
#include "PatternPendulumWave.h"
|
||||
#include "PatternFlowField.h"
|
||||
#include "PatternIncrementalDrift.h"
|
||||
#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternMunch.h"
|
||||
#include "PatternElectricMandala.h"
|
||||
//#include "PatternSpin.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSimplexNoise.h"
|
||||
#include "PatternWave.h"
|
||||
#include "PatternAttract.h"
|
||||
//#include "PatternBounce.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternFlock.h"
|
||||
#include "PatternInfinity.h"
|
||||
#include "PatternPlasma.h"
|
||||
#include "PatternSnake.h"
|
||||
#include "PatternInvaders.h"
|
||||
//#include "PatternCube.h" // Doesn't seem to work, omitting.
|
||||
//#include "PatternFire.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternLife.h"
|
||||
#include "PatternMaze.h"
|
||||
//#include "PatternPulse.h" // Doesn't seem to work, omitting.
|
||||
//#include "PatternSpark.h" // Doesn't seem to work, omitting.
|
||||
#include "PatternSpiral.h"
|
||||
|
||||
class Patterns : public Playlist {
|
||||
private:
|
||||
PatternTest patternTest;
|
||||
// PatternRainbowFlag rainbowFlag; // doesn't work
|
||||
// PatternPaletteSmear paletteSmear;
|
||||
// PatternMultipleStream multipleStream; // doesn't work
|
||||
// PatternMultipleStream2 multipleStream2; // doesn't work
|
||||
// PatternMultipleStream3 multipleStream3; // doesn't work
|
||||
// PatternMultipleStream4 multipleStream4; // doesn't work
|
||||
// PatternMultipleStream5 multipleStream5; // doesn't work
|
||||
// PatternMultipleStream8 multipleStream8; // doesn't work
|
||||
PatternSpiro spiro;
|
||||
// PatternRadar radar;
|
||||
PatternSwirl swirl;
|
||||
PatternPendulumWave pendulumWave;
|
||||
PatternFlowField flowField;
|
||||
PatternIncrementalDrift incrementalDrift;
|
||||
PatternIncrementalDrift2 incrementalDrift2;
|
||||
PatternMunch munch;
|
||||
PatternElectricMandala electricMandala;
|
||||
// PatternSpin spin;
|
||||
PatternSimplexNoise simplexNoise;
|
||||
PatternWave wave;
|
||||
PatternAttract attract;
|
||||
// PatternBounce bounce;
|
||||
PatternFlock flock;
|
||||
PatternInfinity infinity;
|
||||
PatternPlasma plasma;
|
||||
PatternInvadersSmall invadersSmall;
|
||||
// PatternInvadersMedium invadersMedium;
|
||||
// PatternInvadersLarge invadersLarge;
|
||||
PatternSnake snake;
|
||||
// PatternCube cube;
|
||||
// PatternFire fire;
|
||||
PatternLife life;
|
||||
PatternMaze maze;
|
||||
// PatternPulse pulse;
|
||||
// PatternSpark spark;
|
||||
PatternSpiral spiral;
|
||||
|
||||
int currentIndex = 0;
|
||||
Drawable* currentItem;
|
||||
|
||||
int getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
const static int PATTERN_COUNT = 14;
|
||||
|
||||
Drawable* shuffledItems[PATTERN_COUNT];
|
||||
|
||||
Drawable* items[PATTERN_COUNT] = {
|
||||
// &patternTest, // ok
|
||||
&spiro, // cool
|
||||
// &paletteSmear, // fail
|
||||
// &multipleStream, // fail
|
||||
// &multipleStream8,// fail
|
||||
// &multipleStream5,// fail
|
||||
// &multipleStream3,// fail
|
||||
// &radar, // fail
|
||||
// &multipleStream4, // fail
|
||||
// &multipleStream2, // fail
|
||||
&life, // ok
|
||||
&flowField,
|
||||
&pendulumWave, //11 ok
|
||||
|
||||
&incrementalDrift, //12 ok
|
||||
&incrementalDrift2, // 13 fail
|
||||
&munch, // 14 ok
|
||||
// &electricMandala, // 15 ok, but ugly (vortigont)
|
||||
// &spin, // 16 ok but repetitive
|
||||
// &simplexNoise, // 17 - cool!
|
||||
// &wave, // 18 ok (can't work with 256+ matrix due to uint8_t vars)
|
||||
// &rainbowFlag, //20 // fail
|
||||
&attract, // 21 ok
|
||||
// &swirl, // 22 ok, but ugly (vortigont)
|
||||
// &bounce, // bouncing line crap
|
||||
&flock, // works
|
||||
&infinity, // works
|
||||
&plasma, // works
|
||||
// &invadersSmall, // works ish, but ugly (vortigont)
|
||||
// &invadersMedium, // fail
|
||||
// &invadersLarge, // fail
|
||||
&snake, // ok
|
||||
// &cube, // works ish
|
||||
// &fire, // ok ish
|
||||
&maze, // ok
|
||||
// &pulse,// fail
|
||||
// &spark, // same as fire
|
||||
&spiral, // ok
|
||||
};
|
||||
|
||||
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("}");
|
||||
}
|
||||
|
||||
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
|
39
examples/ChainedPanelsAuroraDemo/Playlist.h
Normal file
|
@ -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
|
169
examples/ChainedPanelsAuroraDemo/Vector.h
Normal file
|
@ -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 T>
|
||||
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<float> PVector;
|
||||
|
||||
#endif
|
|
@ -30,8 +30,8 @@ void setup() {
|
|||
HUB75_I2S_CFG mxconfig(
|
||||
PANEL_RES_X, // Module width
|
||||
PANEL_RES_Y, // Module height
|
||||
PANEL_CHAIN // // chain length
|
||||
//,_pins // pin mapping -- uncomment if providing own custom pin mapping as per above.
|
||||
PANEL_CHAIN //, // chain length
|
||||
//_pins // pin mapping -- uncomment if providing own custom pin mapping as per above.
|
||||
);
|
||||
//mxconfig.clkphase = false;
|
||||
//mxconfig.driver = HUB75_I2S_CFG::FM6126A;
|
||||
|
|
158
examples/Julia_Set_Demo/Julia_Set_Demo.ino
Normal file
|
@ -0,0 +1,158 @@
|
|||
#define PANEL_RES_X 128 // Number of pixels wide of each INDIVIDUAL panel module.
|
||||
#define PANEL_RES_Y 64 // Number of pixels tall of each INDIVIDUAL panel module.
|
||||
#define PANEL_CHAIN 1 // Total number of panels chained one to another
|
||||
#define USE_FLOATHACK // To boost float performance, comment if this doesn't work.
|
||||
|
||||
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
|
||||
|
||||
MatrixPanel_I2S_DMA *dma_display = nullptr;
|
||||
|
||||
// inspired by
|
||||
// https://en.wikipedia.org/wiki/Fast_inverse_square_root
|
||||
#ifdef USE_FLOATHACK
|
||||
// cast float as int32_t
|
||||
int32_t intfloat(float n){ return *(int32_t *)&n; }
|
||||
// cast int32_t as float
|
||||
float floatint(int32_t n){ return *(float *)&n; }
|
||||
// fast approx sqrt(x)
|
||||
float floatsqrt(float n){ return floatint(0x1fbb4000+(intfloat(n)>>1)); }
|
||||
// fast approx 1/x
|
||||
float floatinv(float n){ return floatint(0x7f000000-intfloat(n)); }
|
||||
// fast approx log2(x)
|
||||
float floatlog2(float n){ return (float)((intfloat(n)<<1)-0x7f000000)*5.9604645e-08f; }
|
||||
#else
|
||||
float floatinv(float n){ return 1.f/n;}
|
||||
float floatsqrt(float n){ return std::sqrt(n); }
|
||||
float floatlog2(float n){ return std::log2f(n); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////
|
||||
// Escape time mandelbrot set function,
|
||||
// with arbitrary start point zx, zy
|
||||
// and arbitrary seed point ax, ay
|
||||
//
|
||||
// For julia set
|
||||
// zx = pos_x, zy = pos_y;
|
||||
// ax = seed_x, ay = seed_y;
|
||||
//
|
||||
// For mandelbrot set
|
||||
// zx = 0, zy = 0;
|
||||
// ax = pos_x, ay = pos_y;
|
||||
//
|
||||
const float bailOut = 4; // Escape radius
|
||||
const int32_t itmult = 1<<10; // Color speed
|
||||
//
|
||||
// https://en.wikipedia.org/wiki/Mandelbrot_set
|
||||
int32_t iteratefloat(float ax, float ay, float zx, float zy, uint16_t mxIT) {
|
||||
float zzl = 0;
|
||||
for (int it = 0; it<mxIT; it++) {
|
||||
float zzx = zx * zx;
|
||||
float zzy = zy * zy;
|
||||
// is the point is escaped?
|
||||
if(zzx+zzy>=bailOut){
|
||||
if(it>0){
|
||||
// calculate smooth coloring
|
||||
float zza = floatlog2(zzl);
|
||||
float zzb = floatlog2(zzx+zzy);
|
||||
float zzc = floatlog2(bailOut);
|
||||
float zzd = (zzc-zza)*floatinv(zzb-zza);
|
||||
return it*itmult+zzd*itmult;
|
||||
}
|
||||
};
|
||||
// z -> z*z + c
|
||||
zy = 2.f*zx*zy+ay;
|
||||
zx = zzx-zzy+ax;
|
||||
zzl = zzx+zzy;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float sint[256]; // precalculated sin table, for performance reasons
|
||||
|
||||
// Palette color taken from:
|
||||
// https://editor.p5js.org/Kouzerumatsukite/sketches/DwTiq9D01
|
||||
// color palette originally made by piano_miles, written in p5js
|
||||
// hsv2rgb(IT, cos(4096*it)/2+0.5, 1-sin(2048*it)/2-0.5)
|
||||
void drawPixelPalette(int x, int y, uint32_t m){
|
||||
float r = 0.f, g = 0.f, b = 0.f;
|
||||
if(m){
|
||||
char n = m>> 4 ;
|
||||
float l =abs(sint[m>> 2&255] )*255.f ;
|
||||
float s = (sint[m &255]+ 1.f)*0.5f ;
|
||||
r = (max(min(sint[n &255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
g = (max(min(sint[n+ 85&255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
b = (max(min(sint[n+170&255]+0.5f,1.f),0.f)*s+(1-s))*l;
|
||||
}
|
||||
dma_display->drawPixelRGB888(x,y,r,g,b);
|
||||
}
|
||||
|
||||
void drawCanvas() {
|
||||
uint32_t lastMicros = micros();
|
||||
double t = (double)lastMicros/8000000;
|
||||
double k = sin(t*3.212/2)*sin(t*3.212/2)/16+1;
|
||||
float cosk = (k-cos(t))/2;
|
||||
float xoff = (cos(t)*cosk+k/2-0.25);
|
||||
float yoff = (sin(t)*cosk );
|
||||
for(uint8_t y=0;y<PANEL_RES_Y;y++){
|
||||
for(uint8_t x=0;x<PANEL_RES_X;x++){
|
||||
uint32_t itcount = iteratefloat(xoff,yoff,((x-64)+1)/64.f,(y)/64.f,64);
|
||||
uint32_t itcolor = itcount?floatsqrt(itcount)*4+t*1024:0;
|
||||
drawPixelPalette(x,y,itcolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volatile int frameCounts=0;
|
||||
void Task1code(void *parameter){
|
||||
while(true){
|
||||
drawCanvas();
|
||||
delay(1);
|
||||
frameCounts++;
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
HUB75_I2S_CFG::i2s_pins _pins={
|
||||
// R1, G1, B1, R2, G2, B2, A, B, C, D, E,LAT, OE,CLK,
|
||||
25, 26, 27, 14, 12, 13, 23, 19, 5, 17, 18, 4, 15, 16,
|
||||
};
|
||||
HUB75_I2S_CFG mxconfig(
|
||||
PANEL_RES_X, // Module width
|
||||
PANEL_RES_Y, // Module height
|
||||
PANEL_CHAIN, // chain length
|
||||
_pins
|
||||
);
|
||||
|
||||
// Display Setup
|
||||
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
|
||||
dma_display->begin();
|
||||
dma_display->clearScreen();
|
||||
dma_display->setBrightness(64);
|
||||
setCpuFrequencyMhz(240);
|
||||
|
||||
for(int i=0;i<256;i++){
|
||||
sint[i] = sinf(i/256.f*2.f*PI);
|
||||
}
|
||||
|
||||
xTaskCreatePinnedToCore(\
|
||||
Task1code, /* Function to implement the task */\
|
||||
"Task1", /* Name of the task */\
|
||||
10000, /* Stack size in words */\
|
||||
NULL, /* Task input parameter */\
|
||||
4, /* Priority of the task */\
|
||||
NULL, /* Task handle. */\
|
||||
0); /* Core where the task should run */
|
||||
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
uint64_t lastMillis=0;
|
||||
void loop() {
|
||||
if(millis()-lastMillis>=1000){
|
||||
// log frame rate to serial
|
||||
Serial.print("fps: ");
|
||||
Serial.println(frameCounts);
|
||||
lastMillis += 1000;
|
||||
frameCounts=0;
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"name": "ESP32 HUB75 LED MATRIX PANEL DMA Display",
|
||||
"version": "3.0.12",
|
||||
"version": "3.0.10",
|
||||
"description": "An Adafruit GFX compatible library for LED matrix modules which uses DMA for ultra-fast refresh rates and therefore very low CPU usage.",
|
||||
"keywords": "hub75, esp32, esp32s2, esp32s3, display, dma, rgb matrix",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA.git"
|
||||
"url": "https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-DMA.git"
|
||||
},
|
||||
"authors": {
|
||||
"name": "MrCodetastic",
|
||||
"url": "https://github.com/mrcodetastic/"
|
||||
"name": "Mr Faptastic",
|
||||
"url": "https://github.com/mrfaptastic/"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
|
|