Difference between revisions of "User:Clarknova Helvetic/Clone Primitive v2.0"

From Second Life Wiki
Jump to navigation Jump to search
(I didn't know about the <lsl> tag! Sweet! (also v3 now supports sculpties))
Line 1: Line 1:
'''Clone Primitive v2.<u>2</u>'''  is a Total, End-2-End virtual object replication solution for the simulated cyberspace known to its tecnocrati "netziens" as ''Second Life''.
'''Clone Primitive v2.<u>3</u>'''  is a Total, End-2-End virtual object replication solution for the simulated cyberspace known to its tecnocrati "netziens" as ''Second Life''.


Shoot me.
Shoot me.
Line 20: Line 20:
Why would you need this?  You don't.    Maybe.  It does essentially the same thing as shift-copy, which most people learn on their third day.   
Why would you need this?  You don't.    Maybe.  It does essentially the same thing as shift-copy, which most people learn on their third day.   


However, it does one nice thing, which is to print out all your primitive params in a format that's easy to plug into other scripts scripts with [[llSetPrimitiveParams|llSetPrimitiveParams([])]] or [[llSetLinkPrimitiveParams|llSetLinkPrimitiveParams([])]] transformation functions.
However, it does one nice thing, which is to print out all your primitive params in a format that's easy to plug into other scripts using [[llSetPrimitiveParams|llSetPrimitiveParams([])]] and [[llSetLinkPrimitiveParams|llSetLinkPrimitiveParams([])]] transformation functions.


I'm sure people like [[Cubey Terra|Cubey]] and Horizons have scripts like these that spit out parameter codeblocks for use in their morphing rezzer gizmos.
I'm sure people like [[Cubey Terra|Cubey]] and Horizons have scripts like these that spit out parameter codeblocks for use in their morphing rezzer gizmos.
Line 31: Line 31:
<lsl> ///////////////////////////////////////////////////////////////////
<lsl> ///////////////////////////////////////////////////////////////////
//
//
//          END - TO - END PRIM CLONER  v 2.2
//          END - TO - END PRIM CLONER  v 2.3
//
//
//
//
Line 125: Line 125:


float  pause  =  .1  ; //// Change this to change the delay between each printed line.
float  pause  =  .1  ; //// Change this to change the delay between each printed line.
  //// The laggier the server the more delay you'll need to  
                          //// The laggier the server the more delay you'll need to  
  //// prevent line mix-up.
                          //// prevent line mix-up.




Line 161: Line 161:
default
default
{
{
state_entry()
    state_entry()
{
    {


   
say("COPY/PASTE THE CODE BELOW INTO A *BLANK* SCRIPT TO CLONE THIS PRIM: \n\n");  // Announce what we're doing
    say("COPY/PASTE THE CODE BELOW INTO A *BLANK* SCRIPT TO CLONE THIS PRIM: \n\n");  // Announce what we're doing
   
// We're going to change the object's name to a null string to make the output easier to read.
    // We're going to change the object's name to a null string to make the output easier to read.
string object_name = llGetObjectName(); // Store the object's name so we can set it back when done
    string object_name = llGetObjectName(); // Store the object's name so we can set it back when done
llSetObjectName("");
    llSetObjectName("");
   
// Guess we should transfer the description too
    // Guess we should transfer the description too
string object_desc = llGetObjectDesc();
    string object_desc = llGetObjectDesc();
   
//  Print the script header up to state_entry
    //  Print the script header up to state_entry
say("\ndefault\n{\n    state_entry()\n        {\n        list params;\n        \n\n        // If you are cutting code out to paste into custon functions\n        // Define \"params\" as a global list and start cutting below this line.\n\n        params =\n");
    say("\ndefault\n{\n    state_entry()\n        {\n        list params;\n        \n\n        // If you are cutting code out to paste into custon functions\n        // Define \"params\" as a global list and start cutting below this line.\n\n        params =\n");
   
   


   
// Add some comments to the script  
    // Add some comments to the script  


// [12:56]  Tali Rosca: It uses the C-style thing about an assignment also being an expression with a value.
    // [12:56]  Tali Rosca: It uses the C-style thing about an assignment also being an expression with a value.
// [12:56]  Tali Rosca: Why it actually saves memory still baffles my mind, though.
    // [12:56]  Tali Rosca: Why it actually saves memory still baffles my mind, though.
   
// list of the the first: paramater constants as strings, then thier integer value.
    // list of the the first: paramater constants as strings, then thier integer value.
list Param_Names = ["PRIM_TYPE",PRIM_TYPE,"PRIM_MATERIAL",PRIM_MATERIAL,"PRIM_PHYSICS",PRIM_PHYSICS,"PRIM_TEMP_ON_REZ",PRIM_TEMP_ON_REZ,"PRIM_PHANTOM",PRIM_PHANTOM,"PRIM_POSITION",PRIM_POSITION,"PRIM_ROTATION",PRIM_ROTATION,"PRIM_SIZE",PRIM_SIZE];
    list Param_Names = ["PRIM_TYPE",PRIM_TYPE,"PRIM_MATERIAL",PRIM_MATERIAL,"PRIM_PHYSICS",PRIM_PHYSICS,"PRIM_TEMP_ON_REZ",PRIM_TEMP_ON_REZ,"PRIM_PHANTOM",PRIM_PHANTOM,"PRIM_POSITION",PRIM_POSITION,"PRIM_ROTATION",PRIM_ROTATION,"PRIM_SIZE",PRIM_SIZE];




// ASIDE:
            // ASIDE:
// Prim params are of two types: Object-Specific and Face-Specific.
            // Prim params are of two types: Object-Specific and Face-Specific.
//
            //
// I'd Like to group them together according to type, but LsL doesn't
            // I'd Like to group them together according to type, but LsL doesn't
// nor does wiki.secondlife, and I am sworn to complete my destiny...
            // nor does wiki.secondlife, and I am sworn to complete my destiny...
//
            //
// This is probably for historical reasons (the param order, not my  
            // This is probably for historical reasons (the param order, not my  
// ultimate destiny).
            // ultimate destiny).
           
   
integer i; // You're going to see a lot of use, integer i!
    integer i; // You're going to see a lot of use, integer i!
integer length; // So are you, integer length!
    integer length; // So are you, integer length!
   
length = (llGetListLength(Param_Names)); // I'm way lazy.  Let's make LsL do basic math for us.
    length = (llGetListLength(Param_Names)); // I'm way lazy.  Let's make LsL do basic math for us.
   
for ( i = 0 ; i < length ; i = i +2) // This is may answer to list strides.  Take that!
    for ( i = 0 ; i < length ; i = i +2) // This is may answer to list strides.  Take that!
{
    {
if (i > length -3 ) // If we're at the last stride
        if (i > length -3 ) // If we're at the last stride
{
        {
saynd(param(llList2String(Param_Names,length -2), llList2Integer(Param_Names,length -1))) ; // Fecth the constants out of Param_Names.
            saynd(param(llList2String(Param_Names,length -2), llList2Integer(Param_Names,length -1))) ; // Fecth the constants out of Param_Names.
i = length;
            i = length;
}
        }
else if (i == 0) { sayn("[\n          " + param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1))); }
        else if (i == 0) // PRIM_TYPE is a special case.  But then what isn't?
else if (i < length -3 && i != length -6 ) sayn(param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) ) ;
        {  
else if (i < length -3 && i == length -6 )
            //  Checking if it's a sculptie in a rather extravagant way,
{
            //  but I also want to check my work.
say("        // It's probably not a god idea to have your new prim jump to the old one\n        // " + param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) + " ] + (params = []) +");  
           
            integer j = llList2Integer(Param_Names,i+1); // What's the param we're checking?
}
            list r = llGetPrimitiveParams([j]); // What are its values?
}
            integer t = llList2Integer(r,0); // What's the first value?
Param_Names = []; // Free up some memory


// I reallllly want our script to set all of the paramaters at once, with one llSetPrimitiveParams()  
            if (t == 7) // if it's a sculptie
// call at the end of the script but we can't because of bugs in LsL. 
            {
//
                sayn("[\n        PRIM_TYPE,"+ (string)t + ",\""+ llList2String(r,1) + "\"," + llList2String(r,2) );  
// See  https://jira.secondlife.com/browse/SVC-38  for more info.  Please vote to fix it.
               
            }
say("");
            else sayn("[\n        " + param(llList2String(Param_Names,i), j));
        }
comment("Set all of the above paramaters as a group.");
        else if (i < length -3 && i != length -6 ) sayn(param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) ) ;
define();
        else if (i < length -3 && i == length -6 )
        {
say("");
            say("        // It's probably not a god idea to have your new prim jump to the old one\n        // " + param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) + " ] + (params = []) +");
comment("We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others \n      // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.\n      // Please vote to fix it. \n");
       
        }
 
    }
