Advertisement
Guest User

big cube demo code

a guest
Sep 4th, 2015
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 28.88 KB | None | 0 0
  1. #include <math.h>  
  2. #include "application.h"
  3.  
  4. // IMPORTANT: Set pixel COUNT, PIN and TYPE
  5. #define PIXEL_PIN D0
  6. #define totalPIXEL 4096
  7. #define stripPIXEL totalPIXEL/8    //THERE IS FOUR PINS TO DRIVE EACH STRIPS
  8. #define PIXEL_TYPE WS2812B
  9.  
  10. #define SIZE 16
  11. #define PI 3.14159
  12.  
  13.  
  14.  
  15. /**********************************
  16.  * flip variables *
  17.  * ********************************/
  18.  //accelerometer pinout
  19. #define X A0
  20. #define Y A1
  21. #define Z A6
  22. #define NUM_SAMPLES 100
  23. int accelerometer[3];
  24. unsigned long totals[3];
  25. int runningAverage[3];
  26. boolean whack[3];
  27. boolean whacked=false;
  28. #define WHACK_X 20
  29. #define WHACK_Y 20
  30. #define WHACK_Z 20
  31.  
  32. bool autoCycle=true;    //start on autocycle by default
  33.  
  34. /*******************************
  35.  * fade variables *
  36.  * ****************************/
  37. bool fading=false;
  38. int fadeValue=255;
  39. int fadeSpeed=2;
  40.  
  41. /*  datatype definitions
  42. */
  43.  
  44. /**   An RGB color. */
  45. struct Color
  46. {
  47.   unsigned char red, green, blue;
  48.  
  49.   Color(int r, int g, int b) : red(r), green(g), blue(b) {}
  50.   Color() : red(0), green(0), blue(0) {}
  51. };
  52.  
  53. /**   A point in 3D space.  */
  54. struct Point
  55. {
  56.   float x;
  57.   float y;
  58.   float z;
  59.   Point() : x(0), y(0), z(0) {}
  60.   Point(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
  61. };
  62.  
  63. struct Rocket
  64. {
  65.     float x,y,z;
  66.     float xVel, yVel, zVel;
  67.     float gravity;
  68.     Color col; 
  69.     Rocket():x((SIZE-1)/2), y(0), z((SIZE-1)/2), col(Color(255,0,0)){}
  70. };
  71.  
  72.  
  73. #define NUM_ROCKETS 50
  74. Rocket rockets[NUM_ROCKETS];
  75. float offset=0;
  76.  
  77. int y=0;
  78. int yinc=1;
  79. int maxBrightness=50;
  80.  
  81. #define FIREWORKS 0
  82. #define CIRCLES 1
  83. #define ROMAN_CANDLE 2
  84. #define FFT_JOY 3
  85.  
  86. int demo=FIREWORKS;
  87.  
  88. #define MICROPHONE A7
  89. #define GAIN_CONTROL D5
  90.  
  91. /*********************************
  92.  * FFTJoy variables *
  93.  * *******************************/
  94. #define M 5
  95. float real[(int)pow(2,M)];
  96. float imaginary[(int)pow(2,M)];
  97. float maxValue=0;
  98. float sample;
  99.  
  100.  
  101. /******************************
  102.  * fireworks variables *
  103.  * ****************************/
  104. int centerX, centerY, centerZ;
  105. int launchX, launchZ;
  106. int red, green, blue;
  107. float radius=0;
  108. float speed;
  109. bool showRocket;
  110. bool exploded;
  111. bool dead;
  112. float xInc, yInc, zInc;
  113. float rocketX, rocketY, rocketZ;
  114. float launchTime;
  115. int maxSize;
  116. int fireworkRes;
  117. Color rocketColor, fireworkColor;
  118.  
  119. uint8_t PIXEL_RGB[totalPIXEL*3];  //EACH PIXELS HAS 3 BYTES DATA
  120.  
  121. void setVoxel(int x, int y, int z, Color col);
  122. void setVoxel(Point p, Color col);
  123. Color getVoxel(int x, int y, int z);
  124. Color getVoxel(Point p);
  125. void line(Point p1, Point p2, Color col);
  126. void line(int x1, int y1, int z1, int x2, int y2, int z2, Color col);
  127. void sphere(Point center, float radius, Color col);
  128. void sphere(Point center, float radius, Color col, int res);
  129. void sphere(float x, float y, float z, float radius, Color col);
  130. void sphere(float x, float y, float z, float radius, Color col, int res);
  131. void background(Color col);
  132. Color colorMap(float val, float minVal, float maxVal);
  133. Color lerpColor(Color a, Color b, int val, int minVal, int maxVal);
  134. Point add(Point a, Point b);
  135.  
  136. #define DEMO_ROUTINES 4
  137.  
  138. int frame;
  139.  
  140. Point poly1[4];
  141. float poly1Angles[4];
  142. float poly1AnglesInc[4];
  143.  
  144. Point poly2[4];
  145. float poly2Angles[4];
  146. float poly2AnglesInc[4];
  147.  
  148. Point poly3[4];
  149. float poly3Angles[4];
  150. float poly3AnglesInc[4];
  151.  
  152. float poly1Color, poly2Color, poly3Color;
  153. float poly1ColorInc=0.001, poly2ColorInc=0.0005, poly3ColorInc=0.0007;
  154.  
  155. Point center;
  156. unsigned int lastDemo=0;
  157. #define DEMO_TIME 30000
  158. int timeout=0;
  159.  
  160. bool onlinePressed=false;
  161. bool lastOnline=true;
  162. SYSTEM_MODE(SEMI_AUTOMATIC);  //don't connect to the internet on boot
  163. #define BUTTON D6 //press this button to connect to the internet
  164. #define MODE D4
  165.  
  166. void setup()
  167. {
  168.     randomSeed(analogRead(A0));
  169.     Serial.begin(115200);
  170.       pinMode(GAIN_CONTROL, OUTPUT);
  171.       digitalWrite(GAIN_CONTROL, LOW);
  172.     initFireworks();
  173.     initCircles();
  174.     initRockets();
  175.     initCloudButton();
  176.     initAccelerometer();
  177.     pinMode(D0,OUTPUT);  //PB7
  178.     pinMode(D1,OUTPUT); //PB6
  179.     pinMode(D2,OUTPUT);  //BP5
  180.     pinMode(D3,OUTPUT);  //PB4
  181.     pinMode(A2,OUTPUT);  //PA4
  182.     pinMode(A3,OUTPUT); //PA5
  183.     pinMode(A4,OUTPUT);  //BA6
  184.     pinMode(A5,OUTPUT);  //PA7
  185.  
  186.     pinMode(D7, OUTPUT);
  187.     digitalWrite(D7, HIGH);
  188. }
  189.  
  190. //initializes the running average values for the accelerometer
  191. //I just set them to the first reading of the accelerometer on boot -- this is an imperfect method,
  192. //but it gets the rolling average very close it its eventual value
  193. //I chose to base it off of each cube's individual ADC reading, rather than hardcode the values from my sample cube
  194. void initAccelerometer()
  195. {
  196.     runningAverage[0]=analogRead(X);
  197.     runningAverage[1]=analogRead(Y);
  198.     runningAverage[2]=analogRead(Z);
  199. }
  200.  
  201. //sets up the online/offline switch
  202. void initCloudButton()
  203. {
  204.   //set the input mode for the 'connect to cloud' button
  205.   pinMode(BUTTON, INPUT_PULLUP);
  206.   pinMode(MODE, INPUT_PULLUP);
  207.     if(!digitalRead(MODE))  //if the wifi button is held down on boot, do a hard reset.  At any other time, keep the firmware, but try to add new wifi creds
  208.     {
  209.         WiFi.on();
  210.         WiFi.clearCredentials();
  211.         System.factoryReset();
  212.     }
  213.     //a.k.a. onlinePressed is HIGH when the switch is set to 'online' and LOW when the switch is set to 'offline'
  214.     onlinePressed=!digitalRead(BUTTON);
  215.     if(onlinePressed)
  216.         Particle.connect();
  217. }
  218.  
  219. //checks to see if the 'online/offline' switch is switched
  220. void checkCloudButton()
  221. {
  222.     //if the 'connect to cloud' button is pressed, try to connect to wifi.  
  223.     //otherwise, run the program
  224.     //note -- how does this behave when there are no wifi credentials loaded on the spark?
  225.  
  226.     //onlinePressed is HIGH when the switch is _not_ connected and LOW when the switch is connected
  227.     //a.k.a. onlinePressed is HIGH when the switch is set to 'online' and LOW when the switch is set to 'offline'
  228.     onlinePressed=!digitalRead(BUTTON);
  229.  
  230.     if((onlinePressed)&&(!lastOnline))  //marked as 'online'
  231.     {
  232.         lastOnline=onlinePressed;
  233.         Particle.connect();
  234.     }    
  235.  
  236.     else if((!onlinePressed)&&(lastOnline))  //marked as 'offline'
  237.     {
  238.         lastOnline=onlinePressed;
  239.         Particle.disconnect();
  240.     }
  241.  
  242.     lastOnline=onlinePressed;
  243.    
  244.     if(!digitalRead(MODE))
  245.         WiFi.listen();
  246. }
  247.  
  248.  
  249. void updateAccelerometer()
  250. {
  251.     accelerometer[0]=analogRead(X);
  252.     accelerometer[1]=analogRead(Y);
  253.     accelerometer[2]=analogRead(Z);
  254.     for(int i=0;i<3;i++)
  255.     {
  256.         totals[i]+=accelerometer[i];   
  257.         //sweet running average algorithm:  average[i+1]=average[i]+(sample[i]-average[i])/NUM_SAMPLES
  258.         //I average over 100 samples, or ~2.5 seconds
  259.         runningAverage[i]=runningAverage[i]+((accelerometer[i]-runningAverage[i])/NUM_SAMPLES);
  260.         whack[i]=false;
  261.     }  
  262.     if(abs(accelerometer[0]-runningAverage[0])>WHACK_X)
  263.         whack[0]=true;
  264.     if(abs(accelerometer[1]-runningAverage[1])>WHACK_Y)
  265.         whack[1]=true;
  266.     if(abs(accelerometer[2]-runningAverage[2])>WHACK_Z)
  267.         whack[2]=true;
  268.     whacked=whack[0] | whack[1] | whack[2];
  269. }
  270.  
  271. void initRockets()
  272. {
  273.     for(int i=0;i<NUM_ROCKETS;i++)
  274.     {
  275.         rockets[i].gravity=-0.01;
  276.         rockets[i].y=0;
  277.         rockets[i].x=center.x;
  278.         rockets[i].z=center.z;
  279.         rockets[i].col=Color(255,0,0); 
  280.         rockets[i].xVel=-.5;//(random(10)/10)-0.5;
  281.         rockets[i].yVel=0.25;//random(10)/10;
  282.         rockets[i].zVel=0.25;//(random(10)/10)-0.5;
  283.      }
  284. }
  285.  
  286. void initCircles()
  287. {
  288.     center=Point((SIZE-1)/2,(SIZE-1)/2,(SIZE-1)/2);
  289.     for(int i=0;i<4;i++)
  290.     {
  291.         poly1Angles[i]=random(6.28);
  292.         poly2Angles[i]=random(6.28);
  293.         poly3Angles[i]=random(6.28);
  294.     }
  295.     poly1AnglesInc[0]=random(10)/100 - 0.05;
  296.     poly1AnglesInc[1]=random(20)/100 - 0.1;
  297.     poly1AnglesInc[2]=random(10)/100 - 0.05;
  298.     poly1AnglesInc[3]=random(20)/100 - 0.1;
  299.  
  300.     poly2AnglesInc[0]=random(20)/100 - 0.1;
  301.     poly2AnglesInc[1]=random(20)/100 - 0.1;
  302.     poly2AnglesInc[2]=random(20)/100 - 0.1;
  303.     poly2AnglesInc[3]=random(20)/100 - 0.1;
  304.  
  305.     poly3AnglesInc[0]=random(20)/100 - 0.1;
  306.     poly3AnglesInc[1]=random(20)/100 - 0.1;
  307.     poly3AnglesInc[2]=random(20)/100 - 0.1;
  308.     poly3AnglesInc[3]=random(20)/100 - 0.1;
  309. }
  310.  
  311.  
  312. void romanCandle()
  313. {
  314.   background(Color(0,0,0));
  315.     for(int i=0;i<pow(2,M);i++)
  316.     {
  317.         real[i]=analogRead(MICROPHONE)-993;  //adapted for the 0.8v bias point of the big cube
  318.         delayMicroseconds(212);  
  319.         imaginary[i]=0;
  320.     }
  321.     FFT(1, M, real, imaginary);
  322.     for(int i=0;i<pow(2,M);i++)
  323.     {
  324.         imaginary[i]=sqrt(pow(imaginary[i],2)+pow(real[i],2));
  325.         if(imaginary[i]>maxValue)
  326.             maxValue=imaginary[i];
  327.     }
  328.     if(maxValue>100)
  329.         maxValue--;
  330.     int rocketsToFire=0;
  331.     for(int i=0;i<pow(2,M)/2;i++)
  332.     {
  333.         imaginary[i]=SIZE*imaginary[i]/maxValue;
  334.     if(imaginary[i]>SIZE/2)
  335.         rocketsToFire++;
  336.     }  
  337.  
  338.         for(int i=0;i<NUM_ROCKETS;i++)
  339.         {
  340.         rockets[i].yVel+=rockets[i].gravity;
  341.         rockets[i].x+=rockets[i].xVel;
  342.         rockets[i].y+=rockets[i].yVel;
  343.         rockets[i].z+=rockets[i].zVel;
  344.         if(rockets[i].col.green>5)
  345.             rockets[i].col.green-=5;
  346.         if(rockets[i].col.blue>5)
  347.             rockets[i].col.blue-=5;
  348.         /*
  349.         Serial.print(rockets[i].col.red);
  350.         Serial.print(" ");
  351.         Serial.print(rockets[i].col.green);
  352.         Serial.print(" ");
  353.         Serial.println(rockets[i].col.blue);
  354.         setVoxel(rockets[i].x,rockets[i].y,rockets[i].z,rockets[i].col);
  355.         */
  356.  
  357.         if(rocketsToFire>0)
  358.         if(rockets[i].y<0)
  359.         {
  360.         rocketsToFire--;
  361.         rockets[i].gravity=-0.01;
  362.         rockets[i].y=0;
  363.         rockets[i].x=center.x;
  364.         rockets[i].z=center.z;
  365.         rockets[i].col=Color(random(100),random(100),random(100));
  366.         rockets[i].xVel=(float)random(10)/10;//((float)random(10)/10)-0.5;
  367.         rockets[i].yVel=(float)random(10)/10;
  368.         rockets[i].zVel=((float)random(5)/10);
  369.         }
  370.         }
  371.         for(int i=0;i<(NUM_ROCKETS%2==0?NUM_ROCKETS:NUM_ROCKETS-1);i+=2)
  372.         line(rockets[i].x*cos(offset), rockets[i].y, rockets[i].z*sin(offset),rockets[i+1].x, rockets[i+1].y, rockets[i+1].z,rockets[i].col);
  373.         offset+=0.1;
  374.         mirror();
  375. }
  376.  
  377. void mirror()
  378. {
  379.     for(int x=center.x;x<SIZE;x++)
  380.         for(int y=0;y<SIZE;y++)
  381.             for(int z=center.z;z<SIZE;z++)
  382.             {
  383.                 setVoxel(center.x-(x-center.x),y,z, getVoxel(x,y,z));
  384.                 setVoxel(center.x-(x-center.x),y,center.z-(z-center.z), getVoxel(x,y,z));
  385.                 setVoxel(x,y,center.z-(z-center.z), getVoxel(x,y,z));
  386.             }
  387. }
  388. void loop()
  389. {    
  390.     //if the 'connect to cloud' button is pressed, try to connect to wifi.  
  391.     //otherwise, run the program
  392.     checkCloudButton();
  393.  
  394.  
  395.   if(fading)
  396.         fade();
  397.     else
  398.     {   switch(demo%DEMO_ROUTINES){
  399.    
  400.    case(FIREWORKS):
  401.     updateFireworks();
  402.    break;
  403.    
  404.    case(CIRCLES):
  405.       circles();
  406.    break;
  407.    
  408.    case(ROMAN_CANDLE):
  409.       romanCandle();
  410.    break;
  411.    
  412.    case(FFT_JOY):
  413.       fft_joy();
  414.    break;
  415.    }
  416.    frame++;    
  417.     }
  418.    show();
  419.    if(autoCycle)
  420.       if(millis()-lastDemo>DEMO_TIME)
  421.       {
  422.         fading=true;
  423.         demo++;
  424.         lastDemo=millis();
  425.       }
  426.  
  427.     if(fading)
  428.     {
  429.         fadeValue-=fadeSpeed;
  430.         //if we're done fading)
  431.         if(fadeValue<=0)
  432.         {
  433.             fading=false;
  434.             fadeValue=255;
  435.         }
  436.         else
  437.             fade();
  438.     }
  439.  
  440.    //uncomment to enable whack-to-change
  441.  
  442.   updateAccelerometer();
  443.  
  444.    if((whacked)&&((millis()-timeout)>250))
  445.    {
  446.     autoCycle=false;
  447.     fading=true;
  448.     demo++;
  449.     timeout=millis();
  450.     }
  451.  
  452. }
  453.  
  454. void fade()
  455. {
  456.     setFadeSpeed();
  457.     Color voxelColor;
  458.         for(int x=0;x<SIZE;x++)
  459.             for(int y=0;y<SIZE;y++)
  460.                 for(int z=0;z<SIZE;z++)
  461.                     {
  462.                         voxelColor=getVoxel(x,y,z);
  463.                         if(voxelColor.red>0)
  464.                             voxelColor.red--;
  465.                         if(voxelColor.green>0)
  466.                              voxelColor.green--;
  467.                         if(voxelColor.blue>0)
  468.                             voxelColor.blue--;
  469.                         setVoxel(x,y,z, voxelColor);    
  470.                     }
  471. }
  472.  
  473.  
  474.  
  475. /********************************************
  476.  *   FFT JOY functions
  477.  * *****************************************/
  478. void fft_joy(){
  479.     for(int i=0;i<pow(2,M);i++)
  480.     {
  481.         real[i]=analogRead(MICROPHONE)-993;  //adapted for the 0.8v bias point of the big cube
  482.         delayMicroseconds(212);  
  483.         imaginary[i]=0;
  484.     }
  485.     FFT(1, M, real, imaginary);
  486.     for(int i=0;i<pow(2,M);i++)
  487.     {
  488.         imaginary[i]=sqrt(pow(imaginary[i],2)+pow(real[i],2));
  489.         if(imaginary[i]>maxValue)
  490.             maxValue=imaginary[i];
  491.     }
  492.     if(maxValue>100)
  493.         maxValue--;
  494.     for(int i=0;i<pow(2,M)/2;i++)
  495.     {
  496.         imaginary[i]=SIZE*imaginary[i]/maxValue;
  497.         int y;
  498.         for(y=0;y<=imaginary[i];y++)
  499.             setVoxel(i,y,SIZE-1,colorMap(y,0,SIZE));
  500.         for(;y<SIZE;y++)
  501.             setVoxel(i,y,SIZE-1,Color(0,0,0));
  502.     }
  503.     for(int z=0;z<SIZE-1;z++)
  504.         for(int x=0;x<SIZE;x++)
  505.             for(int y=0;y<SIZE;y++)
  506.             {
  507.                 Color col=getVoxel(x,y,z+1);
  508.                 setVoxel(x,y,z,col);
  509.             }
  510.  
  511.     sample++;
  512.     if(sample>=pow(2,M))
  513.         sample-=pow(2,M);
  514. }
  515.  
  516. short FFT(short int dir,int m,float *x,float *y)
  517. {
  518.    int n,i,i1,j,k,i2,l,l1,l2;
  519.    float c1,c2,tx,ty,t1,t2,u1,u2,z;
  520.  
  521.    /* Calculate the number of points */
  522.    n = 1;
  523.    for (i=0;i<m;i++)
  524.       n *= 2;
  525.  
  526.    /* Do the bit reversal */
  527.    i2 = n >> 1;
  528.    j = 0;
  529.    for (i=0;i<n-1;i++) {
  530.       if (i < j) {
  531.          tx = x[i];
  532.          ty = y[i];
  533.          x[i] = x[j];
  534.          y[i] = y[j];
  535.          x[j] = tx;
  536.          y[j] = ty;
  537.       }
  538.       k = i2;
  539.       while (k <= j) {
  540.          j -= k;
  541.          k >>= 1;
  542.       }
  543.       j += k;
  544.    }
  545.  
  546.    /* Compute the FFT */
  547.    c1 = -1.0;
  548.    c2 = 0.0;
  549.    l2 = 1;
  550.    for (l=0;l<m;l++) {
  551.       l1 = l2;
  552.       l2 <<= 1;
  553.       u1 = 1.0;
  554.       u2 = 0.0;
  555.       for (j=0;j<l1;j++) {
  556.          for (i=j;i<n;i+=l2) {
  557.             i1 = i + l1;
  558.             t1 = u1 * x[i1] - u2 * y[i1];
  559.             t2 = u1 * y[i1] + u2 * x[i1];
  560.             x[i1] = x[i] - t1;
  561.             y[i1] = y[i] - t2;
  562.             x[i] += t1;
  563.             y[i] += t2;
  564.          }
  565.          z =  u1 * c1 - u2 * c2;
  566.          u2 = u1 * c2 + u2 * c1;
  567.          u1 = z;
  568.       }
  569.       c2 = sqrt((1.0 - c1) / 2.0);
  570.       if (dir == 1)
  571.          c2 = -c2;
  572.       c1 = sqrt((1.0 + c1) / 2.0);
  573.    }
  574.  
  575.    /* Scaling for forward transform */
  576.    if (dir == 1) {
  577.       for (i=0;i<n;i++) {
  578.          x[i] /= n;
  579.          y[i] /= n;
  580.       }
  581.    }
  582.  
  583.    return(0);
  584. }
  585.  
  586. void circles()
  587. {
  588.    background(Color(0,0,0));
  589.    poly1[0]=Point(center.x+(SIZE/2)*cos(poly1Angles[0]),0,center.z+(SIZE/2)*sin(poly1Angles[0]));
  590.    poly1[1]=Point(0,center.y+(SIZE/2)*cos(poly1Angles[1]),center.z+(SIZE/2)*sin(poly1Angles[1]));
  591.    poly1[2]=Point(center.x+(SIZE/2)*cos(poly1Angles[2]),SIZE-1,center.z+(SIZE/2)*sin(poly1Angles[2]));
  592.    poly1[3]=Point(SIZE-1,center.y+(SIZE/2)*cos(poly1Angles[3]),center.z+(SIZE/2)*sin(poly1Angles[3]));
  593.  
  594.    poly2[0]=Point(center.x+(SIZE/2)*cos(poly2Angles[0]),center.y+(SIZE/2)*sin(poly2Angles[0]),0);
  595.    poly2[1]=Point(SIZE-1,center.y+(SIZE/2)*cos(poly2Angles[1]),center.z+(SIZE/2)*sin(poly2Angles[1]));
  596.    poly2[2]=Point(center.x+(SIZE/2)*cos(poly2Angles[2]),center.y+(SIZE/2)*sin(poly2Angles[2]),SIZE-1);
  597.    poly2[3]=Point(0,center.y+(SIZE/2)*cos(poly2Angles[3]),center.z+(SIZE/2)*sin(poly2Angles[3]));
  598.  
  599.    poly3[0]=Point(center.x+(SIZE/2)*cos(poly3Angles[0]),0, center.z+(SIZE/2)*sin(poly3Angles[0]));
  600.    poly3[1]=Point(center.x+(SIZE/2)*cos(poly3Angles[1]),center.y+(SIZE/2)*cos(poly3Angles[1]),0);
  601.    poly3[2]=Point(center.x+(SIZE/2)*cos(poly3Angles[2]),SIZE-1, center.z+(SIZE/2)*sin(poly3Angles[2]));
  602.    poly3[3]=Point(center.x+(SIZE/2)*cos(poly3Angles[3]),center.y+(SIZE/2)*cos(poly3Angles[3]),SIZE-1);
  603.  
  604.    for(int i=0;i<4;i++)
  605.    {
  606.     poly1Angles[i]+=poly1AnglesInc[i];
  607.     poly2Angles[i]+=poly2AnglesInc[i];
  608.     poly3Angles[i]+=poly3AnglesInc[i];
  609.     float sin1=(float)255*sin(poly1Color);
  610.     float sin2=(float)255*sin(poly2Color);
  611.     float sin3=(float)255*sin(poly3Color);
  612.     line(poly1[i], poly1[(i+1)%4], Color(abs(sin1),0,0));
  613.     line(poly2[i], poly2[(i+1)%4], Color(0,0,abs(sin2)));
  614.     line(poly3[i], poly3[(i+1)%4], Color(0,abs(sin3),0));
  615.    }
  616.    poly1Color+=poly1ColorInc;
  617.    poly2Color+=poly2ColorInc;
  618.    poly3Color+=poly3ColorInc;
  619. }
  620.  
  621. void background(Color col)
  622. {
  623.     for(int x=0;x<SIZE;x++)
  624.         for(int y=0;y<SIZE;y++)
  625.             for(int z=0;z<SIZE;z++)
  626.                 setVoxel(x,y,z,col);
  627. }
  628.  
  629. void setVoxel(int x, int y, int z, Color col)
  630. {
  631.     if((x>=0)&&(x<SIZE))
  632.         if((y>=0)&&(y<SIZE))
  633.             if((z>=0)&&(z<SIZE))
  634.             {
  635.                 int index=z*256+x*16+y;
  636.                 PIXEL_RGB[index*3]=col.green;
  637.                 PIXEL_RGB[index*3+1]=col.red;
  638.                 PIXEL_RGB[index*3+2]=col.blue;
  639.             }
  640. }
  641.  
  642. void setVoxel(Point p, Color col)
  643. {
  644.     setVoxel(p.x, p.y, p.z, col);
  645. }
  646.  
  647. void line(Point p1, Point p2, Color col)
  648. {
  649.     line(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, col);
  650. }
  651.  
  652. void line(int x1, int y1, int z1, int x2, int y2, int z2, Color col)
  653. {
  654.   Point currentPoint;
  655.   currentPoint.x=x1;
  656.   currentPoint.y=y1;
  657.   currentPoint.z=z1;
  658.  
  659.   int dx = x2 - x1;
  660.   int dy = y2 - y1;
  661.   int dz = z2 - z1;
  662.   int x_inc = (dx < 0) ? -1 : 1;
  663.   int l = abs(dx);
  664.   int y_inc = (dy < 0) ? -1 : 1;
  665.   int m = abs(dy);
  666.   int z_inc = (dz < 0) ? -1 : 1;
  667.   int n = abs(dz);
  668.   int dx2 = l << 1;
  669.   int dy2 = m << 1;
  670.   int dz2 = n << 1;
  671.  
  672.   if((l >= m) && (l >= n)) {
  673.     int err_1 = dy2 - l;
  674.     int err_2 = dz2 - l;
  675.  
  676.     for(int i = 0; i < l; i++) {
  677.       setVoxel(currentPoint, col);
  678.  
  679.       if(err_1 > 0) {
  680.         currentPoint.y += y_inc;
  681.         err_1 -= dx2;
  682.       }
  683.  
  684.       if(err_2 > 0) {
  685.         currentPoint.z += z_inc;
  686.         err_2 -= dx2;
  687.       }
  688.  
  689.       err_1 += dy2;
  690.       err_2 += dz2;
  691.       currentPoint.x += x_inc;
  692.     }
  693.   } else if((m >= l) && (m >= n)) {
  694.     int err_1 = dx2 - m;
  695.     int err_2 = dz2 - m;
  696.  
  697.     for(int i = 0; i < m; i++) {
  698.       setVoxel(currentPoint, col);
  699.  
  700.       if(err_1 > 0) {
  701.         currentPoint.x += x_inc;
  702.         err_1 -= dy2;
  703.       }
  704.  
  705.       if(err_2 > 0) {
  706.         currentPoint.z += z_inc;
  707.         err_2 -= dy2;
  708.       }
  709.  
  710.       err_1 += dx2;
  711.       err_2 += dz2;
  712.       currentPoint.y += y_inc;
  713.     }
  714.   } else {
  715.     int err_1 = dy2 - n;
  716.     int err_2 = dx2 - n;
  717.  
  718.     for(int i = 0; i < n; i++) {
  719.       setVoxel(currentPoint, col);
  720.  
  721.       if(err_1 > 0) {
  722.         currentPoint.y += y_inc;
  723.         err_1 -= dz2;
  724.       }
  725.  
  726.       if(err_2 > 0) {
  727.         currentPoint.x += x_inc;
  728.         err_2 -= dz2;
  729.       }
  730.  
  731.       err_1 += dy2;
  732.       err_2 += dx2;
  733.       currentPoint.z += z_inc;
  734.     }
  735.   }
  736.  
  737.   setVoxel(currentPoint, col);
  738. }
  739.  
  740.  
  741. Point add(Point a, Point b)
  742. {
  743.     return Point(a.x+b.x, a.y+b.y, a.z+b.z);
  744. }
  745.  
  746. // draws a hollow  centered around the 'center' PVector, with radius
  747. // radius and color col
  748. void sphere(Point center, float radius, Color col) {
  749.      float res = 30;
  750.      for (float m = 0; m < res; m++)
  751.          for (float n = 0; n < res; n++)
  752.          setVoxel(center.x + radius * sin((float) PI * m / res) * cos((float) 2 * PI * n / res),
  753.               center.y + radius * sin((float) PI * m / res) * sin((float) 2 * PI * n / res),
  754.               center.z + radius * cos((float) PI * m / res),
  755.               col);
  756. }
  757.  
  758. // draws a hollow  centered around the 'center' PVector, with radius
  759. // radius and color col
  760. void sphere(Point center, float radius, Color col, int res) {
  761.      for (float m = 0; m < res; m++)
  762.          for (float n = 0; n < res; n++)
  763.          setVoxel(center.x + radius * sin((float) PI * m / res) * cos((float) 2 * PI * n / res),
  764.               center.y + radius * sin((float) PI * m / res) * sin((float) 2 * PI * n / res),
  765.               center.z + radius * cos((float) PI * m / res),
  766.               col);
  767. }
  768.  
  769. void sphere(float x, float y, float z, float radius, Color col) {
  770.      sphere(Point(x,y,z),radius, col);
  771. }
  772.  
  773. void sphere(float x, float y, float z, float radius, Color col, int res) {
  774.      sphere(Point(x,y,z),radius, col, res);
  775. }
  776.  
  777. void show(){
  778.     uint8_t *ptrA,*ptrB,*ptrC,*ptrD,*ptrE,*ptrF,*ptrG,*ptrH;
  779.     uint8_t mask;
  780.     uint8_t c=0,a=0,b=0,j=0;
  781.    
  782.     GPIOA->BSRRH=0xE0;    //set A3~A5 to low
  783.     GPIOB->BSRRH=0xF0;    //set D0~D4 to low
  784.     GPIOC->BSRRH=0x04;     //set A2 to low
  785.    
  786.     ptrA=&PIXEL_RGB[0];
  787.     ptrB=ptrA+stripPIXEL*3;
  788.     ptrC=ptrB+stripPIXEL*3;
  789.     ptrD=ptrC+stripPIXEL*3;
  790.     ptrE=ptrD+stripPIXEL*3;
  791.     ptrF=ptrE+stripPIXEL*3;
  792.     ptrG=ptrF+stripPIXEL*3;
  793.     ptrH=ptrG+stripPIXEL*3;
  794.    
  795.     delay(1);
  796.     __disable_irq();
  797.  
  798.     uint16_t i=stripPIXEL*3;   //3 BYTES = 1 PIXEL
  799.    
  800.     while(i) { // While bytes left... (3 bytes = 1 pixel)
  801.       i--;
  802.       mask = 0x80; // reset the mask
  803.       j=0;
  804.         // reset the 8-bit counter
  805.       do {
  806.         a=0;
  807.         b=0;
  808.         c=0;
  809.  
  810. //========Set D0~D4, i.e. B7~B4=======
  811.         if ((*ptrA)&mask) b|=0x10;// if masked bit is high
  812.     //    else "nop";
  813.         b<<=1;
  814.         if ((*ptrB)&mask) b|=0x10;// if masked bit is high
  815.     //    else "nop";
  816.         b<<=1;
  817.         if ((*ptrC)&mask) b|=0x10;// if masked bit is high
  818.     //    else "nop";
  819.         b<<=1;
  820.         if ((*ptrD)&mask) b|=0x10;// if masked bit is high
  821.    //     else "nop";
  822.  
  823. //=========Set A2, i.g. C2==========
  824.         if ((*ptrE)&mask) c|=0x04;// if masked bit is high
  825.    //     else "nop";
  826.    
  827.         GPIOA->BSRRL=0xE0;    //set A3~A5 to high
  828.         GPIOB->BSRRL=0xF0;    //set D0~D4 to high
  829.         GPIOC->BSRRL=0x04;    //set A2 to high
  830.        
  831.  
  832. //=========Set A3~A5, i.e. A5~A7========  
  833.         if ((*ptrF)&mask) a|=0x80;// if masked bit is high
  834.         // else "nop";
  835.         a>>=1;
  836.         if ((*ptrG)&mask) a|=0x80;// if masked bit is high
  837.    //     else "nop";
  838.         a>>=1;
  839.         if ((*ptrH)&mask) a|=0x80;// if masked bit is high
  840.  
  841.         a=(~a)&0xE0;
  842.         b=(~b)&0xF0;
  843.         c=(~c)&0x04;
  844.         GPIOA->BSRRH=a;
  845.         GPIOB->BSRRH=b;
  846.         GPIOC->BSRRH=c;
  847.         mask>>=1;
  848.          asm volatile(
  849.             "mov r0, r0" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  850.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  851.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  852.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  853.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  854.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  855.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  856.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  857.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  858.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  859.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  860.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  861.             "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t" "nop" "\n\t"
  862.             ::: "r0", "cc", "memory");
  863.         GPIOA->BSRRH=0xE0;    //set all to low
  864.         GPIOB->BSRRH=0xF0;    //set all to low
  865.         GPIOC->BSRRH=0x04;    //set all to low        
  866.           // WS2812 spec             700ns HIGH
  867.           // Adafruit on Arduino    (meas. 812ns)
  868.           // This lib on Spark Core (meas. 792ns)
  869.           /*
  870.         if(j<7) {
  871.           asm volatile(
  872.             "mov r0, r0" "\n\t"
  873.             ::: "r0", "cc", "memory");
  874.         }
  875.         */
  876.        
  877.       } while ( ++j < 8 ); // ...one color on a pixel done
  878.       ptrA++;
  879.       ptrB++;
  880.       ptrC++;
  881.       ptrD++;
  882.       ptrE++;
  883.       ptrF++;
  884.       ptrG++;
  885.       ptrH++;
  886.     } // end while(i) ... no more pixels
  887.     __enable_irq();    
  888. }
  889.  
  890.  
  891.  
  892. /** Map a value into a color.
  893.   The set of colors fades from blue to green to red and back again.
  894.  
  895.   @param val Value to map into a color.
  896.   @param minVal Minimum value that val will take.
  897.   @param maxVal Maximum value that val will take.
  898.  
  899.   @return Color from value.
  900. */
  901. Color colorMap(float val, float minVal, float maxVal)
  902. {
  903.   const float range = 1024;
  904.   val = range * (val-minVal) / (maxVal-minVal);
  905.  
  906.   Color colors[6];
  907.  
  908.   colors[0].red = 0;
  909.   colors[0].green = 0;
  910.   colors[0].blue = maxBrightness;
  911.  
  912.   colors[1].red = 0;
  913.   colors[1].green = maxBrightness;
  914.   colors[1].blue = maxBrightness;
  915.  
  916.   colors[2].red = 0;
  917.   colors[2].green = maxBrightness;
  918.   colors[2].blue = 0;
  919.  
  920.   colors[3].red = maxBrightness;
  921.   colors[3].green = maxBrightness;
  922.   colors[3].blue = 0;
  923.  
  924.   colors[4].red = maxBrightness;
  925.   colors[4].green = 0;
  926.   colors[4].blue = 0;
  927.  
  928.   colors[5].red = maxBrightness;
  929.   colors[5].green = 0;
  930.   colors[5].blue = maxBrightness;
  931.  
  932.   if(val <= range/6)
  933.     return lerpColor(colors[0], colors[1], val, 0, range/6);
  934.   else if(val <= 2 * range / 6)
  935.     return(lerpColor(colors[1], colors[2], val, range / 6, 2 * range / 6));
  936.   else if(val <= 3 * range / 6)
  937.     return(lerpColor(colors[2], colors[3], val, 2 * range / 6, 3*range / 6));
  938.   else if(val <= 4 * range / 6)
  939.     return(lerpColor(colors[3], colors[4], val, 3 * range / 6, 4*range / 6));
  940.   else if(val <= 5 * range / 6)
  941.     return(lerpColor(colors[4], colors[5], val, 4 * range / 6, 5*range / 6));
  942.   else
  943.     return(lerpColor(colors[5], colors[0], val, 5 * range / 6, range));
  944. }
  945.  
  946. /** Linear interpolation between colors.
  947.  
  948.   @param a, b The colors to interpolate between.
  949.   @param val Position on the line between color a and color b.
  950.   When equal to min the output is color a, and when equal to max the output is color b.
  951.   @param minVal Minimum value that val will take.
  952.   @param maxVal Maximum value that val will take.
  953.  
  954.   @return Color between colors a and b.
  955. */
  956. Color lerpColor(Color a, Color b, int val, int minVal, int maxVal)
  957. {
  958.   int red = a.red + (b.red-a.red) * (val-minVal) / (maxVal-minVal);
  959.   int green = a.green + (b.green-a.green) * (val-minVal) / (maxVal-minVal);
  960.   int blue = a.blue + (b.blue-a.blue) * (val-minVal) / (maxVal-minVal);
  961.  
  962.   return Color(red, green, blue);
  963. }
  964.  
  965. /***************************************
  966.  * fireworks functions *
  967.  * ***********************************/
  968.  
  969.  
  970. void updateFireworks()
  971. {
  972.     background(Color(0,0,0));
  973. //loop through all the pixels, calculate the distance to the center point, and turn the pixel on if it's at the right radius
  974.             if(showRocket)
  975.         sphere(rocketX,rocketY,rocketZ,radius,rocketColor);
  976.             if(exploded)
  977.         sphere(centerX,centerY,centerZ,radius,fireworkColor, fireworkRes);
  978.  
  979.         if(exploded)
  980.             radius+=speed;  //the sphere gets bigger
  981.         if(showRocket)
  982.         {
  983.             rocketX+=xInc;
  984.             rocketY+=yInc;
  985.             rocketZ+=zInc;
  986.         }
  987.         //if our sphere gets too large, restart the animation in another random spot
  988.         if(radius>maxSize)
  989.             prepRocket();
  990.         if(abs(distance(centerX,centerY,centerZ,rocketX, rocketY, rocketZ)-radius)<2)
  991.             {
  992.                 showRocket=false;
  993.                 exploded=true;
  994.             }        
  995. }
  996.  
  997. float distance(float x, float y, float z, float x1, float y1, float z1)
  998. {
  999.     return(sqrt(pow(x-x1,2)+pow(y-y1,2)+pow(z-z1,2)));
  1000. }
  1001.  
  1002. void prepRocket()
  1003. {
  1004.     fireworkRes=10+rand()%20;
  1005.             radius=0.25;
  1006. //      centerX=0;
  1007. //      centerY=14;
  1008. //      centerZ=8;
  1009.             centerX=rand()%8;
  1010.             centerY=rand()%8;
  1011.             centerZ=rand()%8;
  1012.             fireworkColor.red=rand()%maxBrightness;
  1013.             fireworkColor.green=rand()%maxBrightness;
  1014.             fireworkColor.blue=rand()%maxBrightness;
  1015.             launchX=rand()%8;
  1016.             launchZ=rand()%8;
  1017.             rocketX=launchX;
  1018.             rocketY=0;
  1019.             rocketZ=launchZ;
  1020.             launchTime=10+rand()%15;
  1021.             xInc=(centerX-rocketX)/launchTime;
  1022.             yInc=(centerY-rocketY)/launchTime;
  1023.             zInc=(centerZ-rocketZ)/launchTime;
  1024.             showRocket=true;
  1025.             exploded=false;
  1026.             speed=0.35;
  1027.             maxSize=SIZE/2+random(SIZE/2);
  1028.             //speed=rand()%5;
  1029.             //speed*=0.1;
  1030. }
  1031.  
  1032. void initFireworks()
  1033. {
  1034.     rocketColor.red=255;
  1035.     rocketColor.green=150;
  1036.     rocketColor.blue=100;
  1037.     prepRocket();
  1038. }
  1039.  
  1040. Color getVoxel(int x, int y, int z)
  1041. {
  1042.     Color col=Color(0,0,0);
  1043.     if((x>=0)&&(x<SIZE))
  1044.         if((y>=0)&&(y<SIZE))
  1045.             if((z>=0)&&(z<SIZE))
  1046.             {
  1047.                 int index=z*256+x*16+y;
  1048.                 col.red=PIXEL_RGB[index*3+1];
  1049.                 col.green=PIXEL_RGB[index*3];
  1050.                 col.blue=PIXEL_RGB[index*3+2];
  1051.             }
  1052.     return col;
  1053. }
  1054.  
  1055. Color getVoxel(Point p)
  1056. {
  1057.     return getVoxel(p.x, p.y, p.z);
  1058. }
  1059.  
  1060. void setFadeSpeed()
  1061. {
  1062.     if(autoCycle)
  1063.         fadeSpeed=2;
  1064.     else
  1065.         fadeSpeed=20;
  1066. }
  1067.  
  1068.  void incrementDemo()
  1069.  {
  1070.      demo++;
  1071.      setFadeSpeed();
  1072.      fading=true;
  1073.      if(demo>=DEMO_ROUTINES)
  1074.         demo=0;
  1075.  }
  1076.  
  1077.   void decrementDemo()
  1078.  {
  1079.      demo--;
  1080.      setFadeSpeed();
  1081.      fading=true;
  1082.      if(demo<0)
  1083.         demo=DEMO_ROUTINES-1;
  1084.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement