Feedback

Please leave feedback and comments. I am always interested to hear how people get on using these LScripts!

Monday, 4 February 2013

LScript - Channel_GlobalAmbientIntensity

LScript (Layout) to allow access via channel to the global ambient intensity.

Compatible with Newtek LightWave 9.6 and above.

// LScript Channel Filter - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/* 
    LScript Channel Filter - Global Ambient Intensity

    Channel_GlobalAmbientIntensity.ls

*/

@version 2.2
@warnings
@script channel
@name *Global Ambient Intensity

    // Title
    sTitle = "*Global Ambient Intensity";

    // Version
    sVersion = "v1.0";

create: channel
{
    setdesc(sTitle);
}

destroy
{
    // take care of final clean-up activities here
}

process: ca, frame, time
{
    nValue = ca.get(time);

    Light = Light();
    nValue += Light.ambient(time);

    // ca    
    ca.set(nValue);
}


load: what,io
{
    if(what == SCENEMODE)   // processing an ASCII scene file
    {
    }
}

save: what,io
{
    if(what == SCENEMODE)
    {
    }
}

options
{
    reqbegin(sTitle + " " + sVersion);

    // Developer
//    ctlsep();
    ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");

    reqend();
}
All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

LScript - Modeler_Poke

LScript (Modeler) that replicates poke in Maya to split polygons with an averaged center.

Changes

Compatible with Newtek LightWave 9.6 and above.

// LScript Modeler - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/*  
    LScript Modeler - Poke

    Modeler_Poke.ls

*/

@version 2.2
@warnings
@script modeler
@name *Poke

    // Title
    sTitle = "*Poke";

    // Version
    sVersion = "v1.1";

main
{
    // Selection - Polygon (DIRECT)
    selmode(DIRECT);
    iPolyCount = polycount();

    if(iPolyCount[1] < 1) error("No polygons selected.");

    undogroupbegin(); // Undo

    editbegin();

    if(iPolyCount[1] >= 1)
      { 
       
      foreach(aPolygon,polygons)
       {
        aPoints = polyinfo(aPolygon); 
        rempoly(aPolygon);
        vAverage = <0.0,0.0,0.0>;
        for(iPointCount = 2; iPointCount <= sizeof(aPoints); iPointCount++)
          {
          vAverage += pointinfo(aPoints[iPointCount]);  
          }
        // Resize by points
        vAverage *= 1 / (sizeof(aPoints) - 1);
        // Make new point
        iAverage = addpoint(vAverage); // Returns ID

        // Add polygons
        for(iPointCount = 2; iPointCount <= sizeof(aPoints) - 1; iPointCount++)
          {
          aNewPolygon[1] = aPoints[iPointCount]; 
          aNewPolygon[2] = aPoints[iPointCount + 1]; 
          aNewPolygon[3] = iAverage; 
          addpolygon(aNewPolygon);  
          }
        aNewPolygon[1] = aPoints[sizeof(aPoints)]; 
        aNewPolygon[2] = aPoints[2]; 
        aNewPolygon[3] = iAverage; 
        addpolygon(aNewPolygon);             
        }

      }

    editend();

    undogroupend(); // Undo

    info(iPolyCount[1]," poly(s) poked.");
}


All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

Monday, 16 April 2012

LScript - Generic_LightColor


LScript (Layout) applies colour to selected lights between frame 0 and 1. It enables changing light colour during spinning light tricks and in old school techniques like faking spectrums. The values are repeated correctly each frame by timing them to the motion blur length.

Compatible with Newtek LightWave 9.6 and above.

// LScript Generic - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/*  
    LScript Generic - LightColor

    Generic_LightColor.ls

*/

    // Title
    sTitle = "*LightColor";

    // Version
    sVersion = "v1.0";

    // Variable
    aColor;
    aIntensity;

    // Requester
    bRequesterUpdate = false; // Update

    ctrl_c0,ctrl_c1,ctrl_c2,ctrl_c3,ctrl_c4,ctrl_c5,ctrl_c6,ctrl_c7,ctrl_c8,ctrl_c9,ctrl_c10,ctrl_c11,ctrl_c12,ctrl_c13,ctrl_c14;

