Jump to content

Recommended Posts

Posted (edited)

Hey. I'm trying to create or find a ready-made script that changes the textures of certain faces of certain prims in the linkset when placed in the linkset or as a rezzing installer. (Like the one used for vehicle livery appliers etc). I found such a script, but I don’t see where to put numbers of prims. so I doubt that this is what I need. maybe I just misunderstood the description? If somebody can read scripts, please tell me is it what I need? Help!

TEXTURE CHANGER WIKI

 

Edited by ainst Composer

Share this post


Link to post
Share on other sites

Look at the changetexture function at the top of the script, where it says:

list primdata = llCSV2List(llList2String(sides,counter));
        integer prim = llList2Integer(primdata,0);

The global list called sides is defined above, with an explanation in the comments:

//"prim number, side number, side number...side number"
//-1 equals all sides for that prim
list sides = [
    "0,1,2,5",
    "1,3,4,1"];//put in which sides you want the texture to be changed on.

So, the function will be looping through each string in sides, unpacking it to get the link number that is always its first element and applying it to each of the numbered faces that make up the rest of the string.

This is a very old script -- written in 2009 before many more efficient functions were available.  In fact, someone has added a note in the script that says 

//probably best to use llSetLinkPrimitiveParams

which is certainly a good idea.  You could almost certainly write a better script to do the same thing.

  • Thanks 1

Share this post


Link to post
Share on other sites
20 minutes ago, Rolig Loon said:

This is a very old script -- written in 2009 before many more efficient functions were available.  In fact, someone has added a note in the script that says 


//probably best to use llSetLinkPrimitiveParams

which is certainly a good idea.  You could almost certainly write a better script to do the same thing.

Hello! Thank you for your answer!

Very interesting part! How does using llSetLinkPrimitiveParams make it easier? and what are the advantages? Thanks!

Share this post


Link to post
Share on other sites
9 minutes ago, ainst Composer said:

How does using llSetLinkPrimitiveParams make it easier? and what are the advantages?

You could make all of the changes in a single call to SLPPF.  If I were writing the script, I would create a function like the changetexture function in this one but drastically redesigned to create a long list that uses SLPPF's parameters PRIM_LINK_TARGET and PRIM_TEXTURE over and over again to define every single change that I wanted the script to make.  Then I would simple call and execute the composite list

llSetLinkPrimitiveParamsFast(LINK_SET,my_humungous_list);

Calling SLPPF once instead of llSetLinkTexture many times will make the changes appear simultaneously instead of sequentially, and will be somewhat faster. Also, since SLPPF asks you to specify offsets, repeats, and rotations, you can customize the way each texture is applied on each separate face.

  • Thanks 1

Share this post


Link to post
Share on other sites

And yes, the script you have should do what you want.  It may be old, but it should work.  It's just not the way I would approach it myself.  If you really want to learn how to script, write scripts. Don't spend time rewriting someone else's.  😉

  • Thanks 1

Share this post


Link to post
Share on other sites
20 minutes ago, Rolig Loon said:

And yes, the script you have should do what you want.  It may be old, but it should work.  It's just not the way I would approach it myself.  If you really want to learn how to script, write scripts. Don't spend time rewriting someone else's.  😉

I'm trying, I even wrote one or two simple scripts, but for now I’m mostly at the stage of changing and combining existing ones.
I think that in order to become a scripter, people go to this all their lives ...

Slppf - can it be used to apply not only diffuse, but normal and specular maps (materials) too?

Share this post


Link to post
Share on other sites
Posted (edited)
15 minutes ago, ainst Composer said:

Slppf - can it be used to apply not only diffuse, but normal and specular maps (materials) too?

Yes, it can.  That's what the parameters PRIM_NORMAL and PRIM_SPECULAR are for.  SLPPF is a powerful function.  You can make a lot of changes to prim parameters on links and faces across your linkset in a single stroke.
And yes, learning to script in any language takes time and practice, in the same way that learning a foreign language or how to solve differential equations takes time.  They all require higher-level thinking, an ability to see patterns and identify structures, and a good dollop of the patience and tolerance that it takes to solve puzzles.  There really is a lot to be learned by studying other people's scripts, but the risk is that you may not be able to tell whether you are studying good examples or rather poor ones -- or perhaps ones that were created in a different era to address specific conditions that you know nothing about.  At least when you write your own scripts, you know who made the mistakes.

Edited by Rolig Loon
  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)

@Rolig Loon

