1. New to Christmas lighting? Get started with the AusChristmasLighting 101 Manual:
    auschristmaslighting.com/wiki/AusChristmasLighting-101

Developers: Do you want to create a Nutcracker 3.0 effect?

Discussion in 'xLights (Nutcracker)' started by smeighan, Mar 6, 2013.

  1. smeighan

    smeighan Dedicated Elf

    Joined:
    Jan 19, 2012
    Messages:
    1,076
    Likes Received:
    16
    Location:
    4217 Greenfinch Dr CO 80126
    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




    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


    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


    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
     

Share This Page