//// Okay, now for the hard stuff: 4 out of 5 of the Face-Specific params, starting with the hardest:
   
//// PRIM_TEXTURE.  Why is PRIM_TEXTURE a pain?  Because llSetPrimitiveParams wants it in qoutes, but
    Param_Names = []; // Free up some memory
//// llGetPrimitiveParams doesn't give it to us in quotes.  It's a pickle.
////
//// The Face-Specific params each need thier own For loop because the number of faces is variable
//// from prim to prim.  A simple sphere only has one.  A tube can have up to 9.
integer sides = llGetNumberOfSides();  // So here we find out how many faces we've got
comment("This prim has " + (string)sides + " faces.\n"); // Don't care enough to correct for the singular :)


    // I reallllly want our script to set all of the paramaters at once, with one llSetPrimitiveParams()
    // call at the end of the script but we can't because of bugs in LsL. 
    //
    // See  https://jira.secondlife.com/browse/SVC-38  for more info.  Please vote to fix it.
   
    say("");
   
    comment("Set all of the above paramaters as a group.");
    define();
   
    say("");
    comment("We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others \n      // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.\n      // Please vote to fix it. \n");
           
                             
    //// Okay, now for the hard stuff: 4 out of 5 of the Face-Specific params, starting with the hardest:
    //// PRIM_TEXTURE.  Why is PRIM_TEXTURE a pain?  Because llSetPrimitiveParams wants it in qoutes, but
    //// llGetPrimitiveParams doesn't give it to us in quotes.  It's a pickle.
    ////
    //// The Face-Specific params each need thier own For loop because the number of faces is variable
    //// from prim to prim.  A simple sphere only has one.  A tube can have up to 9.
   
   
    integer sides = llGetNumberOfSides();  // So here we find out how many faces we've got
       
    comment("This prim has " + (string)sides + " faces.\n"); // Don't care enough to correct for the singular :)


///  PRIM_TEXTURE ///


say( "      params =\n        [\n");
        /// PRIM_TEXTURE ///
for (i = 0 ; i < sides ; ++i)  
list r =llGetPrimitiveParams([PRIM_TEXTURE,i]);
string s =
"\""  + llList2String(r,0) + "\"" // First element is the texture key.
+ ","
+ llList2String(r,1)
+ ","
+ llList2String(r,2)
+ ","
+ llList2String(r,3) ;
if (i < sides -1)  s = s + " , " ;
else if (i == sides -1)  s = s + "\n        ];";
say("      PRIM_TEXTURE," + (string)i + "," + s );   


        say( "      params =\n        [\n");
        for (i = 0 ; i < sides ; ++i) 
        { 
           
            list r =llGetPrimitiveParams([PRIM_TEXTURE,i]);
            string s =
            "\""  + llList2String(r,0) + "\"" // First element is the texture key.
            + ","
            + llList2String(r,1)
            + ","
            + llList2String(r,2)
            + ","
            + llList2String(r,3) ;
           
            if (i < sides -1)  s = s + " , " ;
            else if (i == sides -1)  s = s + "\n        ];";
                       
            say("      PRIM_TEXTURE," + (string)i + "," + s );   


// Local variables aren't cleared when we leave thier scope.  Can you believe that crap?
r = []; s = "";
}


            // Local variables aren't cleared when we leave thier scopeCan you believe that crap?
define();
            r = []; s = "";  
   
comment("Note that you -cannot- define textures and colors in the same call!\n      // If you're cutting out these params for your custom code watch out for this.\n"); 
        }
       