I have a problem with this script. Take a look please. It scrolls through the textures UUIDs in cicle from the list with the wrong face. I indicated the face 0 and the texture is updated on the face 2... These are the parameters I specified. tell me what am i doing wrong? Why does it behave this way and how to fix it?

//Adjustable global variables...you may change these
//texture list...this list should have 2 or more textures
list textures = [
    "e115becb-d5fe-3bb2-64e1-e07a956d3d54",
    "2c27c1ba-4295-3d3c-eeb0-3eec35df01c3",
    "b4030db3-17dc-5b1e-0603-b2f8f4ee813e",
    "339ca587-0d3e-1224-00ac-9786ebe1caf4"];//put your texture UUIDs/keys in here
 
//Please note there is a .2 second delay between prims.
//"prim number, side number, side number...side number"
//-1 equals all sides for that prim
list sides = [
    "1,0",
    "2,0",
    "3,0",
    "4,0"];//put in which sides you want the texture to be changed on.
float frequency = 2.0;//how often to change the texture in seconds. Shouldn't be below 2.0
 
//please note that the last and first texture will be shown less frequently than those in between
integer random = FALSE;//whether to show the textures randomly, or in order
integer duplicatecheck = FALSE;//if random is true, this will check to make sure the random selection is a new texture

 

Edited by ainst Composer

Share this post


Link to post
Share on other sites
Posted (edited)

@Rolig Loon Thats what happens...

... when you use someone else script

I am sorry, something is wrong with adding GIFs. I am trying to add gif to show you but it posts empty messages.

https://gyazo.com/97af448326fd8ab22041b7e5aff193dd

I guess the reason is in timer.i just need to get rid of the timer somehow...

But then,  why it applies on the wrong face? No matter what face i specify it applies on face 2.

Edited by ainst Composer

Share this post


Link to post
Share on other sites

OK.... It works for me, as in this GIF

4c4a34722334c7f9ca1f935c93884ac8.gif

The trick, though, is that you need to correct a silly mistake in the script.  I wonder why the original scripter didn't catch it. Look where I have marked and then compare with the original

changetexture()//user fucntion to change texture
{
    integer counter;
    key texture = llList2String(textures,currenttexture);//gets texture key from list
    do
    {
        //also with another script
        list primdata = llCSV2List(llList2String(sides,counter));
        integer prim = (integer)llList2String(primdata,0);
        integer primlistlength = llGetListLength(primdata);//speed hack could go here
        integer primlistcounter = 1;//start at 1 since the prim datalist's 1st entry is the prim
        do
        {
            //probably best to use llSetLinkPrimitiveParams
            //prim, texture, side
            llSetLinkTexture(prim,texture,(integer)llList2String(primdata,primlistcounter)); // <<< LOOK HERE...
        }while(++primlistcounter < primlistlength);
    }while(++counter <numberofsidestochange);
}

See where the original script was looking in the wrong list?  It's not too hard to spot if you think through the logic of what those nested do/while loops are meant to do.

BTW, My sides list is a little different from yours, partly because I wanted to watch a third link as well and partly because I corrected for your error in link numbering.  The root prim in a linkset is #1, not #0.  So my list looks like

list sides = ["1,1,2,5","2,3,4,1","3,2,0,4"];

 

  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)

@Rolig Loon Thank you very much!
Now a new problem. The same texture applies on both faces of both prims. (On the second face is the same texture only stretched)

//texture list...this list should have 2 or more textures
list textures = [
    "d511b62a-ec31-26d8-e6ac-a81eee01fc81",
    "1f22b3bd-a654-9758-d511-da392b1aa2bb"
    ];//put your texture UUIDs/keys in here
 
//Please note there is a .2 second delay between prims.
//"prim number, side number, side number...side number"
//-1 equals all sides for that prim
list sides = [
    "3,1",
    "7,0"
    ];//put in which sides you want the texture to be changed on.

https://gyazo.com/8e1567e5a3484da0ea0e60b5c0886e35

Oh by the way I added      llRemoveInventory(llGetScriptName());  after      changetexture();//change the texture (both lines 81 and 90 because i wanted to script self-delete)

Could it be the reason?

 

I am thinking to create a new script using SLPPF...

Edited by ainst Composer

Share this post


Link to post
Share on other sites
Posted (edited)

Thats what i have so far. It changes all three types of materials textures on one face of one prim in the linkset.
I can manually add each prim and face but this is very inconvenient. I don’t know what to do next. To specify at the top of script list of all the prims and faces and textures UUIDs like in the old script? Is there any useful parts? Because now i see it does absolutely not what i needed. It applies each same texture from the list in order or random.