generic
{

    // Item Select
    Items = Scene().getSelect();  

    bLight = false;

    for(i = 1; i <= Items.size(); i++)
      {
      if(Items[i].genus == LIGHT) bLight = true;
      }        

    if(!bLight)
      {
      info("Select a light to apply color to.");
      return;
      }        

    // Recall
    aColor[1] = recall("vColor1",<255.0,255.0,255.0>);
    aIntensity[1] = recall("nIntensity1",1.0);
    aColor[2] = recall("vColor2",<0.0,0.0,0.0>);
    aIntensity[2] = recall("nIntensity2",0.0);
    aColor[3] = recall("vColor3",<0.0,0.0,0.0>);
    aIntensity[3] = recall("nIntensity3",0.0);
    aColor[4] = recall("vColor4",<0.0,0.0,0.0>);
    aIntensity[4] = recall("nIntensity4",0.0);
    aColor[5] = recall("vColor5",<0.0,0.0,0.0>);
    aIntensity[5] = recall("nIntensity5",0.0);
    aColor[6] = recall("vColor6",<0.0,0.0,0.0>);
    aIntensity[6] = recall("nIntensity6",0.0);
    aColor[7] = recall("vColor7",<0.0,0.0,0.0>);
    aIntensity[7] = recall("nIntensity7",1.0);

    reqbegin(sTitle + " " + sVersion);

    // Reset
    ctrl_res0 = ctlbutton("Reset",50,"button_reset"); // Button Reset
    ctlsep();

    // Control
    ctrl_c0 = ctlpopup("Preset",1, @"Gradient",
                                    "RGB",
                                    "Spectrum"@);

    ctlsep();
    ctrl_c1 = ctlcolor("1",aColor[1]);
    ctrl_c2 = ctlpercent("Intensity",aIntensity[1]);
    ctrl_c3 = ctlcolor("2",aColor[2]);
    ctrl_c4 = ctlpercent("Intensity",aIntensity[2]);
    ctrl_c5 = ctlcolor("3",aColor[3]);
    ctrl_c6 = ctlpercent("Intensity",aIntensity[3]);
    ctrl_c7 = ctlcolor("4",aColor[4]);
    ctrl_c8 = ctlpercent("Intensity",aIntensity[4]);
    ctrl_c9 = ctlcolor("5",aColor[5]);
    ctrl_c10 = ctlpercent("Intensity",aIntensity[5]);
    ctrl_c11 = ctlcolor("6",aColor[6]);
    ctrl_c12 = ctlpercent("Intensity",aIntensity[6]);
    ctrl_c13 = ctlcolor("7",aColor[7]);
    ctrl_c14 = ctlpercent("Intensity",aIntensity[7]);

    interpolate();

    // Developer
    ctlsep();
    ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");

    ctlrefresh(ctrl_c0,"refresh_preset"); // Preset
 
    ctlrefresh(ctrl_c1,"refresh");
    ctlrefresh(ctrl_c2,"refresh");
    ctlrefresh(ctrl_c3,"refresh");
    ctlrefresh(ctrl_c4,"refresh");
    ctlrefresh(ctrl_c5,"refresh");
    ctlrefresh(ctrl_c6,"refresh");
    ctlrefresh(ctrl_c7,"refresh");
    ctlrefresh(ctrl_c8,"refresh");
    ctlrefresh(ctrl_c9,"refresh");
    ctlrefresh(ctrl_c10,"refresh");
    ctlrefresh(ctrl_c11,"refresh");
    ctlrefresh(ctrl_c12,"refresh");
    ctlrefresh(ctrl_c13,"refresh");
    ctlrefresh(ctrl_c14,"refresh");

    return if !reqpost();

    aColor[1] = getvalue(ctrl_c1);
    aIntensity[1] = getvalue(ctrl_c2);
    aColor[2] = getvalue(ctrl_c3);
    aIntensity[2] = getvalue(ctrl_c4);
    aColor[3] = getvalue(ctrl_c5);
    aIntensity[3] = getvalue(ctrl_c6);
    aColor[4] = getvalue(ctrl_c7);
    aIntensity[4] = getvalue(ctrl_c8);
    aColor[5] = getvalue(ctrl_c9);
    aIntensity[5] = getvalue(ctrl_c10);
    aColor[6] = getvalue(ctrl_c11);
    aIntensity[6] = getvalue(ctrl_c12);
    aColor[7] = getvalue(ctrl_c13);
    aIntensity[7] = getvalue(ctrl_c14);

    // Store
    store("vColor1",aColor[1]);
    store("nIntensity1",aIntensity[1]);
    store("vColor2",aColor[2]);
    store("nIntensity2",aIntensity[2]);
    store("vColor3",aColor[3]);
    store("nIntensity3",aIntensity[3]);
    store("vColor4",aColor[4]);
    store("nIntensity4",aIntensity[4]);
    store("vColor5",aColor[5]);
    store("nIntensity5",aIntensity[5]);
    store("vColor6",aColor[6]);
    store("nIntensity6",aIntensity[6]);
    store("vColor7",aColor[7]);
    store("nIntensity7",aIntensity[7]);

    // Error
    bError = true;
    for(i = 1; i <= 7; i++)
      {
      if(aIntensity[i] > 0.0){bError = false;}
      }
    if(bError)
      {
      info("Intensity on atleast one color must be above 0.0%");
      return;
      }  

    // Camera Blur Length
    if(Camera().blurLength(0.0) < 1.0)
      {
      nCameraBlurLength = Camera().blurLength(0.0);
      }
    else
      {
      nCameraBlurLength = 1.0;
      }

    for(i = 1; i <= Items.size(); i++)
      {

      if(Items[i].genus == LIGHT)
        {

        Items[i].select();
      
    // Envelope

        AddEnvelope("Color");
        envRed = Envelope("Color.R",CHAN_PERCENT,Items[i].name);
        envGreen = Envelope("Color.G",CHAN_PERCENT,Items[i].name);
        envBlue = Envelope("Color.B",CHAN_PERCENT,Items[i].name);

        // Clear 
        while(envRed.keyCount >= 1)
          {
          envRed.deleteKey(envRed.keys[1]);       
          }
        while(envGreen.keyCount >= 1)
          {
          envGreen.deleteKey(envGreen.keys[1]);       
          }
        while(envBlue.keyCount >= 1)
          {
          envBlue.deleteKey(envBlue.keys[1]);       
          }

        if(aIntensity[1] > 0.0)
          {
          envRed.createKey(0.0,aColor[1].x * (1/255) * aIntensity[1]); 
          envRed.setKeyCurve(0.0,CHAN_LINEAR);        
          envGreen.createKey(0.0,aColor[1].y * (1/255) * aIntensity[1]); 
          envGreen.setKeyCurve(0.0,CHAN_LINEAR);        
          envBlue.createKey(0.0,aColor[1].z * (1/255) * aIntensity[1]); 
          envBlue.setKeyCurve(0.0,CHAN_LINEAR);        
          }
        else
          {
          iColor = 0;
          for(c = 1; c <= 7; c++)
            {
            if(aIntensity[c] > 0.0){iColor = c; break;}
            }
          envRed.createKey(0.0,aColor[iColor].x * (1/255) * aIntensity[iColor]); 
          envRed.setKeyCurve(0.0,CHAN_LINEAR);        
          envGreen.createKey(0.0,aColor[iColor].y * (1/255) * aIntensity[iColor]); 
          envGreen.setKeyCurve(0.0,CHAN_LINEAR);        
          envBlue.createKey(0.0,aColor[iColor].z * (1/255) * aIntensity[iColor]); 
          envBlue.setKeyCurve(0.0,CHAN_LINEAR);   
          }

        if(aIntensity[2] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),aColor[2].x * (1/255) * aIntensity[2]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),aColor[2].y * (1/255) * aIntensity[2]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),aColor[2].z * (1/255) * aIntensity[2]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 1),CHAN_LINEAR); 
          }

        if(aIntensity[3] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),aColor[3].x * (1/255) * aIntensity[3]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),aColor[3].y * (1/255) * aIntensity[3]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),aColor[3].z * (1/255) * aIntensity[3]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 2),CHAN_LINEAR); 
          }

        if(aIntensity[4] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),aColor[4].x * (1/255) * aIntensity[4]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),aColor[4].y * (1/255) * aIntensity[4]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),aColor[4].z * (1/255) * aIntensity[4]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 3),CHAN_LINEAR); 
          }

        if(aIntensity[5] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),aColor[5].x * (1/255) * aIntensity[5]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),aColor[5].y * (1/255) * aIntensity[5]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),aColor[5].z * (1/255) * aIntensity[5]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 4),CHAN_LINEAR); 
          }

        if(aIntensity[6] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),aColor[6].x * (1/255) * aIntensity[6]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),aColor[6].y * (1/255) * aIntensity[6]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),aColor[6].z * (1/255) * aIntensity[6]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 5),CHAN_LINEAR); 
          }

        if(aIntensity[7] > 0.0)
          {           
          envRed.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),aColor[7].x * (1/255) * aIntensity[7]); 
          envRed.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),CHAN_LINEAR);        
          envGreen.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),aColor[7].y * (1/255) * aIntensity[7]); 
          envGreen.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),CHAN_LINEAR);        
          envBlue.createKey((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),aColor[7].z * (1/255) * aIntensity[7]); 
          envBlue.setKeyCurve((1 / Scene().fps) * nCameraBlurLength * ((1 / 6) * 6),CHAN_LINEAR); 
          }

        if(aIntensity[7] <= 0.0 || nCameraBlurLength < 1.0)
          {
          iColor = 0;
          for(c = 7; c >= 1; c--)
            {
            if(aIntensity[c] > 0.0){iColor = c; break;}
            }
          envRed.createKey(1 / Scene().fps,aColor[iColor].x * (1/255) * aIntensity[iColor]); 
          envRed.setKeyCurve(1 / Scene().fps,CHAN_LINEAR);        
          envGreen.createKey(1 / Scene().fps,aColor[iColor].y * (1/255) * aIntensity[iColor]); 
          envGreen.setKeyCurve(1 / Scene().fps,CHAN_LINEAR);        
          envBlue.createKey(1 / Scene().fps,aColor[iColor].z * (1/255) * aIntensity[iColor]); 
          envBlue.setKeyCurve(1 / Scene().fps,CHAN_LINEAR);   
          }
            
          // Repeat
          envRed.preBehavior = CHAN_REPEAT;
          envRed.postBehavior = CHAN_REPEAT;
          envGreen.preBehavior = CHAN_REPEAT;
          envGreen.postBehavior = CHAN_REPEAT;
          envBlue.preBehavior = CHAN_REPEAT;
          envBlue.postBehavior = CHAN_REPEAT;

    //

        }

      }   

}

