Jump to content

Changing multiple textures in a multi-prim object


Fanny Starlight
 Share

You are about to reply to a thread that has been inactive for 1366 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi everybody.

I am new to scripts (LSL), mostly I have worked with full permission ones, doing changes to them for my private creations in second life. I do understand the basics (by now), after a lot of trying and failing :-). To my question, I have a multi-prim object (cloth), with 24 different textures (for state changes), which, after a lot of try's, is working fine now. Now,  the script works with the names of those textures, and if I would like to replace the textures, I need the same names on those, otherwise the script stops working. Is there a way to do that? I did find a lot of texture changing scrips, but all require different names (which I do understand, like the ones here: http://wiki.secondlife.com/wiki/Bobbyb%27s_texture_changer). I wonder if it is possible to replace texture A with Texture A, or if there is no way around that, and one only can replace A with B.

I hope my question is not to confusing, and I would be very grateful for advice.

Thank You all

Fanny

Link to comment
Share on other sites

  • Fanny Starlight changed the title to Changing multiple textures in a multi-prim object

what, insofar as your script is concerned, is the difference between "texture A" and "Texture A" other than the characters "t" and "T".  From a LSL pov "t" and "T" are contextually as different as are "A" and "B""

if you can expand a bit more on what you mean when you say "texture A" and "Texture A" as distinct from texture "A" and texture "B" then we might be able to help

Link to comment
Share on other sites

I too don't understand the naming distinction being made here, but I'm also a bit concerned with the approach of using texture names at all, because it entails bunding the textures in the object contents. I mean, that works, but it's really messy keeping track of those contents, setting permissions, the next owner potentially removing them and breaking the script, etc., when you could instead reference the textures by "key" (UUID) so you don't need to include them inside the object at all. It's a little different workflow for you, but it's a tidier product (unless you want your users to have those textures for other uses).

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, turtle2002 said:

Is there a way to do that?

Two ways. Both hard, but the first might be easier to understand.

The first is probably the worst since it fills up the object inventory and as that gets bigger, editing it gets slower, but in essence; have the textures in the object with their actual name in the description field, and the name of the texture is the name the script expects. So if you decided to replace some of the textures, you would first of all rename the ones back to whatever their original name was from the description field, then add the new textures, with their actual names in the description fields and their object inventory name whatever is appropriate for how the script is going to use them. So if you are going to have a different texture for "Texture_2" you would rename Texture_2 to what it's description reads, copy in the new texture, put it's name in the description field, and then rename it to "Texture_2".

 

The second is a lot more complicated and either needs you to add a notecard reader to your script or else edit the script itself if you need to alter the textures. It builds on Qie's advice to refer to textures by UUID instead of by name, which then means they do not need to be in the object at all.

Effectively you already have in the script some variables, such as string texture1="nameOfTexture"... You either edit your script and amend what is on the righthand side of the assignment, or you have a section that reads a notecard with lines of the form texture1=UUIDofTexture

Both suggestions are going to involve a fair bit of work, but I suspect my first suggestion will be easiest to implement initially. Long-term, the use of UUIDs and a notecard reader will be much better.

  • Like 1
Link to comment
Share on other sites

Thank you all so much!

I am trying the notecard version, since I have already a notecard reader in there.

To Qie, I noted the concern, but since it is for myself, I don't think it is a problem, and if one day I would make stuff for others, I will take an other approach, and, with the suggestion of Haiku, it kind of solves itself.

I will work on it the next few day's and see if I can get it to work.

  • Like 1
Link to comment
Share on other sites

Hi all

I did manage to put in a reader script (I could modify one), I did list the UUID's in a notecard, and when clicked it starts the reading process, but I am completely stuck on how to tell the script to pull those UUID's I have so far what You see below. I know I need to tell the script to link/get/replace the textures from the notecard after that, what is below, but all try's failed.

Is it just llGetTexture() to pull it from the notecard and how to I tell the script to replace it (if statement i guess?)? And I guess I have to list the strings of the textures to be replaced in the script too....

As I said, I am a beginner :-).

Thankies

Fanny

Reader script that I have so far:

key g_lineQuery;
string g_PrintoutCard = "Plain white";
integer isDebug = FALSE;
integer g_lineNum;
integer g_texturePrint;

//Texture strings here?

loadCustomTexturePrints() {
    if(isDebug < 2) {
    llOwnerSay("Texture❤Prints: Loading "+g_PrintoutCard+" texture notecard, this may take a minute or two!");
    }
    g_lineNum = 0;
    if(llGetInventoryType("TEXTURE:" + g_PrintoutCard) != -1) {
    g_lineQuery = llGetNotecardLine("TEXTURE:" + g_PrintoutCard, g_lineNum);
    }
    else {
    llOwnerSay("No Notecard Found!\n Please drag this texture notecard into your model: TEXTURE:" + g_PrintoutCard);
    }
}
                default {
                state_entry() {
                loadCustomTexturePrints();   //load the default notecard on script reset?
                }

                dataserver(key query_id, string data) {
                if(g_lineQuery == query_id) {
                if(data != EOF) {
                ++g_lineNum; //Next Line
                integer index = llSubStringIndex(data, "");
                g_lineQuery = llGetNotecardLine("TEXTURE:" + g_PrintoutCard, g_lineNum);
                return;
                }
                g_lineQuery = llGetNotecardLine("TEXTURE:" + g_PrintoutCard, g_lineNum);
                }
                else {
                if(isDebug < 2) {
                llOwnerSay("Texture❤Prints: Done reading your texture notecard! :3");
                }
                if(isDebug == TRUE) {
                llOwnerSay("Texture❤Prints Script Memory Used: " + (string) llGetUsedMemory() + " Bytes");
                llOwnerSay("Texture❤Prints Script Memory Remaining: " + (string) llGetFreeMemory() + " Bytes");
                }
             }
          }
    }   

