SimpleMLPStylingScript

From Second Life Wiki
Revision as of 13:22, 22 November 2012 by Tano Toll (talk | contribs) (<code> tag omitted from sl mediawiki, cheated with <lsl> tag.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Ok, bit of old and ugly code here. Publishing anyways as example.

What it does. This is an MLP plugin that allows styling of objects. Textures, colors, shinyness. Those are usually enough for most furniture.

Per link, you must describe in the link properties if it is subject to a particular styling paramaters. Those are: Color1, Color2, Texture and Shiny. They are represent as :C+: :C2+: :T+: and :S+: So, a linked prim, like a cushion, that is subject to color and texture, would read: :C+:T+: Another linked prim, like a wooden base, would be subject to color2 (wood shades) and shininess. It's description would read :C2+:S+:

You can activate the plugin by sending commands via a linked message on channel 13335 Example entry in MLP or TMCP notecard: <lsl> MENU Styling | OWNER LINKMSG Light Colors |1,-4,-13335,LightPalette LINKMSG Dark Colors |1,-4,-13335,Palette LINKMSG Adjust Color|1,-4,-13335,AdjustColor LINKMSG Fabric|1,-4,-13335,MenuTexture LINKMSG Wood Color |1,-4,-13335,WoodPalette //LINKMSG SomeTexture|0,-4,-13335,SetTexture:<uuid> //LINKMSG Color Menu|1,-4,-13335,MenuColor //LINKMSG Gray|0,-4,-13335,SetColor:<0.5,0.5,0.5> TOMENU Shadow LINKMSG Shiny Wood|0,-4,-13335,SetShiny:3 LINKMSG Satin Wood|0,-4,-13335,SetShiny:1 LINKMSG Pale Wood|0,-4,-13335,SetShiny:0 TOMENU Size BACK

MENU Shadow | ALL This example sets the root prim's alpha.. adjust link number to whatever the shadow texture was LINKMSG No Shadow|0,-4,-13335,SetAlpha:1:0 LINKMSG Light Shadow|0,-4,-13335,SetAlpha:1:0.5 LINKMSG Full Shadow|0,-4,-13335,SetAlpha:1:1.0 BACK

MENU Size | OWNER LINKMSG Grow|0,-4,-13335,ObjectGrow LINKMSG Shrink|0,-4,-13335,ObjectShrink BACK </lsl>

The styling script is as follows, and again, sorry for bit messy code.. Publishing anyways, might post an update. <lsl> //THIS SCRIPT ASSUMES A FEW THINGS //* THAT ITS CALLED / INITIATED BY MLP or something else that invokes a linked message //That the root prim is colorable just like all childs //That the root prim needs no (re)texturing but all childs do. //Must customize this script for color palette, textures, and/or menu stuff you want in or out - no external configuration

//+BRIGHT CONTRAST+ +SATURATION //-BRIGHT CONTRAST- -SATURATION //+RED //+BLUE //+GREEN //-RED //-BLUE //-GREEN

//PALETTE


vector myColor; //reads root prim color on startup integer channel; integer handle;

list Palette=[ "BORDEAUX", "PINK", "AQUA",

               "TEAL", "SKY", "NAVY", 
               "OKER", "BROWN", "CREAM",
               "BLACK", "GREY", "DARKBROWN"];
               

list PaletteC=[ <0.35,0,0>, <1,0.5,0.5>, <0.3,1.0,0.8>,

               <0,0.35,0.6>, <0.7,0.75,1>, <0,0,0.35>,
               <0.61,0.6,0.12>, <0.3,0.2,0.05>, <1.0,1.0,0.9>,
               <0.01,0.01,0.05>, <0.35,0.35,0.35>, <0.12,0.08,0>];

list PaletteLight=["BLUE1", "BLUE2", "BLUE3",

               "PINK1", "PINK2", "PINK3", 
               "GREEN1", "GREEN2", "CREAM1",
               "WHITE", "GREY2", "AMBER" ];
               

list PaletteL=[ <0.8,0.8,1.0>, <0.9,0.9,1.0>, <0.7,0.8,1.0>,

               <1.0,0.7,0.7>, <1.0,0.8,0.8>, <1.0,0.9,0.9>,
               <0.7,1.0,0.7>, <0.82,1.0,0.8>, <1.0,0.960,0.879>,
               <1.0,1.0,1.0>, <0.75,0.75,0.75>, <1.0, 0.9, 0.6>];
               

list PaletteWood =[ "Cherry", "Oak", "Mahogany",

                   "Pine", "Ebony", "Maple",
                   "OldOak", "Rosewood", "Elm",
                   "Walnut", "DarkWalnut", "Onyx"];

list PaletteW=[ <0.6,0.28,0.18>, <0.62,0.41,0.21>, <0.26,0.08,0.05>,

               <0.76,0.53,0.19>, <0.12,0.11,0.11>, <0.77,0.45,0.26>,
               <0.59,0.4,0.24>, <0.3,0.15,0.15>, <0.4,0.25,0.2>,
               <0.5,0.40,0.28>, <0.29,0.14,0.05>, <0.22,0.19,0.14>];


list Textures = [

   "d14c73dd-9844-3fec-3405-c2cfa6cfae92",
   "29e827fe-6d57-e155-eaed-236a58b71244",
   //"1ae6c524-9a2e-b3a5-6349-4b99dfd861a3",
   //"06811c28-baae-68f8-18b6-38c7819f977f",
   "3486effe-7ab4-d955-6b4f-a85a3325a287",
   //"9e14c601-a7b0-e0e3-585d-a494c320fa87",
   //"80d859fb-dab4-9446-2d79-2d2a9693759d"
   "59d84d87-6ff5-a1b7-3f3b-d45c09ac05c1",
   "a523d079-6e2e-5832-8ac5-30b8c6092508",
   "feddf1ac-8176-11fe-0bc1-696544037253",
   "12d82751-1cd1-8f25-166c-5e2bcb2ed2d6",
   "24cf6699-b625-c06c-b2cd-984b28eb09e0",
   "7b71d0bc-d329-b94e-2fa8-0b584ca0e80c",
   "d598017c-0f6a-42ec-52f6-899be6e82878",
   "ddd57884-5a7b-f658-c8ab-d34df5d6d38e",
   "3fda0baa-d584-7d22-ed54-3943ef26c37f"    

];

list TextureNames = [

   "Stripes",
   "Ghecko",
   //"Bleached",
   //"Modern",
   "LineArt",
   //"Flowers",
   //"Victorian"
   "Leaves",
   "Old green",
   "Classic Leaves",
   "African",
   "Worn",
   "Abstract",
   "Elephant",
   "Wave",
   "Leather"
   ];

string colorStr() {

   return "\nCurrent: [ R="+(string)llRound(100*myColor.x)+"  G="+(string)llRound(100*myColor.y)+"  B="+(string)llRound(100*myColor.z)+" ]";  

}

menuPalette (key id) {

   llDialog (id, "Choose a color"+colorStr(), llListSort(Palette,1,TRUE), channel);
   setListen();

} menuPaletteL (key id) {

   llDialog (id, "Choose a color"+colorStr(), llListSort(PaletteLight,1,TRUE), channel);

} menuWoodPalette (key id) {

   llDialog (id, "Choose a color"+colorStr(), llListSort(PaletteWood,1,TRUE), channel);

}

menuAdjust (key id) {

   llDialog (id, "Adjust color\nHint: use HUE for small color shifts."+colorStr(),
       [
        "- SATURATION", "- HUE", "+ HUE",
        "+ SATURATION", "- BLUE", "+ BLUE",
        "- BRIGHT", "- GREEN", "+ GREEN",
       "+ BRIGHT", "- RED", "+ RED"
        ],
        channel);    

} menuColor(key id) {

   llDialog(id, "Option", ["Adjust", "Palette", "Palette Light"], channel);    

}

menuTexture(key id) {

   /*
   list l;
   integer i=llGetListLength(Textures);
   for (;i;i--) {
       l+="Fabric "+(string)i;   
   }
   llDialog (id, "Select fabric", l, channel);
   */
   llDialog (id, "Select fabric", llListSort(TextureNames,1,TRUE), channel);

}

scale(float s) {

   if (s<0.10)
       return;
   llSetScale(s*llGetScale());       
   if (llGetNumberOfPrims()>1) {
       integer i;
       for (i=2; i<=llGetNumberOfPrims(); i++) {
           list l=llGetLinkPrimitiveParams(i, [PRIM_POS_LOCAL, PRIM_SIZE]);
           //llOwnerSay ("PP:"+(string)l);
           vector newpos=s*(llList2Vector(l,0));   
           vector newscale=s*llList2Vector(l,1);   
           if (newscale==ZERO_VECTOR) //something went wrong
               return;            
           llSetLinkPrimitiveParamsFast (i, [PRIM_POS_LOCAL, newpos, PRIM_SIZE, newscale]);            
       }
   }    

}

setColor (vector c) {

   //check bounds
   if (c.x < 0) c.x=0;
   if (c.x > 1) c.x=1;   
   if (c.y < 0) c.y=0;
   if (c.y > 1) c.y=1;   
   if (c.z < 0) c.z=0;
   if (c.z > 1) c.z=1;   
   myColor=c;
   if (llGetNumberOfPrims()==1)
       llSetColor(myColor, ALL_SIDES);
   else {
       integer i;
       for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
           string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
           if (-1!=llSubStringIndex(d, ":C+:"))
               llSetLinkColor(i, myColor, ALL_SIDES);
       }
   }

}