button_reset
{
    bRequesterUpdate = true;

    setvalue(ctrl_c1,<1.0,1.0,1.0>); // Color 1
    setvalue(ctrl_c2,1.0); // Intensity 1
    setvalue(ctrl_c3,<0.0,0.0,0.0>); // Color 2
    setvalue(ctrl_c4,0.0); // Intensity 2
    setvalue(ctrl_c5,<0.0,0.0,0.0>); // Color 3
    setvalue(ctrl_c6,0.0); // Intensity 3
    setvalue(ctrl_c7,<0.0,0.0,0.0>); // Color 4
    setvalue(ctrl_c8,0.0); // Intensity 4
    setvalue(ctrl_c9,<0.0,0.0,0.0>); // Color 5
    setvalue(ctrl_c10,0.0); // Intensity 5
    setvalue(ctrl_c11,<0.0,0.0,0.0>); // Color 6
    setvalue(ctrl_c12,0.0); // Intensity 6
    setvalue(ctrl_c13,<0.0,0.0,0.0>); // Color 7
    setvalue(ctrl_c14,1.0); // Intensity 7

    // Update
    aColor[1] = getvalue(ctrl_c1);
    aIntensity[1] = getvalue(ctrl_c2);
    aColor[2] = getvalue(ctrl_c3);
    aIntensity[2] = getvalue(ctrl_c4);
    aColor[3] = getvalue(ctrl_c5);
    aIntensity[3] = getvalue(ctrl_c6);
    aColor[4] = getvalue(ctrl_c7);
    aIntensity[4] = getvalue(ctrl_c8);
    aColor[5] = getvalue(ctrl_c9);
    aIntensity[5] = getvalue(ctrl_c10);
    aColor[6] = getvalue(ctrl_c11);
    aIntensity[6] = getvalue(ctrl_c12);
    aColor[7] = getvalue(ctrl_c13);
    aIntensity[7] = getvalue(ctrl_c14); 

    bRequesterUpdate = false;

    interpolate();
}