NEW Script

integer LINKNUM=2; 
integer FACE=0; 

vector WHITE=<1.0,1.0,1.0>;

string DIFFUSE_1 = "d8d8b2e0-7b93-10ed-92ec-67f07dab1271";
string NORMAL_1 = "b83326c9-9cb7-7b31-3938-3558e3571481";
string SPECULAR_1 = "79059f93-6ced-1211-505c-aa5cd41a61ca";


default
{
    state_entry()
    {
        llSay(0, "Hello, changing texture!");
        
        llSetLinkPrimitiveParams
(LINKNUM,   [

PRIM_TEXTURE,FACE,DIFFUSE_1,<1,1,0>,ZERO_VECTOR,0.0,                                
PRIM_NORMAL,FACE,NORMAL_1,<1,1,0>,ZERO_VECTOR,0.0,    

PRIM_SPECULAR,FACE,SPECULAR_1,<1,1,0>,ZERO_VECTOR,0.0,WHITE,100,5

]);
llRemoveInventory(llGetScriptName());
    }

}

Okay, to hell normal maps! As a beginning diffuse maps only! I guess its easier to make a list...

integer LINKNUM=2; 
integer FACE=0; 

vector WHITE=<1.0,1.0,1.0>;

string DIFFUSE_1 = "d8d8b2e0-7b93-10ed-92ec-67f07dab1271";



default
{
    state_entry()
    {
        llSay(0, "Hello, changing texture!");
        
        llSetLinkPrimitiveParams
(LINKNUM,   [

PRIM_TEXTURE,FACE,DIFFUSE_1,<1,1,0>,ZERO_VECTOR,0.0

]);
llRemoveInventory(llGetScriptName());
    }

}

 

Edited by ainst Composer

Share this post


Link to post
Share on other sites
Posted (edited)

@Rolig Loon

Ok i got this working. But the script appears very huge. Especially if using more textures. How to simplify?

I like the idea of making list of texture UUIDs, prims and faces from the old script. But i really dont get it...

In this version i used materials for one face, but it would be great to make it work at least for diffuse only.

integer PRIM_1=7; 
integer PRIM_2=3;
integer PRIM_3=3;
integer PRIM_4=3;
integer PRIM_5=4;
integer PRIM_6=5;
integer PRIM_7=6;

integer FACE_1=0; 
integer FACE_2=0;
integer FACE_3=1;
integer FACE_4=2;
integer FACE_5=0;
integer FACE_6=0;
integer FACE_7=0;

vector WHITE=<1.0,1.0,1.0>;

string DIFFUSE_1 = "1f22b3bd-a654-9758-d511-da392b1aa2bb";
string NORMAL_1 = "457503d4-4804-753a-4a64-ef4fb3cf7d92";
string SPECULAR_1 = "50576c65-a64c-243e-14ca-30aa2ab86a6a";

string DIFFUSE_2 = "e115becb-d5fe-3bb2-64e1-e07a956d3d54";
string DIFFUSE_3 = "2c27c1ba-4295-3d3c-eeb0-3eec35df01c3";
string DIFFUSE_4 = "e115becb-d5fe-3bb2-64e1-e07a956d3d54";
string DIFFUSE_5 = "b4030db3-17dc-5b1e-0603-b2f8f4ee813e";
string DIFFUSE_6 = "b4030db3-17dc-5b1e-0603-b2f8f4ee813e";
string DIFFUSE_7 = "b4030db3-17dc-5b1e-0603-b2f8f4ee813e";

default
{
    state_entry()
    {
        llSay(0, "Hello, changing texture!");
        
        llSetLinkPrimitiveParamsFast
(PRIM_1,   [

PRIM_TEXTURE,FACE_1,DIFFUSE_1,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_NORMAL,FACE_1,NORMAL_1,<1,1,0>,ZERO_VECTOR,0.0,    
PRIM_SPECULAR,FACE_1,SPECULAR_1,<1,1,0>,ZERO_VECTOR,0.0,WHITE,100,5,PRIM_COLOR,FACE_1,<1,1,1>,1.0,
PRIM_LINK_TARGET,
PRIM_2,
PRIM_TEXTURE,FACE_2,DIFFUSE_2,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_LINK_TARGET,
PRIM_3,
PRIM_TEXTURE,FACE_3,DIFFUSE_3,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_LINK_TARGET,
PRIM_4,
PRIM_TEXTURE,FACE_4,DIFFUSE_4,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_LINK_TARGET,
PRIM_5,
PRIM_TEXTURE,FACE_5,DIFFUSE_5,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_COLOR,FACE_1,<1,1,1>,1.0,
PRIM_LINK_TARGET,
PRIM_6,
PRIM_TEXTURE,FACE_6,DIFFUSE_6,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_COLOR,FACE_1,<1,1,1>,1.0,
PRIM_LINK_TARGET,
PRIM_7,
PRIM_TEXTURE,FACE_7,DIFFUSE_7,<1,1,0>,ZERO_VECTOR,0.0,
PRIM_COLOR,FACE_1,<1,1,1>,1.0


]);
llRemoveInventory(llGetScriptName());
    }

}

 