setColor2 (vector c) {

   //check bounds
   if (c.x < 0) c.x=0;
   if (c.x > 1) c.x=1;   
   if (c.y < 0) c.y=0;
   if (c.y > 1) c.y=1;   
   if (c.z < 0) c.z=0;
   if (c.z > 1) c.z=1;   
   myColor=c;
   if (llGetNumberOfPrims()==1)
       llSetColor(myColor, ALL_SIDES);
   else {
       integer i;
       for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
           string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
           if (-1!=llSubStringIndex(d, ":C2+:"))
               llSetLinkColor(i, myColor, ALL_SIDES);
       }
   }

}


setTexture (string texture) {

   if (llGetNumberOfPrims()==1)
       llSetTexture(texture, ALL_SIDES);   
   else {
       integer i;
       for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
           string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
           if (-1!=llSubStringIndex(d, ":T+:"))
               llSetLinkTexture(i, texture, ALL_SIDES);
       }
   }

}

setShiny (integer s) {

       integer i;
       for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
           string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
           if (-1!=llSubStringIndex(d, ":S+:"))
               llSetLinkPrimitiveParams(i, [PRIM_BUMP_SHINY, ALL_SIDES,s, 
                   //existing bumpmap:
                   llList2Integer(llGetLinkPrimitiveParams(i, [PRIM_BUMP_SHINY, ALL_SIDES]),1)
               ]);
       }

}