refresh:value
{
    if(!bRequesterUpdate)
      {
      aColor[1] = getvalue(ctrl_c1);
      aIntensity[1] = getvalue(ctrl_c2);
      aColor[2] = getvalue(ctrl_c3);
      aIntensity[2] = getvalue(ctrl_c4);
      aColor[3] = getvalue(ctrl_c5);
      aIntensity[3] = getvalue(ctrl_c6);
      aColor[4] = getvalue(ctrl_c7);
      aIntensity[4] = getvalue(ctrl_c8);
      aColor[5] = getvalue(ctrl_c9);
      aIntensity[5] = getvalue(ctrl_c10);
      aColor[6] = getvalue(ctrl_c11);
      aIntensity[6] = getvalue(ctrl_c12);
      aColor[7] = getvalue(ctrl_c13);
      aIntensity[7] = getvalue(ctrl_c14);

      interpolate();
      }
}

refresh_preset:value
{

    bRequesterUpdate = true;

    if(value == 1) // Gradient
      {
      setvalue(ctrl_c1,<1.0,1.0,1.0>); // Color 1
      setvalue(ctrl_c2,1.0); // Intensity 1
      setvalue(ctrl_c3,<0.0,0.0,0.0>); // Color 2
      setvalue(ctrl_c4,0.0); // Intensity 2
      setvalue(ctrl_c5,<0.0,0.0,0.0>); // Color 3
      setvalue(ctrl_c6,0.0); // Intensity 3
      setvalue(ctrl_c7,<0.0,0.0,0.0>); // Color 4
      setvalue(ctrl_c8,0.0); // Intensity 4
      setvalue(ctrl_c9,<0.0,0.0,0.0>); // Color 5
      setvalue(ctrl_c10,0.0); // Intensity 5
      setvalue(ctrl_c11,<0.0,0.0,0.0>); // Color 6
      setvalue(ctrl_c12,0.0); // Intensity 6
      setvalue(ctrl_c13,<0.0,0.0,0.0>); // Color 7
      setvalue(ctrl_c14,1.0); // Intensity 7
      }  

    if(value == 2) // RGB
      {
      setvalue(ctrl_c1,<1.0,0.0,0.0>); // Color 1
      setvalue(ctrl_c2,1.0); // Intensity 1
      setvalue(ctrl_c3,<0.0,0.0,0.0>); // Color 2
      setvalue(ctrl_c4,0.0); // Intensity 2
      setvalue(ctrl_c5,<0.0,0.0,0.0>); // Color 3
      setvalue(ctrl_c6,0.0); // Intensity 3
      setvalue(ctrl_c7,<0.0,1.0,0.0>); // Color 4
      setvalue(ctrl_c8,1.0); // Intensity 4
      setvalue(ctrl_c9,<0.0,0.0,0.0>); // Color 5
      setvalue(ctrl_c10,0.0); // Intensity 5
      setvalue(ctrl_c11,<0.0,0.0,0.0>); // Color 6
      setvalue(ctrl_c12,0.0); // Intensity 6
      setvalue(ctrl_c13,<0.0,0.0,1.0>); // Color 7
      setvalue(ctrl_c14,1.0); // Intensity 7
      } 

    if(value == 3) // Spectrum
      {
      setvalue(ctrl_c1,<1.0,0.0,0.0>); // Color 1
      setvalue(ctrl_c2,1.0); // Intensity 1
      setvalue(ctrl_c3,<1.0,0.5,0.0>); // Color 2
      setvalue(ctrl_c4,1.0); // Intensity 2
      setvalue(ctrl_c5,<1.0,1.0,0.0>); // Color 3
      setvalue(ctrl_c6,1.0); // Intensity 3
      setvalue(ctrl_c7,<0.0,1.0,0.0>); // Color 4
      setvalue(ctrl_c8,1.0); // Intensity 4
      setvalue(ctrl_c9,<0.0,1.0,1.0>); // Color 5
      setvalue(ctrl_c10,1.0); // Intensity 5
      setvalue(ctrl_c11,<0.0,0.0,0.6255>); // Color 6
      setvalue(ctrl_c12,1.0); // Intensity 6
      setvalue(ctrl_c13,<0.5,0.0,0.5>); // Color 7
      setvalue(ctrl_c14,1.0); // Intensity 7
      }


    // Update
    aColor[1] = getvalue(ctrl_c1);
    aIntensity[1] = getvalue(ctrl_c2);
    aColor[2] = getvalue(ctrl_c3);
    aIntensity[2] = getvalue(ctrl_c4);
    aColor[3] = getvalue(ctrl_c5);
    aIntensity[3] = getvalue(ctrl_c6);
    aColor[4] = getvalue(ctrl_c7);
    aIntensity[4] = getvalue(ctrl_c8);
    aColor[5] = getvalue(ctrl_c9);
    aIntensity[5] = getvalue(ctrl_c10);
    aColor[6] = getvalue(ctrl_c11);
    aIntensity[6] = getvalue(ctrl_c12);
    aColor[7] = getvalue(ctrl_c13);
    aIntensity[7] = getvalue(ctrl_c14); 

    bRequesterUpdate = false;

    interpolate();
}

