Texture Repeater

From Second Life Wiki
Revision as of 20:30, 1 December 2012 by Jenna Felton (talk | contribs) (corrected the link after reorganization of the linked blog)
Jump to navigation Jump to search

Texture Repeater. Observes textures and texture parameters on the prim. As soon those have changed, updates other prims in the linkset to repeat the changes. This allows the user to texture the covered or hard to aim faces of that prims.

The script copies the texture UUID and parameters given the face 0 to the face 0 on of every other script in linkset. Than the texture UUID and parameters of the face 1 to the face 1 of other script and so on until the face 5. Further faces are not repeated but that is easily extensible.

The script was created for my GlassBox mesh tutorial – where we create mesh prims with faces that cover others completely and make them quite hard to texture inworld on regular way. The script was published here in hope it is also usable other wise, but also to keep my blog post shorter.

Usage

Create a box (or other appropriate form) via build tools and put the script into - this turns the prim into repeater tool. Now you can prepare the prim faces by texturing, or just link it with all prims you want bulk-texture. The face textures are copied immediately by linking. If needed you can now texture the repeater prim – all texture parameters are copied to other prims than.

The repeater must not be the root prim of the linket. You can also use two or more repeaters (not recommended), the script copies only changed parameters and avoids so a permanent texture updates by multiple repeaters.

After usage, click the repeater, the script will ask for link permission. If you accept, the repeater will unlink and destroy itself, but leaving back the textured linkset inworld (if you doubt prim loss, please comment out the llDie() command.) If you put something into the repeater prim, like a notecard, texture or another script, the repeater script skips self-destroying to prevent loosing that unexpected content.

Disclaimer

You can use this script in your project, if commercial or not. If you modify the script, please extend the script header by your name and update notes.

This script is provided as is. Although tested and found as error-free, no responsibility is taken for any misuse of the script, or damage caused by using it.

Repeater script

<lsl> //---------------------------------------------------------------------------- // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 3 of // the License, or (at your option) any later version. // // You may ONLY redistribute this program with copy, mod and transfer // permissions and ONLY if this preamble is not removed. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // $RCSfile: repeater.lslp,v $ // // Texture repeater. Observes textures and texture parameters // on the prim. As soon those have changed, updates other prims // to repeat the changes. This allows to texture covered or hard // to aim prim faces. // // Supports only 6 faces (but easily extensible) // //---------------------------------------------------------------------------- // Author Jenna Felton // Version 1.0, $Revision: 1.2 $ // $Date: 2012/11/29 17:59:13 $ //----------------------------------------------------------------------------

// The lists allow to terminate a ping-pong change of textures // when two repeaters are linked by mistake, but also prevent // change of values that are always changed. To do so we fill // up the lists by dummy values that are never something used // for texture settings. This way the script will notice the // difference between the set texture and stored dummy value.

list lImage = [10, 10, 10, 10, 10, 10]; list lFBrgt = [10, 10, 10, 10, 10, 10]; list lColor = [10, 10, 10, 10, 10, 10]; list lBumps = [10, 10, 10, 10, 10, 10]; list lTextg = [10, 10, 10, 10, 10, 10]; list lPGlow = [10, 10, 10, 10, 10, 10];

//----------------------------------------------------------------------------

updateTextures() {

   if (llGetNumberOfPrims() < 2) return;
   integer face;
   for (face = 0 ; face < 6 ; face++) {
       list    write = [];
       list    read  = llGetPrimitiveParams([
           PRIM_TEXTURE,    face, // [ s texture, v repeats, v offsets, f rotation ] : 0, 3 
           PRIM_FULLBRIGHT, face, // [ i value ]                                     : 4
           PRIM_COLOR,      face, // [ v color, f alpha ]                            : 5, 6
           PRIM_BUMP_SHINY, face, // [ i shiny, i bump ]                             : 7, 8
           PRIM_TEXGEN,     face, // [ i mode ]                                      : 9
           PRIM_GLOW,       face  // [ f intensity ]                                 : 10
       ]);
       
       // [ PRIM_TEXTURE, i face, s texture, v repeats, v offsets, f rotation ] 
       list   tmp   = llList2List(read, 0, 3);
       string image = llDumpList2String(tmp, "|");
       if (llList2String(lImage, face) != image) {
           lImage = llListReplaceList(lImage, [image], face, face);
           write  = [PRIM_TEXTURE, face]+tmp;
       }
       
       // [ PRIM_FULLBRIGHT, i face, i value ] 
       integer fbrgt = llList2Integer(read, 4);
       if (llList2Integer(lFBrgt, face) != fbrgt) {
           lFBrgt = llListReplaceList(lFBrgt, [fbrgt], face, face);
           write += [PRIM_FULLBRIGHT, face, fbrgt];
       }
       
       // [ PRIM_COLOR, i face, v color, f alpha ] 
       tmp          = llList2List(read, 5, 6);
       string color = llDumpList2String(tmp, "|");
       if (llList2String(lColor, face) != color) {
           lColor = llListReplaceList(lColor, [color], face, face);
           write += [PRIM_COLOR, face]+tmp;
       }
       
       // [ PRIM_BUMP_SHINY, i face, i shiny, i bump ] 
       tmp          = llList2List(read, 7, 8);
       string bumps = llDumpList2String(tmp, "|");
       if (llList2String(lBumps, face) != bumps) {
           lBumps = llListReplaceList(lBumps, [bumps], face, face);
           write += [PRIM_BUMP_SHINY, face]+tmp;
       }
       
       // [ PRIM_TEXGEN, i face, i type ] 
       integer textg = llList2Integer(read, 9);
       if (llList2Integer(lTextg, face) != textg) {
           lTextg = llListReplaceList(lTextg, [textg], face, face);
           write += [PRIM_TEXGEN, face, textg];
       }
       
       // [ PRIM_GLOW, i face, f intensity ] 
       float pglow = llList2Float(read, 10);
       if (llList2Float(lPGlow, face) != pglow) {
           lPGlow = llListReplaceList(lPGlow, [pglow], face, face);
           write += [PRIM_GLOW, face, pglow];
       }
       
       if (write != []) {
           llSetLinkPrimitiveParamsFast(LINK_ALL_OTHERS, write);
       }
   }

}

//----------------------------------------------------------------------------

default {

   // Full update: Send all texture settings to other prims
   state_entry() {
       updateTextures();
   }
   // Reset script to repeat full texture updates
   on_rez(integer start) {
       llResetScript();
   }
   // Check what is changed, if relinked - full update
   // if just texture change - partial update
   changed(integer change) {
       if (change & CHANGED_LINK) {
           llResetScript();
       }
       if (change & CHANGED_COLOR || change & CHANGED_TEXTURE) {
           updateTextures();
       }
   }
   // Ask the owner if to unlink the repeater
   touch_start(integer total_number) {
       if (llDetectedKey(0) == llGetOwner()) {
           llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
       }
   }
   // If allowed, unlink repeater and if possible - destroy
   run_time_permissions(integer perms) {
       if (llGetNumberOfPrims() > 1 && perms & PERMISSION_CHANGE_LINKS) {
           perms = llGetLinkNumber();
           if (perms > 0) {
               llBreakLink(perms);
           }
           
           if (llGetNumberOfPrims() > 1) {
               llOwnerSay("ERROR: Could not unlink the prim." 
                    +" Please try again");
               return;
           }
           if (llGetInventoryNumber(INVENTORY_ALL) == 1) {
               llDie();
           }
           else {
               llOwnerSay("WARNING: There is unexpected content"
                   +" into the prim. Destroying aborted");
           }
       }
   }

}

//---------------------------------------------------------------------------- </lsl>