DiyLightAnimation

Software => Nutcracker: RGB Effects Builder => Topic started by: smeighan on March 05, 2013,

Title: Developers: Do you want to create a Nutcracker 3.0 effect?
Post by: smeighan on March 05, 2013,
Are you a C++ developer? If not, skip the rest of this post.
Want to make a new cool effect for Nutcracker?

I have written 3 tutorials to help you. Remember that I am not a C++ programmer, now a windows developer. I have learned enough to know how to add new effects to the Nutcracker code that Matt wrote.

Part1: Setting up your machine to be able to build the xLights project file.
You need just 3 parts to build xlights/nutcracker, Code::Blocks, mingw and wxWidgets.
https://vimeo.com/61068045 (https://vimeo.com/61068045)


Part2: Now that you can compile the current copy of xLights, we need to add our new effect into the wxWidgets gui. After this tutorial you should know how to add a pnale, a slider bar and stuff.
https://vimeo.com/61068046 (https://vimeo.com/61068046)

Part3: Now that we have added the gui stuff, lets actually modify the code to make an effect. We will use the spirograph effect as our straw man.
https://vimeo.com/61153242 (https://vimeo.com/61153242)

The source files can be downloaded from https://github.com/smeighan/nutcracker_c

in the nutcracker/docs directory is a document, "How_To_Add_effects_To_Nutcracker.pdf". This is referenced in the 3rd tutorial.

Check out the code, build a project, add an effect.


Here are two examples of the C++ code that makes effects you have used. You will notice they are not that complicated.

First the Twinkle effect

void RgbEffects::RenderTwinkle(int Count)
{

    int x,y,i,i7,r,ColorIdx;
    int lights = (BufferHt*BufferWi)*(Count/100.0); // Count is in range of 1-100 from slider bar
    int step=BufferHt*BufferWi/lights;
    if(step<1) step=1;
    srand(1); // always have the same random numbers for each frame (state)
    wxImage::HSVValue hsv; //   we will define an hsv color model. The RGB colot model would have been "wxColour color;"

    size_t colorcnt=GetColorCount();

    i=0;

    for (y=0; y<BufferHt; y++) // For my 20x120 megatree, BufferHt=120
    {
        for (x=0; x<BufferWi; x++) // BufferWi=20 in the above example
        {
            i++;
            if(i%step==0) // Should we draw a light?
            {
                // Yes, so now decide on what color it should be

                ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
                palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx
                i7=(state/4+rand())%9; // Our twinkle is 9 steps. 4 ramping up, 5th at full brightness and then 4 more ramping down
                //  Note that we are adding state to this calculation, this causes a different blink rate for each light

                if(i7==0 || i7==8)  hsv.value = 0.1;
                if(i7==1 || i7==7)  hsv.value = 0.3;
                if(i7==2 || i7==6)  hsv.value = 0.5;
                if(i7==3 || i7==5)  hsv.value = 0.7;
                if(i7==4  )  hsv.value = 1.0;
                //  we left the Hue and Saturation alone, we are just modifiying the Brightness Value
                SetPixel(x,y,hsv); // Turn pixel on
            }
        }
    }
}


The second effect is Spirograph
void RgbEffects::RenderSpirograph(int int_R, int int_r, int int_d)
{
#define PI 3.14159265
    int i,x,y,k,xc,yc,ColorIdx;
    int mod1440,state360;
    srand(1);
    float R,r,d,d_orig,t;
    wxImage::HSVValue hsv,hsv0,hsv1; //   we will define an hsv color model. The RGB colot model would have been "wxColour color;"
    size_t colorcnt=GetColorCount();

    xc= (int)(BufferWi/2); // 20x100 flex strips with 2 fols per strip = 40x50
    yc= (int)(BufferHt/2);
    R=xc*(int_R/100.0);   //  Radius of the large circle just fits in the width of model
    r=xc*(int_r/100.0); // start little circle at 1/4 of max width
    if(r>R) r=R;
    d=xc*(int_d/100.0);
    ColorIdx=rand() % colorcnt; // Select random numbers from 0 up to number of colors the user has checked. 0-5 if 6 boxes checked
    palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx
    palette.GetHSV(0, hsv0);
    palette.GetHSV(1, hsv1);
//
//    A hypotrochoid is a roulette traced by a point attached to a circle of radius r rolling around the inside of a fixed circle of radius R, where the point is a distance d from the center of the interior circle.
//The parametric equations for a hypotrochoid are:[citation needed]
//
//  more info: http://en.wikipedia.org/wiki/Hypotrochoid
//
//x(t) = (R-r) * cos t + d*cos ((R-r/r)*t);
//y(t) = (R-r) * sin t + d*sin ((R-r/r)*t);

    mod1440=state%1440;
    state360 = state%360;
    d_orig=d;
    for(i=1; i<=360; i++)
    {
        d = (int)(d_orig+state/2)%100;
        t = (i+mod1440)*PI/180;
        x = (R-r) * cos (t) + d*cos ((R-r/r)*t) + xc;
        y = (R-r) * sin (t) + d*sin ((R-r/r)*t) + yc;
        if(i<=state360) SetPixel(x,y,hsv0); // Turn pixel on
        else SetPixel(x,y,hsv1);
    }
}

I would ask that you NOT check back your changes without contacting me first. So, go ahead, try out some effects!

thanks
sean