interpolate
{

    bRequesterUpdate = true;

    for(i = 1; i <= 7; i++)
      {
      if(aIntensity[i] <= 0.0)
        {


        iColorA = 0;
        for(c = i; c >= 1; c--)
          {
          if(aIntensity[c] > 0.0){iColorA = c; break;}
          }

        iColorB = 0;
        for(c = i; c <= 7; c++)
          {
          if(aIntensity[c] > 0.0){iColorB = c; break;}
          }

        if(iColorA == 0)
          {aColor[i] = aColor[iColorB];}
        else if(iColorB == 0)
          {aColor[i] = aColor[iColorA];}
        else
          {
          aColor[i] = linear1D(aColor[iColorA],aColor[iColorB],maprange01(iColorA,iColorB,i)); 
          } 


        } 
      }

      if(aIntensity[1] <= 0.0){setvalue(ctrl_c1,(1/255) * aColor[1]);} // Color 1
      if(aIntensity[2] <= 0.0){setvalue(ctrl_c3,(1/255) * aColor[2]);} // Color 2
      if(aIntensity[3] <= 0.0){setvalue(ctrl_c5,(1/255) * aColor[3]);} // Color 3
      if(aIntensity[4] <= 0.0){setvalue(ctrl_c7,(1/255) * aColor[4]);} // Color 4
      if(aIntensity[5] <= 0.0){setvalue(ctrl_c9,(1/255) * aColor[5]);} // Color 5
      if(aIntensity[6] <= 0.0){setvalue(ctrl_c11,(1/255) * aColor[6]);} // Color 6
      if(aIntensity[7] <= 0.0){setvalue(ctrl_c13,(1/255) * aColor[7]);} // Color 7

    bRequesterUpdate = false;

}

// MAP RANGE

maprange01: n1,n2,i
{    
    if(n2-n1 == 0.0){return(0.0);}
  else
    {return((1/(n2-n1)) * (i-n1));}
}

// INTERPOLATION

linear1D: n1,n2,i // i = interpolation point (0-1)
{
    return(n1 * (1 - i) + n2 * i);     
}


All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

Saturday, 24 March 2012

LScript - Modeler_Jitter


LScript (Modeler) to offsets vertices based on chosen parameters such as noise and Brownian motion.

Changes

  • Seeded noise
  • Seeded fractal Brownian motion
  • Added control reset
  • Realtime Preview

Compatible with Newtek LightWave 9.6 and above.

// LScript Modeler - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/*  
    LScript Modeler - Jitter

    Modeler_Jitter.ls

*/

@version 2.2
@warnings
@script modeler
@name *Jitter

    // Title
    sTitle = "*Jitter";

    // Version
    sVersion = "v2.0";
 
    bDone = false; // Done
    bChange = false; // Change
    bPreview; // Preview
    iType;
    bAxisX;
    bAxisY;
    bAxisZ;
    nAmplitude;
    iOctaves;
    nPersistence;
    vScale;
    iSeed;
    iInterpolation;
   
    ctrl_c0,ctrl_c1,ctrl_c2,ctrl_c3,ctrl_c4,ctrl_c5,ctrl_c6,ctrl_c7,ctrl_c8,ctrl_c9;
    ctrl_res0;
    ctrl_prev0;

