PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.5KB

  1. #ifndef PLASMA_CLOUD_H__
  2. #define PLASMA_CLOUD_H__
  3. #include <Arduino.h>
  4. #include "ILI9341_t3.h"
  5. #include "MathUtil.h"
  6. #include "BaseAnimation.h"
  7. const float PLASMA_CLOUD_SPEED = 0.02;
  8. const uint_fast16_t PLASMA_CLOUD_MARGIN = 25;
  9. const uint_fast8_t PLASMA_CLOUD_LINE_WIDTH = 8;
  10. const uint_fast8_t PLASMA_CLOUD_STEP_Y = 4;
  11. const float PLASMA_COLOR_CYCLE_SPEED = 0.003;
  12. const uint_fast8_t SQRT_TABLE_LENGTH = 255;
  13. uint_fast8_t sqrtTable[ SQRT_TABLE_LENGTH ];
  14. uint_fast8_t sqrtBitShift; // Shift distances (integers) this many bits. This will give you a lookup index to get the square root.
  15. class PlasmaCloud : public BaseAnimation {
  16. public:
  17. PlasmaCloud() : BaseAnimation() {};
  18. void init( ILI9341_t3 tft );
  19. uint_fast16_t bgColor( void );
  20. String title();
  21. void perFrame( ILI9341_t3 tft, FrameParams frameParams );
  22. private:
  23. float _phase = 0;
  24. float _colorCycle = 0;
  25. uint_fast8_t _ditherY = 0;
  26. uint_fast16_t _bgColor;
  27. };
  28. void PlasmaCloud::init( ILI9341_t3 tft ) {
  29. _bgColor = tft.color565( 0x77, 0, 0xcc );
  30. float w = (float)tft.width();
  31. float h = (float)tft.height();
  32. float maxScreenDistance = (w*w) + (h*h);
  33. uint_fast8_t nextPow2 = ceil( log2f( maxScreenDistance ) );
  34. float maxTableDistance = pow( 2.0f, nextPow2 );
  35. sqrtBitShift = nextPow2 - 8;
  36. float sqrtTableMult = (float)0xff / sqrt(maxScreenDistance);
  37. for( uint_fast8_t i=0; i<SQRT_TABLE_LENGTH; i++ ) {
  38. float useDistance = ((float)i / (float)SQRT_TABLE_LENGTH) * maxTableDistance;
  39. float aSqrt = sqrt( useDistance );
  40. sqrtTable[i] = (uint_fast8_t)(aSqrt * sqrtTableMult);
  41. //sqrtTable[i] = random(0xff);
  42. }
  43. }
  44. uint_fast16_t PlasmaCloud::bgColor( void ) {
  45. return _bgColor;
  46. }
  47. String PlasmaCloud::title() {
  48. return "PlasmaCloud";
  49. }
  50. void PlasmaCloud::perFrame( ILI9341_t3 tft, FrameParams frameParams ) {
  51. uint_fast16_t w = (int_fast16_t)tft.width();
  52. uint_fast16_t h = (int_fast16_t)tft.height();
  53. _phase += frameParams.timeMult * PLASMA_CLOUD_SPEED * (1.0f + frameParams.audioMean*5.0f);
  54. _colorCycle -= frameParams.timeMult * PLASMA_COLOR_CYCLE_SPEED * (1.0f + frameParams.audioMean*6.0f);
  55. if( _colorCycle <= 0.0f ) _colorCycle += 1.0f;
  56. uint_fast8_t colorAdd = _colorCycle * 0xff;
  57. //py._ditherY = (py._ditherY + 1) % PLASMA_YELLOW_DITHER;
  58. PointU16 p0 = (PointU16){
  59. (uint_fast16_t)(w/2 + (sin(_phase*0.32f)*(w/2-PLASMA_CLOUD_MARGIN) )),
  60. (uint_fast16_t)(h/2 + (sin(_phase*0.23f)*(h/2-PLASMA_CLOUD_MARGIN) ))
  61. };
  62. PointU16 p1 = (PointU16){
  63. (uint_fast16_t)(w/2 + (cos(_phase*1.07f)*(w/2-PLASMA_CLOUD_MARGIN) )),
  64. (uint_fast16_t)(h/2 + (cos(_phase*1.42f)*(h/2-PLASMA_CLOUD_MARGIN) ))
  65. };
  66. /*
  67. PointU16 p2 = (PointU16){
  68. (uint_fast16_t)(w/2 + (cos(_phase*0.57f)*(w/2-PLASMA_CLOUD_MARGIN) )),
  69. (uint_fast16_t)(h/2 + (cos(_phase*0.81f)*(h/2-PLASMA_CLOUD_MARGIN) ))
  70. };
  71. */
  72. for( uint_fast16_t x=0; x<w; x+=PLASMA_CLOUD_LINE_WIDTH ) {
  73. for( uint_fast16_t y=_ditherY; y<h; y+=PLASMA_CLOUD_STEP_Y ) {
  74. PointU8 d0 = (PointU8){ abs(p0.x - x), abs(p0.y - y) };
  75. PointU8 d1 = (PointU8){ abs(p1.x - x), abs(p1.y - y) };
  76. //PointU8 d2 = (PointU8){ abs(p2.x - x), abs(p2.y - y) };
  77. uint_fast8_t lookup0 = (d0.x*d0.x + d0.y*d0.y) >> sqrtBitShift;
  78. uint_fast8_t lookup1 = (d1.x*d1.x + d1.y*d1.y) >> sqrtBitShift;
  79. //uint_fast8_t lookup2 = (d2.x*d2.x + d2.y*d2.y) >> sqrtBitShift;
  80. uint_fast8_t bright = (sqrtTable[ lookup0 ] * sqrtTable[ lookup1 ] ) >> 6;
  81. bright = (uint_fast16_t)(bright + colorAdd) & 0xff;
  82. uint_fast16_t color = tft.color565( ((bright&0xfb)<<2), 0, bright );
  83. tft.drawFastHLine( x, y, PLASMA_CLOUD_LINE_WIDTH, color );
  84. }
  85. }
  86. _ditherY = (_ditherY + 1) % PLASMA_CLOUD_STEP_Y;
  87. }
  88. #endif