Link to comment
Share on other sites

1 hour ago, turtle2002 said:

Hi all

I did manage to put in a reader script (I could modify one), I did list the UUID's in a notecard, and when clicked it starts the reading process, but I am completely stuck on how to tell the script to pull those UUID's I have so far what You see below. I know I need to tell the script to link/get/replace the textures from the notecard after that, what is below, but all try's failed.

Is it just llGetTexture() to pull it from the notecard and how to I tell the script to replace it (if statement i guess?)? And I guess I have to list the strings of the textures to be replaced in the script too....

Just to clarify, I was thinking of putting the UUIDs right in the script, in a big long list, otherwise you'll be distributing a notecard with texture UUIDs that everybody can use (which is not such a tragedy as folks imagine; I mean, what will anybody else really do with a texture made to wrap around the UV map of a mesh, unless they're working with the very same mesh?), but fortunately it doesn't matter: if the script reads a notecard, it can use UUIDs or texture names, or even a mixture, because the functions that set an object's texture don't care: they'll use either one (the difference, as mentioned above is that the actual textures need to be in inventory if they'll be addressed by name).

Anyway, your script is going to need several significant additions. At the moment, it has the parts that access each line of a notecard but probably it will want to store all the textures it reads into some global list variable, so it can apply them to the right places when activated. It also needs some way for the user to activate that texture repainting, probably including a little menu system to choose a specific set of textures to use. And once the user makes that choice, it needs as you say some way of knowing which part (which link and which face on that link) should get painted by which of the textures it read from the notecard.

The actual setting of the chosen texture on a link's face you'll eventually do with llSetLinkPrimitiveParamsFast(), specifically the PRIM_TEXTURE parameter, just because it's most efficient (you can paint all the faces in all the prims with a single function call), but if it's intimidating at first, you can instead use calls to llSetLinkTexture() to get started.

(You mention llGetTexture() but your script probably won't use that function because it only checks to see what texture is currently painted on an object's face.)

We're also at that most exciting part of programming: "Data Structures" because your global list(s) and your notecard(s) need to specify that stuff about "which link and which face" for each texture. So... I guess think about how that might work, and someone will surely help with that if you want.

(Oh, also, to make it easier to post code in the forums, look for the little "<>" button in the forum post editor; it does a good job of preserving indentation.)

  • Like 1
Link to comment
Share on other sites

Thank You Qie,

I will use those "<>" next time :-), and I am pretty sure there will be a next time. Thank you for the clarification on the commands, I will try to implement those, and see what happens.

One question to your suggestion to put all the UUID's in the script, and then call up a set of it, with a notecard I can do that (notecardA, notecardB, and so on) and call up a set, that is what works so far, just the reading of the card gives me a bit of trouble,

How would I do that if I have a long list of UUID's in the script? The menu button would need to activate a bunch, not just one texture.

Thank you again, I really appreciate the help a lot

Fanny

Link to comment
Share on other sites

4 hours ago, turtle2002 said:

How would I do that if I have a long list of UUID's in the script? The menu button would need to activate a bunch, not just one texture.

There are at least a couple ways to handle that, probably the simplest is to add another "column" to the list of textures. This is the exciting "data structures" thing I was mumbling about.

Whether it's lines in a notecard or the series of data elements in the list, the script needs more than just texture identifiers in order to know what to do with those textures.

So maybe the list would be a long sequence of "rows" each of which contain "columns" for

  • Texture identifier (UUID or name or something)
  • Link to which it applies
  • Face to which it applies
  • Set of textures to which it belongs
  • and later maybe other stuff we haven't thought of yet

Then, when the user picks a texture Set from a menu, the script knows what to do: it steps through the whole list, one "row" at a time, looking for those that belong to that Set, and then painting the identified Texture on the Face of the Link specified on that "row."*

Now, when you lay out the whole list structured this way, you'll notice that there's a tremendous amount of redundancy. Each Set references the same number of rows, so you could just put all the rows in Set sequence and omit the actual Set identifier, relying instead on position in the list to know to which Set a row belongs. You could take that even further by knowing that the first row in a set always refers to Face 0 of Link 1, and so forth. Now you're back to a flat list of texture identifiers only, with all the structure hidden in the sequence of that list. But I'd suggest at least for now sticking to the longer, all explicit approach.

___________________
* I put scare quotes around "row" and "column" because lists are a flat data representation, it's only how we populate and interpret them that gives any structure. In other familiar languages there are arrays that have (at least) rows and columns built-in to the representation -- same as databases have tables of rows and columns -- so it's a handy way of communicating about a data structure. Incidentally, the number of "columns" in a list's "row" is called its "stride" which comes up when you want to sort the list. Also, the very simplest form of other languages such as LISP can get by with representing every thing with lists, too, leaving all structure to the program instead of the language. On the other hand, every real LISP includes arrays and structs and other structured data representations, and LISP lists can contain embedded lists, so feeling sorry for our LSL selves is somewhat justified.

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1366 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...