main
{

    // Recall
    bPreview = recall("bPreview",true);
    iType = recall("iType",2);
    bAxisX = recall("bAxisX",true);
    bAxisY = recall("bAxisY",true);
    bAxisZ = recall("bAxisZ",true);
    nAmplitude = recall("nAmplitude",0.1);
    iOctaves = recall("iOctaves",3);
    nPersistence = recall("nPersistence",0.25);
    vScale = recall("vScale",<1.0,1.0,1.0>);
    iSeed = recall("iSeed",1);
    iInterpolation = recall("iInterpolation",3);

    reqbegin(sTitle + " " + sVersion);

    // Reset / Preview
    ctrl_res0 = ctlbutton("Reset",50,"button_reset"); // Button Reset
    ctrl_prev0 = ctlcheckbox("Preview",bPreview); // Preview
    ctlsep();

    // Control
    ctrl_c0 = ctlchoice("Type",iType,@"Noise","fBm"@); // Type
    ctrl_c1 = ctlcheckbox("X",bAxisX); // X
    ctrl_c2 = ctlcheckbox("Y",bAxisY); // Y
    ctrl_c3 = ctlcheckbox("Z",bAxisZ); // Z
    ctrl_c4 = ctldistance("Amplitude",nAmplitude); // Amplitude
    ctrl_c5 = ctlslider("Octaves",iOctaves,1,64); // Octaves
    ctrl_c6 = ctlnumber("Persistence",nPersistence); // Persistence
    ctrl_c7 = ctlvector("Scale",vScale); // Scale
    ctrl_c8 = ctlinteger("Seed",iSeed); // Seed
    ctrl_c9 = ctlchoice("Interpolation",iInterpolation,@"None","Linear","Cosine"@); // Interpolation

    // Developer
    ctlsep();
    ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");

    process(); // Process

    // Refresh
    ctlrefresh(ctrl_prev0,"refresh");
    ctlrefresh(ctrl_c0,"refresh");
    ctlrefresh(ctrl_c1,"refresh");
    ctlrefresh(ctrl_c2,"refresh");
    ctlrefresh(ctrl_c3,"refresh");
    ctlrefresh(ctrl_c4,"refresh");
    ctlrefresh(ctrl_c5,"refresh");
    ctlrefresh(ctrl_c6,"refresh");
    ctlrefresh(ctrl_c7,"refresh");
    ctlrefresh(ctrl_c8,"refresh");
    ctlrefresh(ctrl_c9,"refresh");

    if (!reqpost())
    {
        // Cancel

        if(bDone){undo();} // Undo

        return;
    }
    else
    {
        // Ok

        if(!bDone || bChange) // Process
        {
        values(); // Values
        process(); // Process
        }

        // Store
        store("bPreview",bPreview);
        store("iType",iType);
        store("bAxisX",bAxisX);
        store("bAxisY",bAxisY);
        store("bAxisZ",bAxisZ);
        store("nAmplitude",nAmplitude);
        store("iOctaves",iOctaves);
        store("nPersistence",nPersistence);
        store("vScale",vScale);
        store("iSeed",iSeed);
        store("iInterpoltation",iInterpolation);
    }

    reqend();
}

refresh:value
{
    bChange = true; // Change
    values(); // Values
    if(bPreview){process();} // Process
}

values
{
    bPreview = getvalue(ctrl_prev0); // Preview
    iType = getvalue(ctrl_c0); // Type
    bAxisX = getvalue(ctrl_c1); // X
    bAxisY = getvalue(ctrl_c2); // Y
    bAxisZ = getvalue(ctrl_c3); // Z
    nAmplitude = getvalue(ctrl_c4); // Amplitude
    iOctaves = getvalue(ctrl_c5); // Octaves
    nPersistence = getvalue(ctrl_c6); // Persistence
    vScale = getvalue(ctrl_c7); // Scale
    iSeed = getvalue(ctrl_c8); // Seed 
    iInterpolation = getvalue(ctrl_c9); // Interpolation
}

button_reset
{
    setvalue(ctrl_c0,2); // Type
    setvalue(ctrl_c1,true); // X
    setvalue(ctrl_c2,true); // Y
    setvalue(ctrl_c3,true); // Z
    setvalue(ctrl_c4,0.1); // Amplitude
    setvalue(ctrl_c5,3); // Octaves
    setvalue(ctrl_c6,0.25); // Persistence
    setvalue(ctrl_c7,<1.0,1.0,1.0>); // Scale
    setvalue(ctrl_c8,1); // Seed
    setvalue(ctrl_c9,3); // Interpolation
}