/// PRIM_COLOR ///
say( "      params =\n        [\n");
for (i = 0 ; i < sides ; ++i) 


if (i < sides -1 ) sayn("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i));
       
if (i == sides -1 ) saynd("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i));
        define();
}
       
define();
        comment("Note that you -cannot- define textures and colors in the same call!\n      // If you're cutting out these params for your custom code watch out for this.\n");  
   
       
///  PRIM_BUMP_SHINY ///
        ///  PRIM_COLOR ///
say( "     params =\n        [\n");
        say( "     params =\n        [\n");
for (i = 0 ; i < sides ; ++i) 
        for (i = 0 ; i < sides ; ++i)   
        {   
if (i < sides -1 ) sayn("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i) );
if (i == sides -1 ) saynd("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i));
}
define();
 
///  PRIM_FULLBRIGHT ///
 
say( "      params =\n      [\n");
for (i = 0 ; i < sides ; ++i) 
sayn("PRIM_FULLBRIGHT," + (string)i + "," + fsp(PRIM_FULLBRIGHT,i));
}
////  Now back to an Object-Specific paramaters : Flexible & Shadows
////  Remember that I'm going in this screwy order so that our
////  Code matches the table on http://wiki.secondlife.com/wiki/LlSetPrimitiveParams
sayn(param( "PRIM_FLEXIBLE",21));
sayn("// " + param( "PRIM_CAST_SHADOWS",24));
 
 
//// Now for one more Face-Specific paramater
///  PRIM_TEXGEN ///    
// Planar mapping is for correcting the what circular surfaces do to textures
// The default value for all faces is 0 ( distored )
// So we will only uncomment lines that carry a value of 1 ( corrected )
//  And we make a note of that in the output script here
comment("Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.\n      // Most builds don't use it, so it's commented out to save bytes in auto-transform code.\n        // The default value is 1 (distorted).\n       // if you are metamorphing an object that already had planar mapping (rare)\n      // uncomment those 0 lines.\n      // This may not seem like much savings\n      //  but if your script is trying to metamorph between as many as five objects\n      // those few bytes saved might come in handy at the end.\n\n      // If your textures are coming out with the offsets all wrong, try uncommenting them.");
for (i = 0 ; i < sides ; ++i)   
{   
list r = llGetPrimitiveParams([PRIM_TEXGEN,i]);
if (llList2Integer(r,-1) == 0) say("        // PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");
if (llList2Integer(r,-1) == 1) say("        PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");   
}
/// The last paramater is Object-Specific
saynd("PRIM_POINT_LIGHT," + osp(PRIM_POINT_LIGHT) );
say("        llSetPrimitiveParams(params);\        params = [];");  //  Print the final function call, braces & some blank lines
say("\n\n        // If you were cut/pasting this code into a custom transform function\n        // end your cut above this comment.\n        // Otherwise ignore this.\n\n        llSetObjectName(\"" + object_name + "\");\n");  // Make the target's name match this one
say("\n        llSetObjectDesc(\"" + object_name + "\");\n");  // Make the target's desc match this one
comment("This next line deletes the script.  Comment it out if you want the script to persist");
say("\n        llRemoveInventory(llGetScriptName());\n    }\n}\n\n\n");  // Remove the cloning script when done
 
llSetObjectName(object_name); // Change our object's name back.
say("Don't forget to remove the \"[HH:MM]  :\" timestamp at the beginning of each line.  Use Find/Replace  :)"); // Remind us to remove prefixes.)
llRemoveInventory(llGetScriptName());  // Delete this script.
}
}</lsl>
 
Well thet shoor is a lotta code!  Most of it whitespace and comments.
 