Edited by ainst Composer

Share this post


Link to post
Share on other sites

There you go.  You got rid of the extra baggage that you really didn't need in the other script.  You didn't need the timer for what you are planning, and now you have a single SLPPF statement. It's not really all that long and it won't look quite as scary if you do a little aesthetic compacting. Look for chunks of code that you keep repeating over and over again, like

<1,1,0>,ZERO_VECTOR,0.0

and then use that as a list element to write

list stuff = [<1,1,0>,ZERO_VECTOR,0.0];

llSetLinkPrimitiveParamsFast(LINK_SET,
[34,PRIM_1,PRIM_TEXTURE,FACE_1,DIFFUSE_1]+ stuff +
[PRIM_NORMAL,FACE_1,NORMAL_1]+ stuff +
PRIM_SPECULAR,FACE_1,SPECULAR_1] + stuff + [WHITE,100,5,PRIM_COLOR,FACE_1,<1,1,1>,1.0] +
[34,PRIM_2,PRIM_TEXTURE,FACE_2,DIFFUSE_2] +stuff +
[34,PRIM_3,PRIM_TEXTURE,FACE_3,DIFFUSE_3] + stuff +

and so forth.  After the first few lines where you have normal and spec textures, the code really starts to look streamlined.  Doing that doesn't buy you extra efficiency but it makes the script look prettier and it forces you to focus on the parts of the statement that are unique while putting all the repeating stuff aside visually.  In my mind, code aesthetics is more than simply making your work look nice.  A well organized, clean script is easier to read, so it's easier to spot where you may have made a mistake and easier to debug and adjust later.

BTW, note that the very beginning of your statement is not quite right.  Your statement is supposed to be addressing the whole linkset, so it has to begin with

llSetLinkPrimitiveParamsFast(LINK_SET,[34, ......

(34 is the integer code for PRIM_LINK_TARGET, so that shortens things visually even further ).

 

  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)
4 hours ago, Rolig Loon said:

There you go.  You got rid of the extra baggage that you really didn't need in the other script.  You didn't need the timer for what you are planning, and now you have a single SLPPF statement. It's not really all that long and it won't look quite as scary if you do a little aesthetic compacting. Look for chunks of code that you keep repeating over and over again, like


<1,1,0>,ZERO_VECTOR,0.0

and then use that as a list element to write

list stuff = [<1,1,0>,ZERO_VECTOR,0.0];


llSetLinkPrimitiveParamsFast(LINK_SET,
[34,PRIM_1,PRIM_TEXTURE,FACE_1,DIFFUSE_1]+ stuff +
[PRIM_NORMAL,FACE_1,NORMAL_1]+ stuff +
PRIM_SPECULAR,FACE_1,SPECULAR_1] + stuff + [WHITE,100,5,PRIM_COLOR,FACE_1,<1,1,1>,1.0] +
[34,PRIM_2,PRIM_TEXTURE,FACE_2,DIFFUSE_2] +stuff +
[34,PRIM_3,PRIM_TEXTURE,FACE_3,DIFFUSE_3] + stuff +

and so forth.  After the first few lines where you have normal and spec textures, the code really starts to look streamlined.  Doing that doesn't buy you extra efficiency but it makes the script look prettier and it forces you to focus on the parts of the statement that are unique while putting all the repeating stuff aside visually.  In my mind, code aesthetics is more than simply making your work look nice.  A well organized, clean script is easier to read, so it's easier to spot where you may have made a mistake and easier to debug and adjust later.

BTW, note that the very beginning of your statement is not quite right.  Your statement is supposed to be addressing the whole linkset, so it has to begin with

llSetLinkPrimitiveParamsFast(LINK_SET,[34, ......

(34 is the integer code for PRIM_LINK_TARGET, so that shortens things visually even further ).

 

Thanks a lot!

The script indeed turns out much shorter!

Edited by ainst Composer

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...