process
{
    // Undo
    if(bDone){undo();}
    undogroupbegin();

    // Process

    // Selection - Point (DIRECT)
    selmode(DIRECT);
    iPointCount = pointcount();
    if(iPointCount < 1) error("No points selected.");

    noiseseed(iSeed); // Noise Seed

    for(iO = 1; iO <= 3; iO++)
      {
      aOffset[iO] = ;
      }

    editbegin();

        if((iType == "1") && (iInterpolation == 1)) // Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = noise3D(vPoint + aOffset[1]);}
            if(bAxisY){vOffset.y = noise3D(vPoint + aOffset[2]);}
            if(bAxisZ){vOffset.z = noise3D(vPoint + aOffset[3]);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          } 

        else if((iType == "1") && (iInterpolation == 2)) // Linear Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = linearnoise3D(vPoint + aOffset[1]);}
            if(bAxisY){vOffset.y = linearnoise3D(vPoint + aOffset[2]);}
            if(bAxisZ){vOffset.z = linearnoise3D(vPoint + aOffset[3]);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          }

        else if((iType == "1") && (iInterpolation == 3)) // Cosine Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = cosinenoise3D(vPoint + aOffset[1]);}
            if(bAxisY){vOffset.y = cosinenoise3D(vPoint + aOffset[2]);}
            if(bAxisZ){vOffset.z = cosinenoise3D(vPoint + aOffset[3]);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          }  

        else if((iType == "2") && (iInterpolation == 1)) // fBm Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = fBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
            if(bAxisY){vOffset.y = fBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
            if(bAxisZ){vOffset.z = fBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          }  

        else if((iType == "2") && (iInterpolation == 2)) // Linear fBm Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = linearfBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
            if(bAxisY){vOffset.y = linearfBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
            if(bAxisZ){vOffset.z = linearfBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          }

        else if((iType == "2") && (iInterpolation == 3)) // Cosine fBm Noise
          {
          moninit(iPointCount,"Processing...");  // Progress Monitor
          for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
            {
            vOffset = <0.0,0.0,0.0>;
            vPoint = pointinfo(points[iCurrentPoint]) * vScale;
            if(bAxisX){vOffset.x = cosinefBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
            if(bAxisY){vOffset.y = cosinefBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
            if(bAxisZ){vOffset.z = cosinefBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
            pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point  
            monstep(); // Progress Monitor
            }
          monend(); // Progress Monitor
          }

    editend();

    // Undo
    undogroupend();

    bChange = false; // Change

    // Done
    bDone = true;
}

// INTERPOLATION

linear1D: n1,n2,i // i = interpolation point (0-1)
{
    return(n1 * (1 - i) + n2 * i);     
}

cosine1D: n1,n2,i // i = interpolation point (0-1)
{
    i2 = (1 - cos(i * 3.1415926535)) * 0.5;
    return(n1 * (1 - i2) + n2 * i2);     
}

// NOISE

_noiseseed = 1;
_noiseresolution = 512;
_noise = nil;
_noiseoffset = nil;
_noiseperm = nil;

noiseinit
{  
    randomseed(_noiseseed); // Random Seed
    for(iN = 1; iN <= _noiseresolution; iN++)
      {
      _noise[iN] = (random() * 2) - 1; // -1.0..1.0
      _noiseperm[iN] = wrap(1,_noiseresolution,integer(random() * _noiseresolution));
      }

    for(iO = 1; iO <= 64; iO++)
      {
      _noiseoffset[iO] = ;
      }
}

noiseseed: seed
{
    _noiseseed = seed;
    noiseinit(); // Init
}

noiseresolution: resolution
{
    _noiseresolution = resolution;
    noiseinit(); // Init 
}

noiseperm1D: n // i
{
// !    if(_noiseperm == nil){noiseinit();} // Init
    return(_noiseperm[wrap(1,_noiseresolution,integer(n))]);
}

noiseperm2D: v // n
{
    return(noiseperm1D(v.y + noiseperm1D(v.x)));
}

noiseperm3D: v // n
{
    return(noiseperm1D(v.z + noiseperm2D(v)));
}

noise3D: v // n
{
// !    if(_noise == nil){noiseinit();} // Init
    return(_noise[noiseperm3D(v)]);
}

linearnoise3D: v // n
{
    v = wrap(1,_noiseresolution,v); 
    vFrac = frac(v);
    vInt = v - vFrac;
    nA1 = noise3D();
    nA2 = noise3D();
    nA3 = noise3D();
    nA4 = noise3D();
    nA = linear1D(linear1D(nA1,nA2,vFrac.x),linear1D(nA3,nA4,vFrac.x),vFrac.z);
    nB1 = noise3D();
    nB2 = noise3D();
    nB3 = noise3D();
    nB4 = noise3D();
    nB = linear1D(linear1D(nB1,nB2,vFrac.x),linear1D(nB3,nB4,vFrac.x),vFrac.z);
    return(linear1D(nA,nB,vFrac.y));
}

cosinenoise3D: v // n
{
    v = wrap(1,_noiseresolution,v); 
    vFrac = frac(v);
    vInt = v - vFrac;
    nA1 = noise3D();
    nA2 = noise3D();
    nA3 = noise3D();
    nA4 = noise3D();
    nA = cosine1D(cosine1D(nA1,nA2,vFrac.x),cosine1D(nA3,nA4,vFrac.x),vFrac.z);
    nB1 = noise3D();
    nB2 = noise3D();
    nB3 = noise3D();
    nB4 = noise3D();
    nB = cosine1D(cosine1D(nB1,nB2,vFrac.x),cosine1D(nB3,nB4,vFrac.x),vFrac.z);
    return(cosine1D(nA,nB,vFrac.y));
}

fBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// !    if(_noiseoffset == nil){noiseinit();} // Init
    nNoise = 0.0;
    for(iO = 1; iO <= octaves; iO++)
      {
      nNoise += noise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
      }
    return(nNoise);
}

linearfBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// !    if(_noiseoffset == nil){noiseinit();} // Init
    nNoise = 0.0;
    for(iO = 1; iO <= octaves; iO++)
      {
      nNoise += linearnoise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
      }
    return(nNoise);
}

cosinefBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// !    if(_noiseoffset == nil){noiseinit();} // Init
    nNoise = 0.0;
    for(iO = 1; iO <= octaves; iO++)
      {
      nNoise += cosinenoise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
      }
    return(nNoise);
}

// RANDOM

_randomseed = 0; // n Seed

randomseed: seed
{
    _randomseed = seed;
}

random
{
    n = (_randomseed * 214013 + 2531011) % 2^^24;
    _randomseed = n;
    n /= 2^^24; // 0..1
    return(n);
}

gaussianrandom
{
    n1 = random();
    n2 = random();
    if(n1 == 0.0){n1 = 0.01;}
    return(sqrt(-2.0 * log(n1)) * cos(2.0 * 3.1415926535 * n2));
}

// WRAP

wrap: min,max,n
{
    n = n - floor((n - min) / (max - min)) * (max - min);
    if(n < 0) n = n + max - min; // error check
    return(n);
}
All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs

Wednesday, 14 March 2012

LScript - Motion_SpotlightTrick


LScript (Layout) to anti-aliase shadow maps used on Spotlights. It works by implementing an old school technique of spinning (Spinning Light Trick) a light across a frame time inorder to offset sample positions. It helps reduce glitches and improves overall image quality. Apply it to a Spotlight in its Motion Options, enable motion blur and see what happens when you render.

Changes

  • Must have motionblur enabled with more than 1 pass
  • Attach to a spotlight
  • Enable shadow maps

Compatible with Newtek LightWave 9.6 and above.

// LScript Item Animation - www.StephenCulley.co.uk
//
// web   address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk

/*  
    LScript Item Animation - SpotlightTrick

    Motion_SpotlightTrick.ls

*/

@version 2.2
@warnings
@script motion
@name *Spotlight Trick

    // Title
    sTitle = "*Spotlight Trick";

    // Version
    sVersion = "v1.1";

    // Item
    Item = nil;

    // Variable
    bH = false;
    bP = false;
    bB = true;
    nAmount = 360.0;
    nSoftEdge = 0.0;   

create : id
{
    // Description
    setdesc(sTitle);
 
    // Info
    info("*Spotlight Trick - Motion blur must be enabled.");

    // Item
    Item = id; // Item
}

destroy
{
}

process: ma, frame, time
{     
    // Variables
    vPosition = ma.get(POSITION,time);
    vRotation = ma.get(ROTATION,time);
    vnForward = normalize3D(Item.getForward(time));

    if(Camera().blurLength(time) <> 0.0)
      {
      // Map Range
      n01 = maprange01(frame * (1 / Scene().fps),(frame + 1) * (1 / Scene().fps),time);

      // Position
      if(nSoftEdge <> 0.0){vPosition -= vnForward * ((10 / Camera().blurLength(time)) * nSoftEdge * n01);} 

      // Rotation
      nDegree = linear1D(0.0,(1 / Camera().blurLength(time)) * nAmount.0,n01);
      if(bH){vRotation.x += nDegree;} // H
      if(bP){vRotation.y += nDegree;} // P
      if(bB){vRotation.z += nDegree;} // B  
      } 

// ma

  ma.set(POSITION,vPosition);
  ma.set(ROTATION,vRotation);

}

// INTERPOLATION

linear1D: n1,n2,i // i = interpolation point (0-1)
{
    return(n1 * (1 - i) + n2 * i);     
}

// MAP RANGE

maprange01: n1,n2,i

{    
    if(n2-n1 == 0.0){return(0.0);}
  else
    {return((1/(n2-n1)) * (i-n1));}
}

// VECTOR 3D

magnitude3D: v // n
{
    // Vector
    return(sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z)));
}