== Sample Output ==


            if (i < sides -1 ) sayn("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i));
            if (i == sides -1 ) saynd("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i));
        }
        define();
       
       
        ///  PRIM_BUMP_SHINY ///
        say( "      params =\n        [\n");
        for (i = 0 ; i < sides ; ++i) 
        { 
            if (i < sides -1 ) sayn("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i) );
            if (i == sides -1 ) saynd("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i));
   
        }
        define();


Here's an example of the output. This will make a shiny, metallic mobius strip.
        /// PRIM_FULLBRIGHT ///
       


    default
        say( "      params =\n      [\n");
    {
         for (i = 0 ; i < sides ; ++i)
         state_entry()
        {  
            {
            sayn("PRIM_FULLBRIGHT," + (string)i + "," + fsp(PRIM_FULLBRIGHT,i));  
            list params;
           
      
      
            // If you are cutting code out to paste into custon functions
        }
            // Define "params" as a global list and start cutting below this line.
       
       
    ////  Now back to an Object-Specific paramaters : Flexible & Shadows
    ////  Remember that I'm going in this screwy order so that our
    ////  Code matches the table on http://wiki.secondlife.com/wiki/LlSetPrimitiveParams
      
      
            params =
       
    sayn(param( "PRIM_FLEXIBLE",21));
    sayn("// " + param( "PRIM_CAST_SHADOWS",24));
       
 
      
      
            [
 
              PRIM_TYPE,4,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.500000, -0.500000, 0.000000>,<0.250000, 0.050000, 0.000000>,<0.000000, -0.100000, 0.000000>,<0.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,1.000000,0.000000,0.000000 ,
            PRIM_MATERIAL,2 ,
            PRIM_PHYSICS,0 ,
            PRIM_TEMP_ON_REZ,0 ,
            PRIM_PHANTOM,2 ,
            // It's probably not a god idea to have your new prim jump to the old one
            // PRIM_POSITION,<80.725319, 41.797234, 233.014313> ] + (params = []) +
            PRIM_ROTATION,<-0.378789, 0.297200, -0.082870, 0.872539> ,
            PRIM_SIZE,<1.072797, 1.206897, 1.072797>
            ];
   
   
          // Set all of the above paramaters as a group.
            llSetPrimitiveParams(params);
            params = [];
   
   
          // We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others
          // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.
          // Please vote to fix it.
      
      
   
    //// Now for one more Face-Specific paramater
          // This prim has 3 faces.
      
      
          params =
        ///  PRIM_TEXGEN ///   
             [
       
        // Planar mapping is for correcting the what circular surfaces do to textures
        // The default value for all faces is 0 ( distored )
        // So we will only uncomment lines that carry a value of 1 ( corrected )
       
        //  And we make a note of that in the output script here
        comment("Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.\n      // Most builds don't use it, so it's commented out to save bytes in auto-transform code.\n        // The default value is 1 (distorted).\n      // if you are metamorphing an object that already had planar mapping (rare)\n      // uncomment those 0 lines.\n      // This may not seem like much savings\n      //  but if your script is trying to metamorph between as many as five objects\n      // those few bytes saved might come in handy at the end.\n\n      // If your textures are coming out with the offsets all wrong, try uncommenting them.");
        for (i = 0 ; i < sides ; ++i) 
        { 
             list r = llGetPrimitiveParams([PRIM_TEXGEN,i]);
            if (llList2Integer(r,-1) == 0) say("        // PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");
            if (llList2Integer(r,-1) == 1) say("        PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");   
        }
       
    /// The last paramater is Object-Specific
      
      
            PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 ,
            PRIM_TEXTURE,1,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 ,
            PRIM_TEXTURE,2,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000
            ];
            llSetPrimitiveParams(params);
            params = [];
   
          // Note that you -cannot- define textures and colors in the same call!
          // If you're cutting out these params for your custom code watch out for this.
      
      
          params =
    saynd("PRIM_POINT_LIGHT," + osp(PRIM_POINT_LIGHT) );
            [
      
      
            PRIM_COLOR,0,<0.054902, 0.654902, 0.062745>,1.000000 ,
    say("        llSetPrimitiveParams(params);\        params = [];");  //  Print the final function call, braces & some blank lines
            PRIM_COLOR,1,<0.054902, 0.654902, 0.062745>,1.000000 ,
       
            PRIM_COLOR,2,<0.054902, 0.654902, 0.062745>,1.000000
    say("\n\n        // If you were cut/pasting this code into a custom transform function\n        // end your cut above this comment.\n        // Otherwise ignore this.\n\n        llSetObjectName(\"" + object_name + "\");\n");  // Make the target's name match this one
            ];
    say("\n        llSetObjectDesc(\"" + object_name + "\");\n");  // Make the target's desc match this one
            llSetPrimitiveParams(params);
            params = [];
          params =
            [
      
      
            PRIM_BUMP_SHINY,0,3,0 ,
    comment("This next line deletes the script.  Comment it out if you want the script to persist");
            PRIM_BUMP_SHINY,1,3,0 ,
            PRIM_BUMP_SHINY,2,3,0
            ];
            llSetPrimitiveParams(params);
            params = [];
          params =
          [
      
      
            PRIM_FULLBRIGHT,0,1 ,
    say("\n        llRemoveInventory(llGetScriptName());\n    }\n}\n\n\n"); // Remove the cloning script when done
            PRIM_FULLBRIGHT,1,1 ,
            PRIM_FULLBRIGHT,2,1 ,
            PRIM_FLEXIBLE,0,2,0.300000,2.000000,0.000000,1.000000,<0.000000, 0.000000, 0.000000> ,
            // PRIM_CAST_SHADOWS,1 ,
   
          // Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.
          // Most builds don't use it, so it's commented out to save bytes in auto-transform code.
            // The default value is 1 (distorted).
          // if you are metamorphing an object that already had planar mapping (rare)
          // uncomment those 0 lines.
          // This may not seem like much savings
          // but if your script is trying to metamorph between as many as five objects
          // those few bytes saved might come in handy at the end.
      
      
          // If your textures are coming out with the offsets all wrong, try uncommenting them.
 
            // PRIM_TEXGEN,0,0 ,
    llSetObjectName(object_name); // Change our object's name back.
            // PRIM_TEXGEN,1,0 ,
            // PRIM_TEXGEN,2,0 ,
            PRIM_POINT_LIGHT,1,<1.000000, 1.000000, 1.000000>,0.200000,20.000000,0.000000
            ];
            llSetPrimitiveParams(params);       params = [];
   
   
            // If you were cut/pasting this code into a custom transform function
            // end your cut above this comment.
            // Otherwise ignore this.
   
            llSetObjectName("Mobius Torus");
   
   
            llSetObjectDesc("Mobius Torus");
      
      
   
    say("Don't forget to remove the \"[HH:MM]  :\" timestamp at the beginning of each line.  Use Find/Replace  :)"); // Remind us to remove prefixes.)
          // This next line deletes the scriptComment it out if you want the script to persist
    llRemoveInventory(llGetScriptName()); // Delete this script.
   
            llRemoveInventory(llGetScriptName());
        }
     }
     }
} </lsl>
Well thet shoor is a lotta code!  Most of it whitespace and comments.
== Sample Output ==
Here's an example of the output.  This will make a shiny, metallic mobius strip.
<lsl>default
{
    state_entry()
        {
        list params;
       
        // If you are cutting code out to paste into custon functions
        // Define "params" as a global list and start cutting below this line.
        params =
        [
        PRIM_TYPE,4,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.500000, -0.500000, 0.000000>,<0.250000, 0.050000, 0.000000>,<0.000000, -0.100000, 0.000000>,<0.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,1.000000,0.000000,0.000000 ,
        PRIM_MATERIAL,2 ,
        PRIM_PHYSICS,0 ,
        PRIM_TEMP_ON_REZ,0 ,
        PRIM_PHANTOM,2 ,
        // It's probably not a god idea to have your new prim jump to the old one
        // PRIM_POSITION,<84.270088, 36.444294, 231.487076> ] + (params = []) +
        PRIM_ROTATION,<-0.363768, 0.720439, 0.134244, 0.574995> ,
        PRIM_SIZE,<1.072797, 1.206897, 1.072797>
        ];
      // Set all of the above paramaters as a group.
        llSetPrimitiveParams(params);
        params = [];
      // We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others
      // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.
      // Please vote to fix it.
      // This prim has 3 faces.
      params =
        [
        PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 ,
        PRIM_TEXTURE,1,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 ,
        PRIM_TEXTURE,2,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000
        ];
        llSetPrimitiveParams(params);
        params = [];
      // Note that you -cannot- define textures and colors in the same call!
      // If you're cutting out these params for your custom code watch out for this.
      params =
        [
        PRIM_COLOR,0,<0.054902, 0.654902, 0.062745>,1.000000 ,
        PRIM_COLOR,1,<0.054902, 0.654902, 0.062745>,1.000000 ,
        PRIM_COLOR,2,<0.054902, 0.654902, 0.062745>,1.000000
        ];
        llSetPrimitiveParams(params);
        params = [];
      params =
        [
        PRIM_BUMP_SHINY,0,3,0 ,
        PRIM_BUMP_SHINY,1,3,0 ,
        PRIM_BUMP_SHINY,2,3,0
        ];
        llSetPrimitiveParams(params);
        params = [];
      params =
      [
        PRIM_FULLBRIGHT,0,1 ,
        PRIM_FULLBRIGHT,1,1 ,
        PRIM_FULLBRIGHT,2,1 ,
        PRIM_FLEXIBLE,0,2,0.300000,2.000000,0.000000,1.000000,<0.000000, 0.000000, 0.000000> ,
        // PRIM_CAST_SHADOWS,1 ,
      // Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.
      // Most builds don't use it, so it's commented out to save bytes in auto-transform code.
        // The default value is 1 (distorted).
      // if you are metamorphing an object that already had planar mapping (rare)
      // uncomment those 0 lines.
      // This may not seem like much savings
      //  but if your script is trying to metamorph between as many as five objects
      // those few bytes saved might come in handy at the end.
      // If your textures are coming out with the offsets all wrong, try uncommenting them.
        // PRIM_TEXGEN,0,0 ,
        // PRIM_TEXGEN,1,0 ,
        // PRIM_TEXGEN,2,0 ,
        PRIM_POINT_LIGHT,1,<1.000000, 1.000000, 1.000000>,0.200000,20.000000,0.000000
        ];
        llSetPrimitiveParams(params);        params = [];
        // If you were cut/pasting this code into a custom transform function
        // end your cut above this comment.
        // Otherwise ignore this.
        llSetObjectName("Mobius Torus");
        llSetObjectDesc("Mobius Torus");
      // This next line deletes the script.  Comment it out if you want the script to persist
        llRemoveInventory(llGetScriptName());
    }
}</lsl>




Line 499: Line 514:
'''Tip:''' One neat thing you can do is have your prim cycle between objects. Just take the entire codeblock in state_entry() and stick it in a custom function  thus:
'''Tip:''' One neat thing you can do is have your prim cycle between objects. Just take the entire codeblock in state_entry() and stick it in a custom function  thus:


    shape_1()
<lsl>shape_1()
    {
{
        // Clone Prim codeblock
      // Clone Prim codeblock
    }
}
    shape_2()
shape_2()
    {
{
        // Clone Prim codeblock
      // Clone Prim codeblock
    }                       
}                       
    shape_3()
shape_3()
    {
{
        // Clone Prim codeblock
    // Clone Prim codeblock
    }
}
    shape_4()
shape_4()
{
      // Clone Prim codeblock
}                                             
 
default
     {
     {
        // Clone Prim codeblock
      on_rez(integer p) { llResetScript(); }
    }                                             
      state_entry()
      {
        do
        {
          shape_1();
          llSleep(10.);
   
   
          shape_2();
          llSleep(10.);
   
   
    default
          shape_3();
    {
          llSleep(10.);
        on_rez(integer p) { llResetScript(); }
 
        state_entry()
          shape_4();
        {
          llSleep(10.);
            do
            {
                shape_1();
                llSleep(10.);
                shape_2();
                llSleep(10.);
                shape_3();
                llSleep(10.);
                shape_4();
                llSleep(10.);
   
   
            }while (1);
      }while (1);
        }
     }
     }
}</lsl>




All sorts of possibilities, really.  I recommend coffee, sleep deprivation and imagination.
All sorts of possibilities, really.  I recommend coffee, sleep deprivation and imagination.
( In its current form this script can run with 8 complete output blocks, but 9 == stack/heap ).


== BUGS ==
== BUGS ==

Revision as of 01:43, 8 January 2008

Clone Primitive v2.3 is a Total, End-2-End virtual object replication solution for the simulated cyberspace known to its tecnocrati "netziens" as Second Life.

Shoot me.

Cloned by script

How to Use

Drop this script into a prim and it spits out a complete script in owner chat.

Paste that script into a completely blank script, strip out the Timestamps with find/replace, and drop that into any other prim. Viola! You have a copy of the first prim.

Both scripts self-delete from object inventory after doing their thing.


What's it for?

Why would you need this? You don't. Maybe. It does essentially the same thing as shift-copy, which most people learn on their third day.

However, it does one nice thing, which is to print out all your primitive params in a format that's easy to plug into other scripts using llSetPrimitiveParams([]) and llSetLinkPrimitiveParams([]) transformation functions.

I'm sure people like Cubey and Horizons have scripts like these that spit out parameter codeblocks for use in their morphing rezzer gizmos.


The Script

I'm including the script with its huge comment header. Below that a sample output script.

<lsl> /////////////////////////////////////////////////////////////////// // // END - TO - END PRIM CLONER v 2.3 // // // This script chats out lines of text that can be pasted back // into a blank script to clone the original prim. // // It also produces codeblocks optimized for automated transforms. // //

////////////////////////////////////////////////////////////////////

// // HOW TO USE // // // Drag 'n Drop this script into the prim you want to copy. // // It will output a complete script for replicating the object // in Owner-Only chat. Then it will delete itself. // // Copy and paste the chatted script into a *completly blank* // new script // // Then use the Search/Replace function under the Edit menu // to replace the "[HH:MM]  :" line prefixes with a blank. // // Just hit the 'Replace All' button. // // It can take 2 minutes or more to print out, so you may have to // do this a few times. // // // The Primitve Paramaters will be chatted out in the oder that // they're featured on the offical Wiki: // // http://wiki.secondlife.com/wiki/LlGetPrimitiveParams //

///////////////////////////////////////////////////////////////////

// // WHY? // // Chances are you're not going to need an end-to-end // script to dupe your prim. Shift-drag copy is a lot easier. // // But if you're reading this you probably want some of the code, // so carve out what you need from the output. // // The output code is also commented where appropriate. If you want // To know more about what's going on, read the comments here and // check out the wiki. The wiki's good. // // Many advanced items on the grid transform from one object to // another. Builders have used scrips like this to generate the // code that goes into those products. // // Consider the use of both of llSetPrimitiveParams([]) and // llSetLinkPrimitiveParams([]). A multi-prim prim object can be // metamorphed with a single scipt. // // In my experience you can pack five complete primitive trans- // formations into one script before you run out of bytes. //

///////////////////////////////////////////////////////////////////

// // Released nder the terms of the // GNU General Public Liscence v3 // // This source code is free to use / modify / resell // with the following restrictions: // // If you include any portion of -this- script in a product you // distribute you must make the script fully mod/copy/trans for // the next user/owner. You must also liscence it under the GPL // and give attribution to the contributors. // // This does not extend to the code this script generates. That // is yours to liscense as you see fit. // // No warantee expressed or implied. // // For more info see http://www.gnu.org/copyleft/gpl.html //

///////////////////////////////////////////////////////////////////

// // Written by // Clarknova Helvetic [2008.01.04] // w/ thanks to Bopete Yossarian // ////////////////////////////////////////////////////////////////////


/// Global Functions & Vars to make life easier


float pause = .1  ; //// Change this to change the delay between each printed line.

                         //// The laggier the server the more delay you'll need to 
                         //// prevent line mix-up.


// Object-Specific parameters 2 string string osp(integer p) {return llDumpList2String(llGetPrimitiveParams([p]),","); }

// Face-Specific parameters 2 string string fsp(integer p, integer f) { return llDumpList2String(llGetPrimitiveParams([p,f]),","); }

// Parameter prefixed and formatted for output string param(string p , integer q) { return p + "," + osp(q); }

// General owner chat w\ Sleep function to stop chat lag from screwing up the line order say(string c) { llSleep(pause); llOwnerSay(c); }

// Printing out next element to add to the parameter list sayn(string c) { say(" " + c + " , "); }

// Printing out the last element to add to the parameter list saynd(string c) { say(" " + c + "\n ];"); }

// Print out the code to apply the parameters to the object define() { say(" llSetPrimitiveParams(params);\n params = [];"); }

// Handle to insert comments comment(string c) { say("\n // " + c ); }


/// On with the show...


default {

   state_entry()
   {


   say("COPY/PASTE THE CODE BELOW INTO A *BLANK* SCRIPT TO CLONE THIS PRIM: \n\n");  // Announce what we're doing
   
   // We're going to change the object's name to a null string to make the output easier to read.
   string object_name = llGetObjectName(); // Store the object's name so we can set it back when done
   llSetObjectName("");
   
   // Guess we should transfer the description too
   string object_desc = llGetObjectDesc();
   
   //  Print the script header up to state_entry
   say("\ndefault\n{\n    state_entry()\n        {\n         list params;\n        \n\n         // If you are cutting code out to paste into custon functions\n         // Define \"params\" as a global list and start cutting below this line.\n\n         params =\n");
    
    


   // Add some comments to the script 
   // [12:56]  Tali Rosca: It uses the C-style thing about an assignment also being an expression with a value.
   // [12:56]  Tali Rosca: Why it actually saves memory still baffles my mind, though.
   
   // list of the the first: paramater constants as strings, then thier integer value.
   list Param_Names = ["PRIM_TYPE",PRIM_TYPE,"PRIM_MATERIAL",PRIM_MATERIAL,"PRIM_PHYSICS",PRIM_PHYSICS,"PRIM_TEMP_ON_REZ",PRIM_TEMP_ON_REZ,"PRIM_PHANTOM",PRIM_PHANTOM,"PRIM_POSITION",PRIM_POSITION,"PRIM_ROTATION",PRIM_ROTATION,"PRIM_SIZE",PRIM_SIZE];


           // ASIDE:
           // Prim params are of two types: Object-Specific and Face-Specific.
           //
           // I'd Like to group them together according to type, but LsL doesn't
           // nor does wiki.secondlife, and I am sworn to complete my destiny...
           //
           // This is probably for historical reasons (the param order, not my 
           // ultimate destiny).
           
   
   integer i; // You're going to see a lot of use, integer i!
   integer length; // So are you, integer length!
   
   length = (llGetListLength(Param_Names)); // I'm way lazy.  Let's make LsL do basic math for us.
   
   for ( i = 0 ; i < length ; i = i +2) // This is may answer to list strides.  Take that!
   {
       if (i > length -3 ) // If we're at the last stride
       {
           saynd(param(llList2String(Param_Names,length -2), llList2Integer(Param_Names,length -1))) ; // Fecth the constants out of Param_Names.
           i = length;
       }
       else if (i == 0) // PRIM_TYPE is a special case.  But then what isn't?
       {   
           //  Checking if it's a sculptie in a rather extravagant way,  
           //  but I also want to check my work.
           
           integer j = llList2Integer(Param_Names,i+1); // What's the param we're checking?
           list r = llGetPrimitiveParams([j]); // What are its values?
           integer t = llList2Integer(r,0); // What's the first value?
           if (t == 7) // if it's a sculptie
           {
               sayn("[\n         PRIM_TYPE,"+ (string)t + ",\""+ llList2String(r,1) + "\"," + llList2String(r,2) ); 
               
           }
           else sayn("[\n         " + param(llList2String(Param_Names,i), j));
       }
       else if (i < length -3 && i != length -6 ) sayn(param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) ) ;
       else if (i < length -3 && i == length -6 )
       {
           say("        // It's probably not a god idea to have your new prim jump to the old one\n        // " + param( llList2String(Param_Names,i), llList2Integer(Param_Names,i+1)) + " ] + (params = []) +"); 
       
       }
   }
   
   Param_Names = []; // Free up some memory
   // I reallllly want our script to set all of the paramaters at once, with one llSetPrimitiveParams() 
   // call at the end of the script but we can't because of bugs in LsL.  
   //
   // See  https://jira.secondlife.com/browse/SVC-38  for more info.  Please vote to fix it.
   
   say(""); 
   
   comment("Set all of the above paramaters as a group.");
   define();
   
   say("");
   comment("We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others \n       // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.\n       // Please vote to fix it. \n");
           
                             
    //// Okay, now for the hard stuff: 4 out of 5 of the Face-Specific params, starting with the hardest:
    //// PRIM_TEXTURE.  Why is PRIM_TEXTURE a pain?  Because llSetPrimitiveParams wants it in qoutes, but
    //// llGetPrimitiveParams doesn't give it to us in quotes.  It's a pickle.
    ////
    //// The Face-Specific params each need thier own For loop because the number of faces is variable
    //// from prim to prim.  A simple sphere only has one.  A tube can have up to 9.
    
    
   integer sides = llGetNumberOfSides();  // So here we find out how many faces we've got
       
   comment("This prim has " + (string)sides + " faces.\n"); // Don't care enough to correct for the singular :)


       ///  PRIM_TEXTURE ///
       say( "      params =\n        [\n");
       for (i = 0 ; i < sides ; ++i)  
       {   
           
           list r =llGetPrimitiveParams([PRIM_TEXTURE,i]);
           string s = 
           "\""  + llList2String(r,0) + "\"" // First element is the texture key.
           + ","
           + llList2String(r,1)
           + ","
           + llList2String(r,2)
           + ","
           + llList2String(r,3) ;
           
           if (i < sides -1)  s = s + " , " ; 
           else if (i == sides -1)  s = s + "\n        ];";
                       
           say("       PRIM_TEXTURE," + (string)i + "," + s );    


           // Local variables aren't cleared when we leave thier scope.  Can you believe that crap?
           r = []; s = ""; 
   
       }
       


       define();
       
       comment("Note that you -cannot- define textures and colors in the same call!\n      // If you're cutting out these params for your custom code watch out for this.\n");   
   
       
       ///  PRIM_COLOR ///
       say( "      params =\n        [\n");
       for (i = 0 ; i < sides ; ++i)  
       {   
            if (i < sides -1 ) sayn("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i));
            if (i == sides -1 ) saynd("PRIM_COLOR," + (string)i + "," + fsp(PRIM_COLOR,i)); 
       }
       define();
       
       
       ///  PRIM_BUMP_SHINY ///
       say( "      params =\n        [\n");
       for (i = 0 ; i < sides ; ++i)  
       {   
           if (i < sides -1 ) sayn("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i) );
           if (i == sides -1 ) saynd("PRIM_BUMP_SHINY," + (string)i + "," + fsp(PRIM_BUMP_SHINY,i)); 
   
       }
       define();
       ///  PRIM_FULLBRIGHT ///
       
       say( "      params =\n      [\n");
       for (i = 0 ; i < sides ; ++i)  
       {   
           sayn("PRIM_FULLBRIGHT," + (string)i + "," + fsp(PRIM_FULLBRIGHT,i)); 
   
       }
       
       
   ////   Now back to an Object-Specific paramaters : Flexible & Shadows
   ////   Remember that I'm going in this screwy order so that our
   ////   Code matches the table on http://wiki.secondlife.com/wiki/LlSetPrimitiveParams
   
       
   sayn(param( "PRIM_FLEXIBLE",21));
   sayn("// " + param( "PRIM_CAST_SHADOWS",24));
       



   //// Now for one more Face-Specific paramater
   
       ///  PRIM_TEXGEN ///     
       
       // Planar mapping is for correcting the what circular surfaces do to textures 
       // The default value for all faces is 0 ( distored ) 
       // So we will only uncomment lines that carry a value of 1 ( corrected )
       
       //  And we make a note of that in the output script here
       comment("Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.\n       // Most builds don't use it, so it's commented out to save bytes in auto-transform code.\n        // The default value is 1 (distorted).\n       // if you are metamorphing an object that already had planar mapping (rare)\n       // uncomment those 0 lines.\n       // This may not seem like much savings\n       //  but if your script is trying to metamorph between as many as five objects\n       // those few bytes saved might come in handy at the end.\n\n       // If your textures are coming out with the offsets all wrong, try uncommenting them.");
       for (i = 0 ; i < sides ; ++i)  
       {   
           list r = llGetPrimitiveParams([PRIM_TEXGEN,i]);
           if (llList2Integer(r,-1) == 0) say("        // PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");
           if (llList2Integer(r,-1) == 1) say("        PRIM_TEXGEN," + (string)i + "," + llDumpList2String(r," , ") + " , ");    
       }
       
   /// The last paramater is Object-Specific
   
   
   saynd("PRIM_POINT_LIGHT," + osp(PRIM_POINT_LIGHT) );
   
   say("        llSetPrimitiveParams(params);\        params = [];");  //  Print the final function call, braces & some blank lines
       
   say("\n\n         // If you were cut/pasting this code into a custom transform function\n         // end your cut above this comment.\n         // Otherwise ignore this.\n\n        llSetObjectName(\"" + object_name + "\");\n");  // Make the target's name match this one
   say("\n        llSetObjectDesc(\"" + object_name + "\");\n");  // Make the target's desc match this one
   
   comment("This next line deletes the script.  Comment it out if you want the script to persist");
   
   say("\n        llRemoveInventory(llGetScriptName());\n     }\n}\n\n\n");  // Remove the cloning script when done 
   
   llSetObjectName(object_name); // Change our object's name back.
   
   say("Don't forget to remove the \"[HH:MM]  :\" timestamp at the beginning of each line.  Use Find/Replace  :)"); // Remind us to remove prefixes.)
   llRemoveInventory(llGetScriptName());  // Delete this script.
   }

} </lsl>

Well thet shoor is a lotta code! Most of it whitespace and comments.

Sample Output

Here's an example of the output. This will make a shiny, metallic mobius strip.

<lsl>default {

   state_entry()
       {
        list params;
       
        // If you are cutting code out to paste into custon functions
        // Define "params" as a global list and start cutting below this line.
        params =
        [
        PRIM_TYPE,4,0,<0.000000, 1.000000, 0.000000>,0.000000,<0.500000, -0.500000, 0.000000>,<0.250000, 0.050000, 0.000000>,<0.000000, -0.100000, 0.000000>,<0.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,1.000000,0.000000,0.000000 , 
        PRIM_MATERIAL,2 , 
        PRIM_PHYSICS,0 , 
        PRIM_TEMP_ON_REZ,0 , 
        PRIM_PHANTOM,2 , 
        // It's probably not a god idea to have your new prim jump to the old one
       // PRIM_POSITION,<84.270088, 36.444294, 231.487076> ] + (params = []) +
        PRIM_ROTATION,<-0.363768, 0.720439, 0.134244, 0.574995> , 
        PRIM_SIZE,<1.072797, 1.206897, 1.072797>
       ];


      // Set all of the above paramaters as a group.
        llSetPrimitiveParams(params);
       params = [];


      // We are breaking the llSetPtimitiveParam([]) calls into blocks, because some params are incompatible with others 
      // during the same call. This is an LsL bug.  See https://jira.secondlife.com/browse/SVC-38 for more info.
      // Please vote to fix it. 


      // This prim has 3 faces.
      params =
       [
       PRIM_TEXTURE,0,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 , 
       PRIM_TEXTURE,1,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000 , 
       PRIM_TEXTURE,2,"5748decc-f629-461c-9a36-a35a221fe21f",<1.000000, 1.000000, 0.000000>,<0.000000, 0.000000, 0.000000>,0.000000
       ];
        llSetPrimitiveParams(params);
       params = [];

      // Note that you -cannot- define textures and colors in the same call!
     // If you're cutting out these params for your custom code watch out for this.
      params =
       [
        PRIM_COLOR,0,<0.054902, 0.654902, 0.062745>,1.000000 , 
        PRIM_COLOR,1,<0.054902, 0.654902, 0.062745>,1.000000 , 
        PRIM_COLOR,2,<0.054902, 0.654902, 0.062745>,1.000000
       ];
        llSetPrimitiveParams(params);
       params = [];
      params =
       [
        PRIM_BUMP_SHINY,0,3,0 , 
        PRIM_BUMP_SHINY,1,3,0 , 
        PRIM_BUMP_SHINY,2,3,0
       ];
        llSetPrimitiveParams(params);
       params = [];
      params =
     [
        PRIM_FULLBRIGHT,0,1 , 
        PRIM_FULLBRIGHT,1,1 , 
        PRIM_FULLBRIGHT,2,1 , 
        PRIM_FLEXIBLE,0,2,0.300000,2.000000,0.000000,1.000000,<0.000000, 0.000000, 0.000000> , 
        // PRIM_CAST_SHADOWS,1 , 

      // Planar mapping (PRIM_TEXGEN) is for correcting the what circular surfaces do to textures.
      // Most builds don't use it, so it's commented out to save bytes in auto-transform code.
       // The default value is 1 (distorted).
      // if you are metamorphing an object that already had planar mapping (rare)
      // uncomment those 0 lines.
      // This may not seem like much savings
      //  but if your script is trying to metamorph between as many as five objects
      // those few bytes saved might come in handy at the end.
      // If your textures are coming out with the offsets all wrong, try uncommenting them.
        // PRIM_TEXGEN,0,0 , 
        // PRIM_TEXGEN,1,0 , 
        // PRIM_TEXGEN,2,0 , 
        PRIM_POINT_LIGHT,1,<1.000000, 1.000000, 1.000000>,0.200000,20.000000,0.000000
       ];
        llSetPrimitiveParams(params);        params = [];

        // If you were cut/pasting this code into a custom transform function
        // end your cut above this comment.
        // Otherwise ignore this.
       llSetObjectName("Mobius Torus");


       llSetObjectDesc("Mobius Torus");


      // This next line deletes the script.  Comment it out if you want the script to persist

       llRemoveInventory(llGetScriptName());
    }

}</lsl>


Heavens to Betsy!

See? Simple to deal with. Comment out what you don't want, restructure, etc. I use this script mainly for finding the horizontal texture offset on face 666 of my tortured tube dong.

Easy peasy to read, too.

Tips & Ideas

Warning: Bad chat lag will sometimes re-order your code for you. Increase the pause variable at the top of the script and try again. If that fails reduce your draw distance, move to a different sim and wait for SL to stop sucking.

Tip: comment out the PRIM_SIZE in the output script and drop it in a megaprim after you've built your scale model.

Tip: One neat thing you can do is have your prim cycle between objects. Just take the entire codeblock in state_entry() and stick it in a custom function thus:

<lsl>shape_1() {

     // Clone Prim codeblock

} shape_2() {

     // Clone Prim codeblock

} shape_3() {

    // Clone Prim codeblock

} shape_4() {

     // Clone Prim codeblock

}

default

   {
     on_rez(integer p) { llResetScript(); }
     state_entry()
     {
        do
        {
          shape_1();
          llSleep(10.);

          shape_2();
          llSleep(10.);

          shape_3();
          llSleep(10.);
          shape_4();
          llSleep(10.);

      }while (1);
   }

}</lsl>


All sorts of possibilities, really. I recommend coffee, sleep deprivation and imagination.

( In its current form this script can run with 8 complete output blocks, but 9 == stack/heap ).

BUGS

PRIM_TEXGEN aka Planar Mapping values are automatically commented out if they're at default (FALSE).

This is to save a little bytecode in case you're plugging a bunch of prim transforms into custom functions. Usually no one uses Planar Mapping (it corrects for the distortion of circular surfaces).

This isn't a bug, it's a feature, and it's commented on in both Clone Primitive and the output script.

If this makes your textures look like their offsets went wrong, uncomment the PRIM_TEXGEN lines and recompile.

License

In my comment header here , and in copies I give out in-world, I declare this script copyrighted under the GPL v3.

Linden Labs declares everything on their Wiki released under the CC Attribution-Share Alike 2.5.

Both amount to the same thing: if you use redistribute my code in any form, those scripts must be full perms, and my name and the name of everyone that touched them must be prominently commented.

Period. I am fascist about this.

Code output by the script is of course yours, and you can do anything you want with that, but this script must remain Open Source. You can even copy/paste it into your own script item and sell it on SLX, but you have to include the license information and my name, and everyone will laugh at you and your customers will know you ripped them off you big jerk. :D

Also I'm selling it as well, for anyone silly enough to spend $L20, so I'm way ahead of and undercutting you.