setListen() {

   llListenControl (handle, TRUE);
   llSetTimerEvent (0.0);
   llSetTimerEvent (120.0);

}


//funky color conv, tx Sally! vector RGB2HSV( vector rgb ) {

   float R = rgb.x;
   if (R<0)        // catch malformed input
       R=0;
   else if (R>1)
       R=1;
   float G = rgb.y;
   if (G<0)        // catch malformed input
       G=0;
   else if (G>1)
       G=1;
   float B = rgb.z;
   if (B<0)        // catch malformed input
       B=0;
   else if (B>1)
       B=1;

   float H;
   float S;
   float V;

   list rgbList = [R, G, B]; // list used to get min and max

   float min;
   float max;
   float achromatic;  // =1 if R=G=B
   float delta;

   vector hsv;  // the return HSV vector

   min = llListStatistics(LIST_STAT_MIN, rgbList); //MIN of ( R, G, B );
   max = llListStatistics(LIST_STAT_MAX, rgbList); //MAX of ( R, G, B );
   if (R==G && G==B)
       achromatic = 1;  // it is a shade of grey, white or black
   else
       achromatic = 0;

   V = max;                    // V = brightness Value form 0 to 1
   delta = max - min;

   if( max != 0 )
       S = delta / max;        // S = saturation from 0 to 1
   else {
       // R = G = B = 0        // S = 0, V = 0, H = 0
       S = 0;                  
       V = 0;                  
       H = 0;

       hsv.x = H;
       hsv.y = S;
       hsv.z = V;
       return hsv;             //H = S = V = 0
   }

   if (achromatic == 1)
       H = 0;
   else if( R == max )
       H = 0 + ( G - B ) / delta;    // between red & yellow
   else if( G == max )
       H = 2 + ( B - R ) / delta;    // between yellow & cyan
   else
       H = 4 + ( R - G ) / delta;    // between cyan & red


   H *= 60;                          // H is traditionally a figure between 0 and 360 degrees
   if( H < 0 )
       H += 360;

   hsv.x = H;
   hsv.y = S;
   hsv.z = V;
   return hsv;

}