normalize3D: v // v
{
    // Vector normalize to 0 - 1
    nMagnitude = magnitude3D(v);
    if(nMagnitude <> 0) nMagnitude = 1 / nMagnitude;
    return(v * nMagnitude);
}

load: what,io
{
    if(what == SCENEMODE)   // processing an ASCII scene file
    {
        if(io.read().asStr() == sTitle + " " + sVersion)
            {
            bH = io.read().asInt(); // H
            bP = io.read().asInt(); // P
            bB = io.read().asInt(); // B
            nAmount = io.read().asNum(); // Amount           
            nSoftEdge = io.read().asNum(); // Soft Edge           
            }
    }
}

save: what,io
{
    if(what == SCENEMODE)
    {
        // Header
        io.writeln(sTitle + " " + sVersion);

        io.writeln(bH); // H
        io.writeln(bP); // P
        io.writeln(bB); // B
        io.writeln(nAmount); // Amount
        io.writeln(nSoftEdge); // Soft Edge
    }
}

options
{
    if(reqisopen())
        {
        reqend();
        return;
        }

    reqbegin(sTitle + " " + sVersion);

    ctrl_c0 = ctlcheckbox("Spin H", bH);
    ctrl_c1 = ctlcheckbox("Spin P", bP);
    ctrl_c2 = ctlcheckbox("Spin B (Antialiase Shadow Map)", bB);
    ctrl_c3 = ctlangle("Amount",nAmount);   
    ctlsep();
    ctrl_c4 = ctlpercent("Soft Edge",nSoftEdge);   

    // Developer
    ctlsep();
    ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");

    // Refresh
    ctlrefresh(ctrl_c0,"refresh_c0"); // H
    ctlrefresh(ctrl_c1,"refresh_c1"); // P
    ctlrefresh(ctrl_c2,"refresh_c2"); // B
    ctlrefresh(ctrl_c3,"refresh_c3"); // Amount
    ctlrefresh(ctrl_c4,"refresh_c4"); // Soft Edge

    reqopen();
}

refresh_c0:value // H
{
    bH = value;
}

refresh_c1:value // P
{
    bP = value;
}

refresh_c2:value // B
{
    bB = value;
}

refresh_c3:value // Amount
{
    nAmount = value;
}

refresh_c4:value // Soft Edge
{
    nSoftEdge = value;
}


All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs