pchestna

L3D Cube noise mirrored

Dec 27th, 2014
474
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.32 KB | None | 0 0
  1. #include<FastLED.h>
  2.  
  3. #define LED_PIN     2
  4. #define BRIGHTNESS  32
  5. #define LED_TYPE    WS2812B
  6. #define COLOR_ORDER GRB
  7.  
  8. const uint8_t kCubeSize = 8;
  9. const bool    kMatrixSerpentineLayout = false;
  10.  
  11. typedef enum {X_LAYER, Y_LAYER, Z_LAYER} LAYER;
  12. typedef enum {UP, DOWN} DIRECTION;
  13. bool bAnimate = false;
  14.  
  15. // Dictates the direction of the frames
  16. DIRECTION fillDirection = UP;
  17. // Which axis are we filling the frames
  18. LAYER layer = Y_LAYER;
  19. // Which frame number gets the new noise data
  20. int nFillFrame;
  21.  
  22. #define NUM_LEDS (kCubeSize * kCubeSize * kCubeSize)
  23. #define MAX_DIMENSION kCubeSize
  24.  
  25. // The leds
  26. CRGB leds[NUM_LEDS];
  27.  
  28. // The 16 bit version of our coordinates
  29. static uint16_t x;
  30. static uint16_t y;
  31. static uint16_t z;
  32.  
  33. // This example combines two features of FastLED to produce a remarkable range of
  34. // effects from a relatively small amount of code.  This example combines FastLED's
  35. // color palette lookup functions with FastLED's Perlin/simplex noise generator, and
  36. // the combination is extremely powerful.
  37. //
  38. // You might want to look at the "ColorPalette" and "Noise" examples separately
  39. // if this example code seems daunting.
  40. //
  41. // The basic setup here is that for each frame, we generate a new array of
  42. // 'noise' data, and then map it onto the LED matrix through a color palette.
  43. //
  44. // Periodically, the color palette is changed, and new noise-generation parameters
  45. // are chosen at the same time.  In this example, specific noise-generation
  46. // values have been selected to match the given color palettes; some are faster,
  47. // or slower, or larger, or smaller than others, but there's no reason these
  48. // parameters can't be freely mixed-and-matched.
  49. //
  50. // In addition, this example includes some fast automatic 'data smoothing' at
  51. // lower noise speeds to help produce smoother animations in those cases.
  52. //
  53. // The FastLED built-in color palettes (Forest, Clouds, Lava, Ocean, Party) are
  54. // used, as well as some 'hand-defined' ones, and some proceedurally generated
  55. // palettes.
  56.  
  57. // We're using the x/y dimensions to map to the x/y pixels on the matrix.  We'll
  58. // use the z-axis for "time".  speed determines how fast time moves forward.  Try
  59. // 1 for a very slow moving effect, or 60 for something that ends up looking like
  60. // water.
  61. uint16_t speed = 1; // speed is set dynamically once we've started up
  62.  
  63. // Scale determines how far apart the pixels in our noise matrix are.  Try
  64. // changing these values around to see how it affects the motion of the display.  The
  65. // higher the value of scale, the more "zoomed out" the noise will be.  A value
  66. // of 1 will be so zoomed in, you'll mostly see solid colors.
  67. uint16_t scale = 30; // scale is set dynamically once we've started up
  68.  
  69. // This is the array that we keep our computed noise values in
  70. uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
  71.  
  72. CRGBPalette16 currentPalette( LavaColors_p );
  73. uint8_t       colorLoop = 1;
  74.  
  75. void setup() {
  76.   delay(3000);
  77.   LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS);
  78.   LEDS.setBrightness(BRIGHTNESS);
  79.  
  80.   // Initialize our coordinates to some random values
  81.   x = random16();
  82.   y = random16();
  83.   z = random16();
  84.  
  85.   if (fillDirection == UP) nFillFrame = 0; else nFillFrame = kCubeSize-1;
  86. }
  87.  
  88. // Fill a frame of the x/y array of 8-bit noise values using the inoise8 function.
  89. void fillnoise8() {
  90.   // If we're runing at a low "speed", some 8-bit artifacts become visible
  91.   // from frame-to-frame.  In order to reduce this, we can do some fast data-smoothing.
  92.   // The amount of data smoothing we're doing depends on "speed".
  93.   uint8_t dataSmoothing = 0;
  94.   if( speed < 50) {
  95.     dataSmoothing = 200 - (speed * 4);
  96.   }
  97.  
  98.   for(int i = 0; i < MAX_DIMENSION; i++) {
  99.     int ioffset = scale * i;
  100.     for(int j = 0; j < MAX_DIMENSION; j++) {
  101.       int joffset = scale * j;
  102.      
  103.       uint8_t data = inoise8(x + ioffset,y + joffset,z);
  104.  
  105.       // The range of the inoise8 function is roughly 16-238.
  106.       // These two operations expand those values out to roughly 0..255
  107.       // You can comment them out if you want the raw noise data.
  108.       data = qsub8(data,16);
  109.       data = qadd8(data,scale8(data,39));
  110.  
  111.       if( dataSmoothing ) {
  112.         uint8_t olddata = noise[i][j];
  113.         uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing);
  114.         data = newdata;
  115.       }
  116.      
  117.       noise[i][j] = data;
  118.     }
  119.   }
  120.  
  121.   z += speed;
  122.  
  123.   // apply slow drift to X and Y, just for visual variation.
  124.   x += speed / 8;
  125.   y -= speed / 16;
  126. }
  127.  
  128. void mapNoiseToLEDsUsingPalette()
  129. {
  130.   static uint8_t ihue=0;
  131.  
  132.   for(int i = 0; i < kCubeSize; i++) {
  133.     for(int j = 0; j < kCubeSize; j++) {
  134.       // We use the value at the (i,j) coordinate in the noise
  135.       // array for our brightness, and the flipped value from (j,i)
  136.       // for our pixel's index into the color palette.
  137.  
  138.       uint8_t index = noise[j][i];
  139.       uint8_t bri =   noise[i][j];
  140.  
  141.       // if this palette is a 'loop', add a slowly-changing base value
  142.       if( colorLoop) {
  143.         index += ihue;
  144.       }
  145.  
  146.       // brighten up, as the color palette itself often contains the
  147.       // light/dark dynamic range desired
  148.       if( bri > 127 ) {
  149.         bri = 255;
  150.       } else {
  151.         bri = dim8_raw( bri * 2);
  152.       }
  153.  
  154.       CRGB color = ColorFromPalette( currentPalette, index, bri);
  155.      
  156.       static int nTo;
  157.       switch (layer)
  158.       {
  159.          case X_LAYER:
  160.            nTo = XYZ(nFillFrame, i, j);
  161.          break;
  162.          case Y_LAYER:
  163.            nTo = XYZ(i, nFillFrame, j);
  164.          break;
  165.          case Z_LAYER:
  166.            nTo = XYZ(i, j, nFillFrame);
  167.          break;
  168.       }
  169.       leds[nTo] = color;
  170.     }
  171.   }
  172.  
  173.   ihue+=1;
  174. }
  175.  
  176. // Copies pixels from one layer to another
  177. void copyLayer(uint8_t fromLayer, uint8_t toLayer);
  178. void copyLayer(uint8_t fromLayer, uint8_t toLayer)
  179. {
  180.   int nFrom; // from pixel
  181.   int nTo; // to pixel
  182.  
  183.   for (int m = 0; m < kCubeSize; m++)
  184.     for (int n = 0; n < kCubeSize; n++)
  185.     {
  186.       switch (layer)
  187.       {
  188.          case X_LAYER:
  189.            nFrom = XYZ(fromLayer, m, n);
  190.            nTo = XYZ(toLayer, m, n);
  191.          break;
  192.          case Y_LAYER:
  193.            nFrom = XYZ(m, fromLayer, n);
  194.            nTo = XYZ(m, toLayer, n);
  195.          break;
  196.          case Z_LAYER:
  197.            nFrom = XYZ(m, n, fromLayer);
  198.            nTo = XYZ(m, n, toLayer);
  199.          break;
  200.       }
  201.       leds[nTo] = leds[nFrom];
  202.     }
  203. }
  204.  
  205. // Copy frames foward in the plane being used from the fillFrame back
  206. void moveFrameForward()
  207. {
  208.   switch (fillDirection)
  209.   {
  210.     case UP:
  211.     {
  212.       for (int nLayer = kCubeSize-1; nLayer > 0; nLayer--)
  213.       {
  214.         if (bAnimate)
  215.           copyLayer(nLayer-1, nLayer);
  216.         else
  217.           copyLayer(nFillFrame, nLayer);
  218.       }
  219.     }
  220.     break;
  221.    
  222.     case DOWN:
  223.     {
  224.       for (int nLayer = 0; nLayer < kCubeSize; nLayer++)
  225.       {
  226.         if (bAnimate)
  227.           copyLayer(nLayer+1, nLayer);
  228.         else
  229.           copyLayer(nFillFrame, nLayer);
  230.       }
  231.     }
  232.     break;
  233.   }
  234. }
  235.  
  236. void loop() {
  237.   // Periodically choose a new palette, speed, and scale
  238.   //ChangePaletteAndSettingsPeriodically();
  239.  
  240.   // generate noise data
  241.   fillnoise8();
  242.  
  243.   // convert the noise data to colors in the LED array
  244.   // using the current palette
  245.   mapNoiseToLEDsUsingPalette();
  246.  
  247.   if (bAnimate)
  248.   {
  249.     LEDS.show();
  250.     delay(10);
  251.     // Copy frames into time after showing
  252.     moveFrameForward();
  253.   }
  254.   else
  255.   {
  256.     // mirror to other frames before show
  257.     moveFrameForward();
  258.     LEDS.show();
  259.     delay(10);
  260.   }
  261. }
  262.  
  263.  
  264.  
  265. // There are several different palettes of colors demonstrated here.
  266. //
  267. // FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
  268. // OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
  269. //
  270. // Additionally, you can manually define your own color palettes, or you can write
  271. // code that creates color palettes on the fly.
  272.  
  273. // 1 = 5 sec per palette
  274. // 2 = 10 sec per palette
  275. // etc
  276. #define HOLD_PALETTES_X_TIMES_AS_LONG 5
  277.  
  278. void ChangePaletteAndSettingsPeriodically()
  279. {
  280.   uint8_t secondHand = ((millis() / 1000) / HOLD_PALETTES_X_TIMES_AS_LONG) % 60;
  281.   static uint8_t lastSecond = 99;
  282.  
  283.   if( lastSecond != secondHand) {
  284.     lastSecond = secondHand;
  285.     if( secondHand ==  0)  { currentPalette = RainbowColors_p;         speed = 1; scale = 30; colorLoop = 1; }
  286.     if( secondHand ==  5)  { SetupPurpleAndGreenPalette();             speed = 1; scale = 50; colorLoop = 1; }
  287.     if( secondHand == 10)  { SetupBlackAndWhiteStripedPalette();       speed = 1; scale = 30; colorLoop = 1; }
  288.     if( secondHand == 15)  { currentPalette = ForestColors_p;          speed = 1; scale =120; colorLoop = 0; }
  289.     if( secondHand == 20)  { currentPalette = CloudColors_p;           speed = 1; scale = 30; colorLoop = 0; }
  290.     if( secondHand == 25)  { currentPalette = LavaColors_p;            speed = 1; scale = 50; colorLoop = 0; }
  291.     if( secondHand == 30)  { currentPalette = OceanColors_p;           speed = 1; scale = 90; colorLoop = 0; }
  292.     if( secondHand == 35)  { currentPalette = PartyColors_p;           speed = 1; scale = 30; colorLoop = 1; }
  293.     if( secondHand == 40)  { SetupRandomPalette();                     speed = 1; scale = 20; colorLoop = 1; }
  294.     if( secondHand == 45)  { SetupRandomPalette();                     speed = 1; scale = 50; colorLoop = 1; }
  295.     if( secondHand == 50)  { SetupRandomPalette();                     speed = 1; scale = 90; colorLoop = 1; }
  296.     if( secondHand == 55)  { currentPalette = RainbowStripeColors_p;   speed = 1; scale = 20; colorLoop = 1; }
  297.   }
  298. }
  299.  
  300. // This function generates a random palette that's a gradient
  301. // between four different colors.  The first is a dim hue, the second is
  302. // a bright hue, the third is a bright pastel, and the last is
  303. // another bright hue.  This gives some visual bright/dark variation
  304. // which is more interesting than just a gradient of different hues.
  305. void SetupRandomPalette()
  306. {
  307.   currentPalette = CRGBPalette16(
  308.                       CHSV( random8(), 255, 32),
  309.                       CHSV( random8(), 255, 255),
  310.                       CHSV( random8(), 128, 255),
  311.                       CHSV( random8(), 255, 255));
  312. }
  313.  
  314. // This function sets up a palette of black and white stripes,
  315. // using code.  Since the palette is effectively an array of
  316. // sixteen CRGB colors, the various fill_* functions can be used
  317. // to set them up.
  318. void SetupBlackAndWhiteStripedPalette()
  319. {
  320.   // 'black out' all 16 palette entries...
  321.   fill_solid( currentPalette, 16, CRGB::Black);
  322.   // and set every fourth one to white.
  323.   currentPalette[0] = CRGB::White;
  324.   currentPalette[4] = CRGB::White;
  325.   currentPalette[8] = CRGB::White;
  326.   currentPalette[12] = CRGB::White;
  327.  
  328. }
  329.  
  330. // This function sets up a palette of purple and green stripes.
  331. void SetupPurpleAndGreenPalette()
  332. {
  333.   CRGB purple = CHSV( HUE_PURPLE, 255, 255);
  334.   CRGB green  = CHSV( HUE_GREEN, 255, 255);
  335.   CRGB black  = CRGB::Black;
  336.  
  337.   currentPalette = CRGBPalette16(
  338.     green,  green,  black,  black,
  339.     purple, purple, black,  black,
  340.     green,  green,  black,  black,
  341.     purple, purple, black,  black );
  342. }
  343.  
  344. //
  345. // xyz coordinate mapping code
  346. //
  347. uint16_t XYZ( uint8_t x, uint8_t y, uint8_t z)
  348. {
  349.   uint16_t i;
  350.  
  351.   i = 8 * ((y * kCubeSize) + x) + z;
  352.  
  353.   if ((i >= 0) && (i <= 512))
  354.     return i;
  355.   else
  356.     return 0;
  357. }
Advertisement
Add Comment
Please, Sign In to add comment