Link-Set Texture Configuration ( V2 )

Written by Kitsune

For example - We have a piece of furniture with 5 frame prims and 4 cushion prims.

    https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); color: rgb(0, 0, 0); font-family: verdana, helvetica, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">
  • You want the frame to have 4 texture options -
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • Dark Wood
    • Light Wood
    • Aluminium
    • Shiny Black
  • And the cushions have 4 texture options -
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • Pink Damasque
    • Green Twill
    • Black Fur
    • Crimson Velour

You want these options to be available to choose from -

    https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); color: rgb(0, 0, 0); font-family: verdana, helvetica, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">
  • Dark Wood frame with Crimson Velour cushions.
  • Light Wood frame with Pink Damasque cushions.
  • Aluminium frame with Green Twill cushions.
  • Shiny Black frame with Black Fur cushions.
  • Dark Wood frame with Pink Damasque cushions.
  • Light Wood frame with Green Twill cushions.
  • Aluminium frame with Black Fur cushions.
  • Shiny Black frame with Crimson Velour cushions.
  • Dark Wood frame with Green Twill cushions.
  • Light Wood frame with Black Fur cushions.
  • Aluminium frame with Crimson Velour cushions.
  • Shiny Black frame with Pink Damasque cushions.

Put this script in any prim in the set. If you put it in the root prim, the whole object will become touchable. This may be undesirable. If the script is in any other prim in the set, only that prim will be touchable (unless you have other touch active scripts in the object). The script responds to its owner only. It will reset if the owner changes so that the new owner can control it.

  1. Set the object manually to one of the texturing configurations.
  2. Set your Viewer Preferences > Text Chat > Chat Options > Show Timestamp in Local Chat to OFF (uncheck that option).
  3. Click the prim with this script in it.
  4. A dialog will appear, click the "Config" button.
  5. A load of data will be chatted to you.
  6. Copy from your local chat history all the text between "!!!!!!!!!!----CONFIGURATION START----!!!!!!!!!!" & "!!!!!!!!!!----CONFIGURATION END----!!!!!!!!!!". Don't include those two lines. Since this is local chat (and the script is cleaner without automatic removal) you'll need to check there is no unwanted chat mixed up in the object data chat.
  7. Paste that text into an otherwise clean Notecard (no other text in the card).
  8. Name it. The Notecard name needs to be short enough to be the name of that configuration option when offered on a dialog button.
  9. Set the object manually to another of the texturing configurations.
  10. Repeat these steps until all the configurations (Maximum of 12) are stored to Notecards.

Once all the Notecards are saved and named, drop them all into the same prim contents as the script. That's it. Now when the prim is clicked a dialog will appear offering the options, taking the names for each option from the Notecards the script finds.

    https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); color: rgb(0, 0, 0); font-family: verdana, helvetica, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">
  • To add new configurations after adding Notecards to the prim, you'll need to remove the Notecards already in the contents and add them again after creating the new Notecards. In other words, If the prim has any Notecards in it, it will offer the options. If the prim has no Notecards in it, it will offer the "Config" button.
  • The change from one configuration to another can be very slow (depending on the number of prims and the number of faces of each prim etc).
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • This slowness is a trade off. The main advantages are -
        https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
      • The script doesn't use a vast amount of memory ("Memory use is bad, M'kay?").
      • There are not loads of scripts. Just one script for the whole object.
      • Dramatically different texturing is as simple to apply as slight changes.
    • This isn't designed for dynamic effect. It is for simply changing decoration. Speed is hardly important when changing the color of an arm chair after all.

All texture parameters are catered for. Every individual face separately.

    https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); color: rgb(0, 0, 0); font-family: verdana, helvetica, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">
  • Texture
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • UUID
    • Repeats
    • Offsets
    • Rotations
  • Color
  • Alpha
  • Mapping
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • Default or Planar
  • Shiny
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • High, Medium, Low or None
  • Bump Mapping
      https://d1yjxggot69855.cloudfront.net/skins/monobook/bullet.gif); ">
    • All the bumpy options are recorded
  • Fullbright
  • Glow

This is early days for this idea (I may possibly rework it sometime) and there are limits. The amount of data that can be stored to a Notecard being one of them. Very large prim-count objects with complex prims (hollowed and path cut boxes having up to 9 faces for example) may create too much data to be stored to one Notecard. Sorry bout that. - Fred Gandt

 

 

// V2 //
 
SpewConfig(integer nol)
{
    llSetObjectName("");
    llOwnerSay("/me /n!!!!!!!!!!----CONFIGURATION START----!!!!!!!!!!");
    integer ln = 1;
    do
    {
        list s = [];
        list p = [];
        integer c = 0;
        integer f = 0;
        integer l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [17, -1])));
        do
        {
            llOwnerSay("/me " + llDumpList2String([17, (f++)] + llList2List(s, c, (c + 3)), ","));
            c += 4;
        }
        while(c < l);
        c = 0;
        f = 0;
        l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [18, -1])));
        do
        {
            llOwnerSay("/me " + llDumpList2String([18, (f++)] + llList2List(s, c, (c + 1)), ","));
            c += 2;
        }
        while(c < l);
        c = 0;
        f = 0;
        l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [19, -1])));
        do
        {
            p += [19, (f++)] + llList2List(s, c, (c + 1));
            c += 2;
        }
        while(c < l);
        llOwnerSay("/me " + llDumpList2String(p, ","));
        p = [];
        c = 0;
        f = 0;
        l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [20, -1])));
        do
        p += [20, (f++)] + llList2List(s, c, c);
        while((++c) < l);
        llOwnerSay("/me " + llDumpList2String(p, ","));
        p = [];
        c = 0;
        f = 0;
        l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [22, -1])));
        do
        p += [22, (f++)] + llList2List(s, c, c);
        while((++c) < l);
        llOwnerSay("/me " + llDumpList2String(p, ","));
        p = [];
        c = 0;
        f = 0;
        l = llGetListLength((s = llGetLinkPrimitiveParams(ln, [25, -1])));
        do
        p += [25, (f++)] + llList2List(s, c, c);
        while((++c) < l);
        llOwnerSay("/me " + llDumpList2String(p, ","));
        llOwnerSay("/me LINK");
    }
    while((++ln) <= nol);
    llOwnerSay("/me !!!!!!!!!!----CONFIGURATION END----!!!!!!!!!!\n");
    llSetObjectName(my_name);
}
 
list TypeCast(list p)
{
    list P = [];
    list c = [];
    integer int = 0;
    integer count = 0;
    integer length = llGetListLength(p);
    do
    {
        if((int = ((integer)llList2String((c = llCSV2List(llList2String(p, count))), 0))) == 17)
        {
            P += [int, ((integer)llList2String(c, 1)),
                       ((key)llList2String(c, 2)),
                       ((vector)llList2String(c, 3)),
                       ((vector)llList2String(c, 4)),
                       ((float)llList2String(c, 5))];
        }
        else if(int == 18)
        {
            P += [int, ((integer)llList2String(c, 1)),
                       ((vector)llList2String(c, 2)),
                       ((float)llList2String(c, 3))];
        }
        else
        {
            integer l = (llGetListLength(c) - 1);
            integer i = -1;
            if(int == 19)
            {
                do
                {
                    ++i;
                    P += [int, ((integer)llList2String(c, (++i))),
                               ((integer)llList2String(c, (++i))),
                               ((integer)llList2String(c, (++i)))];
                }
                while(i < l);
            }
            else if((int == 20) | (int == 22))
            {
                do
                {
                    ++i;
                    P += [int, ((integer)llList2String(c, (++i))),
                               ((integer)llList2String(c, (++i)))];
                }
                while(i < l);
            }
            else if(int == 25)
            {
                do
                {
                    ++i;
                    P += [int, ((integer)llList2String(c, (++i))),
                               ((float)llList2String(c, (++i)))];
                }
                while(i < l);
            }
        }
    }
    while((++count) < length);
    return P;
}
 
key iq;
 
key owner;
 
integer lis;
 
integer link;
 
integer nclc;
 
list params = [];
 
string my_name = "";
 
integer channel = -4756297; // The channel for dialog coms. Keep it negative and in the millions.
 
string present = "Default"; // The name of your default configuration NC
 
default
{
    state_entry()
    {
        owner = llGetOwner();
        my_name = llGetObjectName();
    }
    touch_start(integer nd)
    {
        if(llDetectedKey(0) == owner)
        {
            integer inn = llGetInventoryNumber(INVENTORY_NOTECARD);
            if(inn)
            {
                list ncn = [];
                while(inn)
                ncn += [llGetInventoryName(INVENTORY_NOTECARD, (--inn))];
                llListenRemove(lis);
                lis = llListen(channel, llKey2Name(owner), owner, "");
                llDialog(owner, ("\n\nChoose your texture configuration.\nThe present configuration is - \"" + present + "\""), ncn, channel);
                llSetTimerEvent(60.0);
            }
            else
            {   // Could just jump right to it but, this stops accidental activation.
                llListenRemove(lis);
                lis = llListen(channel, llKey2Name(owner), owner, "Config");
                llDialog(owner, "\n\nClick \"Config\" when the objects texturing is set.", ["Config"], channel);
                llSetTimerEvent(10.0);
            }
        }
    }
    timer()
    {
        llSetTimerEvent(0.0);
        llListenRemove(lis);
        llOwnerSay("The listen has been removed by timer.");
    }
    dataserver(key q, string data)
    {
        if((q == iq) && (data != EOF))
        {
            if((data = llStringTrim(data, STRING_TRIM)) != "LINK")
            params += [data];
            else
            {
                llSetLinkPrimitiveParamsFast((++link), TypeCast(params));
                params = [];
            }
            iq = llGetNotecardLine(present, (++nclc));
        }
    }
    listen(integer chan, string name, key id, string msg)
    {
        llSetTimerEvent(0.0);
        llListenRemove(lis);
        if(msg == "Config")
        SpewConfig(llGetObjectPrimCount(llGetKey()));
        else
        {
            params = [];
            link = 0;
            iq = llGetNotecardLine((present = msg), (nclc = 0));
        }
    }
    changed(integer change)
    {
        if(change & (CHANGED_OWNER | CHANGED_INVENTORY))
        llResetScript();
    }
}