vector HSV2RGB( vector hsv ) {

   integer i;

    float H = hsv.x;
    while (H<0)        // catch malformed H input
       H+=360;
    while (H>=360)
       H-=360;
    float S = hsv.y;
    if (S<0)        // catch malformed S input
   S=0;
    else if (S>1)
   S=1;
    float V = hsv.z;
    if (V<0)        // catch malformed V input
   V=0;
    else if (V>1)
   V=1;

   float R;
   float G;
   float B;

   float f;         // variables for calculating base color mixing around the "spectrum circle"
   float p;
   float q;
   float t;

   vector rgb;

   if( S == 0 ) {  // achromatic (grey) simply set R,G, & B = Value
       R = V;
       G = V;
       B = V;

       rgb.x = R;
       rgb.y = G;
       rgb.z = B;
       return rgb;
   }

   H /= 60;              // Hue factored into range 0 to 5
   i = llFloor( H );      // integer floor of Hue
   f = H - i;            // factorial part of H

   p = V * ( 1 - S );
   q = V * ( 1 - S * f );
   t = V * ( 1 - S * ( 1 - f ) );

   if (i==0){
       R = V;
       G = t;
       B = p;
   } else if (i==1){
       R = q;
       G = V;
       B = p;
   } else if (i==2){
       R = p;
       G = V;
       B = t;
   } else if (i==3){
       R = p;
       G = q;
       B = V;
   } else if (i==4){
       R = t;
       G = p;
       B = V;
   } else {       
       R = V;
       G = p;
       B = q;
   }

   rgb.x = R;
   rgb.y = G;
   rgb.z = B;

   return rgb;

}


default {

   state_entry()
   {
       myColor = llGetColor(ALL_SIDES);
       integer i;
       for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
           string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
           if (-1!=llSubStringIndex(d, ":C+:")) {
               myColor=llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_COLOR, ALL_SIDES]),0);
           }
       }
       
       
       //llOwnerSay("Color: "+(string)myColor);
       channel=10000+llRound(llFrand(320932));
       handle=llListen(channel, "", "", "");
       llListenControl(handle, FALSE);
   }
   
   on_rez(integer n) {
       llResetScript();   
   }


   link_message(integer ch, integer n, string data, key id) {
       if (n==-13335) {
           //hack.. just don't flood this please (...)
           //but we try to get this menu on top of MLP menu
           //llSleep (1.0);
           
           list l=llParseString2List(data, [":"], []);
           string d=llList2String(l,0);
           string p=llList2String(l,1);
           //interesting, styling command
           setListen();
           if (d=="MenuColor")
               menuColor(id);
           else if (d=="MenuTexture")
               menuTexture(id);
           else if (d=="ObjectGrow")
               scale(1.05);
           else if (d=="ObjectShrink")
               scale(1.0/1.05);
           else if (d=="Palette")
               menuPalette(id);
           else if (d=="LightPalette")
               menuPaletteL(id);    
           else if (d=="WoodPalette")
               menuWoodPalette(id);    
           else if (d=="AdjustColor")
               menuAdjust(id);
           else if (d=="SetTexture") {
               //we really need a texture handle that'd perfectly fit
               setTexture(p);   
           } else if (d=="SetColor") {
               setColor ((vector)p);   
           } else if (d=="SetColor2") {
               setColor2 ((vector)p);   
           } else if (d=="SetAlpha") {
               llSetLinkAlpha((integer)p, (float)llList2String(l, 2), ALL_SIDES);   
           } else if (d=="SetShiny") {
               setShiny((integer)p);   
           } else if (d=="Shiny") {
               llSetLinkPrimitiveParams((integer)p, [PRIM_BUMP_SHINY, ALL_SIDES,(integer)llList2String(l,2), 
                   //existing bumpmap:
                   llList2Integer(llGetLinkPrimitiveParams((integer)p, [PRIM_BUMP_SHINY, ALL_SIDES]),1)
               ]);
           } else if (d=="Link___") {
               //template for any value on any link..
               llSetLinkPrimitiveParamsFast((integer)p, [(integer)llList2String(l,2), (float)llList2String(l,3)]);
           }
           
       }   
   }
   
   listen (integer ch, string n, key id, string d) {
       
       //only listen to agents
       if (llGetAgentSize(id)); else return; 
       
       //user still active; assume no other spam on this channel        
       setListen();
       
       if (d=="<<BACK")
           menuColor(id);
       else if (d=="Adjust")
           menuAdjust(id);
       else if (d=="Palette")
           menuPalette(id);
       else if (d=="Palette Light")
           menuPaletteL(id);
       else {
           integer i=llListFindList(Palette+PaletteLight, [d]);
           if (i>=0) {
               //set color to palette entry
               setColor(llList2Vector(PaletteC+PaletteL, i));
               if (-1!=llListFindList(Palette, [d]))
                   menuPalette(id);
               else
                   menuPaletteL(id);
               return;    
           }
           i=llListFindList(PaletteWood, [d]);
           if (i>=0) {
               //set color to palette entry
               setColor2(llList2Vector(PaletteW, i));
               menuWoodPalette(id);
               return;    
           }
           
                 
           list m=llParseString2List(d, [" "], []);
           string o=llList2String(m,0);
           string p=llList2String(m,1);
           
           if ((o=="-") || (o=="+")) {
               float f=-1.0;
               if (o=="+")
                   f=1.0;
               if (p=="BRIGHT")
                   setColor(0.05*f*<1,1,1> + myColor);
               else if (p=="SATURATION")
                   //setColor(myColor + 0.05*f*(myColor-<0.55,0.55,0.55>));
                   setColor (HSV2RGB(<0,0.075*f,0>+RGB2HSV(myColor)));
               else if (p=="RED")
                   setColor(f*<0.05,0,0> + myColor);
               else if (p=="GREEN")
                   setColor(f*<0,0.05,0> + myColor);
               else if (p=="BLUE")
                   setColor(f*<0,0,0.05> + myColor);
               else if (p=="HUE")
                   setColor (HSV2RGB(<15.0*f,0,0>+RGB2HSV(myColor)));
               menuAdjust(id);
               return;
           }
           /*
           if (o=="Fabric") {
               setTexture(llList2String(Textures, (integer)p-1));
               menuTexture(id);
           }
           */
           i=llListFindList(TextureNames, [d]);
           if (i>=0) {
               setTexture (llList2String(Textures, i));
               menuTexture(id);   
           }
           
       }
   }
   
   timer() {
       llSetTimerEvent(0.0);
       llListenControl (handle, FALSE);   
   }

}

</lsl>

Happy scripting.