//heart in fire
//Fastled 16x16 rgb led matrix demo
//Yaroslaw Turbin, 25-01-2022
//https://twitter.com/ldir_ko
//https://www.reddit.com/user/ldirko/
//https://vk.com/ldirko
//https://www.youtube.com/c/ldirldir/

#include "FastLED.h"

// Matrix size
#define NUM_ROWS 16
#define NUM_COLS 16
#define NUM_LEDS NUM_ROWS * NUM_COLS

// LEDs pin
#define DATA_PIN 3

// LED brightness
#define BRIGHTNESS 255

// Define the array of leds
CRGB leds[NUM_LEDS];
CRGB chsvLut[256];
byte light_texture[32][32];

byte bump [16][16] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0b, 0x12, 0x18, 0x13, 0x10, 0x10, 0x15, 0x18, 0x12, 0x08, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0b, 0x1e, 0x26, 0x2c, 0x30, 0x2f, 0x30, 0x30, 0x2c, 0x26, 0x1b, 0x0b, 0x00, 0x00,
  0x00, 0x00, 0x17, 0x26, 0x32, 0x39, 0x3e, 0x41, 0x42, 0x3e, 0x39, 0x31, 0x26, 0x15, 0x00, 0x00,
  0x00, 0x00, 0x1c, 0x2d, 0x39, 0x3f, 0x43, 0x47, 0x47, 0x44, 0x3f, 0x37, 0x2d, 0x1a, 0x00, 0x00,
  0x00, 0x00, 0x18, 0x2e, 0x38, 0x41, 0x47, 0x46, 0x46, 0x45, 0x40, 0x38, 0x2c, 0x16, 0x00, 0x00,
  0x00, 0x00, 0x09, 0x26, 0x36, 0x3e, 0x43, 0x46, 0x46, 0x42, 0x3f, 0x35, 0x25, 0x08, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0b, 0x28, 0x38, 0x3e, 0x41, 0x42, 0x3f, 0x37, 0x28, 0x09, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x0d, 0x2c, 0x38, 0x3c, 0x3c, 0x37, 0x2a, 0x0b, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x2d, 0x34, 0x34, 0x2c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x2b, 0x29, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  generateCHSVlut();
}

void generateCHSVlut() {
  for (int j = 0; j < 256; j++)
    // chsvLut[j]=CHSV(100,255,j);  //for one color
    chsvLut[j] = HeatColor(j / 1.4); //256 pallette color
}

void textGener() {
  int a = millis() / 2;
  for (int x = 0; x < 32; x++) {
    for (int y = 0; y < 32; y++) {
      byte red = qsub8 (inoise8 (x * 20, y * 10 + a), abs8(y - (32 - 1)) * 255 / (32 + 7));
      light_texture[x][y] = red;
    }
  }
}

void Bumpmap(int8_t lightx, int8_t lighty) {
  int8_t vly = lighty;
  for (int y = 1; y < 15; y++) {
    ++vly;
    int8_t vlx = lightx;
    for (int x = 1; x < 15; x++) {
      ++vlx;

      int8_t nx = bump[y][x] - bump[y][x - 1];
      int8_t ny = bump[y][x] - bump[y - 1][x];

      // int8_t nx = bump[y][x+1] - bump[y][x - 1];
      // int8_t ny = bump[y+1][x] - bump[y - 1][x];

      byte difx = abs8(vlx - nx / 4);
      byte dify = abs8(vly - ny / 4);

      byte col = light_texture[difx & 31][dify & 31]; 

      leds[XY(x, y)] = chsvLut[col]; 
    }
  }
}

void loop() {

  int8_t lightX = 8;
  int8_t lightY = 6;

  textGener();

  Bumpmap(lightX, lightY);
  FastLED.show();
}

uint16_t XY (uint8_t x, uint8_t y) {
  return (y * NUM_COLS + x); //simple function to find led number in led matrix,
}