//bumpmap

#define FASTER 1
#define TIMING 0

#include "FastLED.h"

// Matrix size
#define NUM_ROWS 32
#define NUM_COLS 32
#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];
byte bump[NUM_LEDS];
CRGB chsv[256];

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
	Serial.begin(1000000);
	for (int i = 0; i < 256; i++)
		chsv[i] = CHSV(120, 255, i);
}

void generatebump () {
  uint16_t t = millis() / 8;
  int index = 0;
  for (int j = 0; j < NUM_ROWS; j++) {
    for (int i = 0; i < NUM_COLS; i++) {
			byte col;
			uint16_t u, v; 
			u = i * 32 + t / 4;
			v = j * 32 - t / 5;
			if (!FASTER) {
				col = inoise8(u, v, t);
				col = map(col, 0, 255, 0,192);
			} else {
				col = 76 + inoise8_raw(u, v, t);
			}
      bump[index++] = col;
    }
  }
}

void Bumpmap(int8_t lightx, int8_t lighty) {

  int yindex = NUM_COLS;
  int8_t vly = lighty;

  for (int y = 1; y < NUM_ROWS - 1; y++) {
    ++vly;
    int8_t vlx = lightx;
    for (int x = 1; x < NUM_COLS - 1; x++) {
      ++vlx;
      int8_t nx = bump[x + 1 + yindex] - bump[x - 1 + yindex];
      int8_t ny = bump[x + yindex + NUM_COLS] - bump[x + yindex - NUM_COLS];
			if (!FASTER) {
				byte difx = abs8(vlx - nx);
				byte dify = abs8(vly - ny);
				int col = 255 - sqrt16(difx * difx + dify * dify) * 3;
				if (col < 0) col = 0;
				leds[XY(x, y)] = CHSV(120, 255, col);
			} else {
				uint16_t sumsquare = (vlx - nx) * (vlx - nx) + (vly - ny) * (vly - ny);
				byte col = 0;
				if (sumsquare < 7225) // 7225 == (255 / 3)²
					col = 255 - sqrt16(sumsquare) * 3;
				leds[XY(x, y)] = chsv[col];
			}
    }
    yindex += NUM_COLS;
  }
}

void loop() {

  int time = millis() / 8;
  int8_t lightX = 1 - (sin8(time / 3) - 128) / 4; // beatsin8(20,0,80); //
  int8_t lightY = 1 - (sin8(time / 2) - 128) / 4; // beatsin8(25,0,80); //

	unsigned long t1 = micros();
  generatebump ();
	unsigned long t2 = micros();
  Bumpmap(lightX, lightY);
	unsigned long t3 = micros();
  FastLED.show();

	if (TIMING) {
		static unsigned long t2_sum, t3_sum;
		t2_sum += t2 - t1;
		t3_sum += t3 - t2;
		static byte frame;
		if (!(++frame % 64)) {
			Serial.print("\ntotal\t\t");
			Serial.print(1000000.0 / FastLED.getFPS());
			Serial.print("\t");
			Serial.print(FastLED.getFPS());
			Serial.println(" FPS");
			Serial.print(F("generatebump()\t"));
			Serial.println(t2_sum / 64);
			Serial.print(F("Bumpmap()\t"));
			Serial.println(t3_sum / 64);
			Serial.print(F("FastLED.show()\t("));
			Serial.print(NUM_LEDS * 30 + 90);
			Serial.println(")");
			t2_sum = t3_sum = 0;
		}
	}
}

uint16_t XY (uint8_t x, uint8_t y) {
	//simple function to find led number in led matrix,
	if (y & 1)
  	return (y + 1) * NUM_COLS - 1 - x;
  return y * NUM_COLS + x;
}
//change this to your routine
//or generate XY function for your matrix there:
//https://macetech.github.io/FastLED-XY-Map-Generator/

FPS: 0
Power: 0.00W