Jump to content

2 Linked Prims - Cycle Individual Inventory Textures From 1 Menu


joeyblueyes
 Share

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

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

Recommended Posts

Hi All,

I have 2 linked prim and each has (lets say) 5 textures each stored in its inventory!  When the linked object is touched, a menu appears.  Using 1 button for each prim in the menu, I would like to cycle through the textures in "that prim's" inventory!

 

In the Root Prim, I have the following code:

            textureIndex++;
            numTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
            if(textureIndex == numTextures) textureIndex = 0;
            textureName = llGetInventoryName(INVENTORY_TEXTURE, textureIndex);
            if (textureName != "") 
llSetTexture(textureName, side);

 

The above is working fine and cycling through all of the Textures stored in the "Root Prim".....  Good so far...

 

The problem is that I would like another button to cycle textures FOR the "Child Prim" FROM the "Child Prim's" Inventory!

 

I tried the following code similar to above:

            textureIndex++;
            numTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
            if(textureIndex < 0) textureIndex = numTextures - 1;
            textureName = llGetInventoryName(INVENTORY_TEXTURE, textureIndex);
            if (textureName != "")
            llSetLinkTexture(LINK_ALL_CHILDREN, textureName, ALL_SIDES);

 

Using "llSetLinkTexture", I can successfully cycle textures on the Child Prim, however, it uses the textures stored in the Root Prim's Inventory!

 

Seems that if there were a "llGetLinkInventoryNumber" & "llGetLinkInventoryName", then this would work fine!

 

Can someone please point me in the right direction to get the textures stored in the Child Prim's Inventory?

 

Thanks in advance!  :-)

 

Link to comment
Share on other sites

You can't do what you're trying to, at least not directly.   The script and the texture need to be in the same prim if the script is to read the texture's uuid (which is what it's doing).

So, one option, it seems to me, is to have a script in each prim and have the script in the root send a link message to tell the the script in the child prim when to read the next texture and apply it (actually, I think it would look better if the script sends the message to LINK_SET and responds to the link message, too).

The other option would be to have the script in the root prim change the textures in the child prim by using llSetLinkTexture or llSetLInkPrimitiveParamsFast.

Link to comment
Share on other sites


Innula Zenovka wrote:

You can't do what you're trying to, at least not directly.   The script and the texture need to be in the same prim if the script is to read the texture's uuid (which is what it's doing).

So, one option, it seems to me, is to have a script in each prim and have the script in the root send a link message to tell the the script in the child prim when to read the next texture and apply it (actually, I think it would look better if the script sends the message to LINK_SET and responds to the link message, too).

The other option would be to have the script in the root prim change the textures in the child prim by using llSetLinkTexture or llSetLInkPrimitiveParamsFast.

Thanks for your reply, Innula!

 

I'm not exactly sure how to impliment your first option, as I'm still quite green when it comes to scripting, but as for the second option, I did use llSetLinkTexture, and it works to change the texture in the Child, but only still with the textures stored in the Root!

 

I thought about llSetLInkPrimitiveParamsFast, but even with that, wouldn't I still be limited to just calling the Root prim textures?

 

Can you give me an idea on how to possibly use your 1st option?

 

Thanks for your help!!!

Link to comment
Share on other sites

This is how I would do it for the first option:

integer max;integer counter;default{	state_entry()	{		max = llGetInventoryNumber(INVENTORY_TEXTURE);		counter = 0;	}	changed(integer change){		if(change & CHANGED_INVENTORY){			llResetScript();		}	}	touch_start(integer total_number)	{		if(llDetectedLinkNumber(0)<2){//the root prim or a single, unlinked prim has been touched			llMessageLinked(LINK_SET,0,"",""); //send a message all scripts		}	}	link_message(integer sender, integer num, string str, key id){//on receiving a message		llSetTexture(llGetInventoryName(INVENTORY_TEXTURE,(counter%max)),ALL_SIDES);//advance the texture		counter++; //advance the counter	}}

 

 For the second method,  you would need to put all your textures in the root prim and have a way of distinguishing which ones were for use on the root prim and which for use on the child (two lists of names, either in the script or a notecard?).

Link to comment
Share on other sites

I've done a version of the second method by putting a set of "root prim" textures in the root prim and then scripting it to copy textures that are added later and send them to the child prim.  That way, the root has a full set and the child has only the "child prim" set.You can use the master script in the root prim to manage what happens as you add or remove textures, and can run a different touch menu in each prim.

Link to comment
Share on other sites

Thanks again Innula!

 

In your example where you have....  

llMessageLinked(LINK_SET,0,"",""); //send a message all scripts

Is the "0" what targets all scripts?  And if so, could that be "2" to target just the Child prim script?  Or second thought, there would only be 1 additional script, and that is the child prim script...  I'll have to see if I can give this a shot!

 

I do also like the idea of possibly using notecards to list the texture names, and have all in the root prim....  Hmmm!

 

Link to comment
Share on other sites


Rolig Loon wrote:

I've done a version of the second method by putting a set of "root prim" textures in the root prim and then scripting it to copy textures that are added later and send them to the child prim.  That way, the root has a full set and the child has only the "child prim" set.You can use the master script in the root prim to manage what happens as you add or remove textures, and can run a different touch menu in each prim.

Thanks Rolig!  My thought was to have the set in the child prim unchanged!  It would be the set that I originally add, but the set in the root prim would be what the user can add to, delete or change to preference!  Would your method still work in this way?

Link to comment
Share on other sites

The syntax of llMessageLinked is llMessageLinked(integer target, integer number, string string, key id).    

Target here is the target prim(s), which can be the constants LINK_SET, LINK_THIS, LINK_ROOT, LINK_ALL_CHILDREN, LINK_ALL_OTHERS or a specific link number.

The others, integer number, string string, and key id, are all arbitrary values you can pass to the receiver script if you want to.   Even if it's not used, the number argument has to have some sort of value, which is why I put 0 in -- I could just has well have used 99 or 999.

So, it's LINK_SET that targets all the scripts.   LINK_ALL_CHILDREN or LINK_ALL_OTHERS would target the child prim, as would llMessageLinked(2,999,"","").

The reason  I suggested sending a message to LINK_SET and triggering the texture change in both scripts that way is that it's going to synchronise them a lot better than is telling the main script to send a message to the other script and then to change the texture on its own prim.    It's not wrong to do it that way -- it's just my way tends to look better in most circumstances.

Link to comment
Share on other sites


joeyblueyes wrote:

Thanks Rolig!  My thought was to have the set in the child prim unchanged!  It would be the set that I originally add, but the set in the root prim would be what the user can add to, delete or change to preference!  Would your method still work in this way?

Sure.  The only reason I did it that way was that I wanted the root prim to be a "master" control that responds only to the owner, and the child prim to be a "public" control that would respond to anyone.  It was a teaching application --- answers on textures in the master control but not in the public one.

 

Link to comment
Share on other sites

It's a long script, written for a client.  I can't share it, therefore, but the guts are easy enough to describe.  Build a changed event that looks to see if the number of textures in the root prim has increased or decreased.  If it has increased, send a copy of the new texture for the child prim.  If it has decreased, tell the child prim to delete the same one from its inventory too.  Once you have that under control, then let the script in the root prim change the texture on it or the child prim, and let the script in the child prim only change its own textures.

There's no reason not to do the whole thing in one script, keeping all textures in the root prim and simply making two lists, as Innula suggested. At the time I wrote my script, though, that wasn't a possibility.

Link to comment
Share on other sites

Best of luck.

Do please keep in mind that, if you're using something like llSetLinkTexture to texture a child prim, you will need to be able to read the texture's uuid to apply it to the child prim.

This means the texture has to be full perms to the owner of the script.   While I'm not sure offhand what LSL lets you get away with if the texture is full perms -- whether llSetLinkTexture(2, "my texture name", ALL_SIDES) will work if the texture is full perms for you -- I know it won't work if it's not.

So if you want to have one script and two lists of textures -- whether the lists are hard-coded or read from a notecard -- you'll need to make sure that the child prim is receiving the uuid, not the texture name.

Link to comment
Share on other sites


Innula Zenovka wrote:

Best of luck.

Do please keep in mind that, if you're using something like llSetLinkTexture to texture a child prim, you will need to be able to read the texture's uuid to apply it to the child prim.

This means the texture has to be full perms to the owner of the script.   While I'm not sure offhand what LSL lets you get away with if the texture is full perms -- whether llSetLinkTexture(2, "my texture name", ALL_SIDES) will work if the texture is full perms for you -- I know it won't work if it's not.

So if you want to have one script and two lists of textures -- whether the lists are hard-coded or read from a notecard -- you'll need to make sure that the child prim is receiving the uuid, not the texture name.

Thank you so much, Innula!  All of the textures I'm using are ones I make myself, so the full perm part is easy there!  ;-)

Didn't get the chance to try any of the ideas here yet, but I hope to give it a go tomorrow!  Thanks again!!!

Link to comment
Share on other sites

Thanks -- that looks interesting, but my first reaction is that it seems rather a performance to keep on sending out all all those scripts and then deleting them every time you want to change a texture.   I can see how, at least in theory, it's maybe a better way to do it if you have lots and lots of boards which don't need to change very frequently (and which, when they do change, don't all need to change simulatenously), but I'm not sure I'd want to use it for most purposes.

I'd be interested to know what Rolig makes of it, since she's worked in that area.

 

Link to comment
Share on other sites

I was wondering about performance issues also, but I guess if the texture change isn't that often, it may not be an issue!  I do like the 2 little scripts that get the texture and prim UUID's for you!  That's a quick handy thing to have.....

 

The description states....  ".. load textures onto unlinked prims", but looking at it, I would think it should work on linked prims as well?

Link to comment
Share on other sites

I can't see any reason to use this on a system of linked prims, since you can always use llSetLinkPrimitiveParamsFast to to the same job with a single script now.  This system was written back in 2009, before SLPPF was available, of course.  This approach looks more interesting for a system of unlinked prims in the same region, although I share your feeling that it's a lot of work for something that can be done more easily by putting a very simple script in each remote billboard.  If those scripts are identical Mono-compiled scripts, the load on the sim's servers is negligible.

Link to comment
Share on other sites

I liked Innula's idea of 2 lists for the textures, but then got to thinking about simplicity for the end user to just be able to drag-n-drop textures, and not have to worry about updating a list!  If I were to use llSetLinkPrimitiveParamsFast, I'd have to use that list format!

Link to comment
Share on other sites

Like Rolig, I really cannot see any reason to do it this way in linked prims.   But, just  for reference, this is how I would do it, if I  was doing it this way for some reason I really cannot imagine.

First, I would prepare the target prim (which I assume is link number 2) like this:

integer pin = 12345;default{    state_entry()    {        llSetRemoteScriptAccessPin(pin);        llRemoveInventory(llGetScriptName());    }}

 I'd also put my textures into that prim.

Then, the root prim, I would put this

integer target_prim_no =2; // or whatever the link number iskey target_key;integer pin = 12345;integer counter;default{    state_entry()    {        if(llGetLinkNumber()>1){            integer n = llGetInventoryNumber(INVENTORY_TEXTURE);            if(n){//if there are any textures                integer i = llGetStartParameter();                string texture = llGetInventoryName(INVENTORY_TEXTURE, (i%n));                if(llGetInventoryType(texture)==INVENTORY_TEXTURE){//makes sure it exists                    llSetTexture(texture,ALL_SIDES);                    llRemoveInventory(llGetScriptName());                }            }        }    }    touch_end(integer total_number)    {//llRemoteLoadScriptPin sleeps the script for 3 seconds, so go into another state to make the prim untouchable while it's sleeping        state next;    }}state next {    state_entry()    {        target_key = llGetLinkKey(target_prim_no);        llRemoteLoadScriptPin(target_key,llGetScriptName(),pin,TRUE,counter);//pass the counter as the start parameter        counter++;        state default;    }}

 But, as I said, I really don't think it's the best way to do it.

Link to comment
Share on other sites


joeyblueyes wrote:

I liked Innula's idea of 2 lists for the textures, but then got to thinking about simplicity for the end user to just be able to drag-n-drop textures, and not have to worry about updating a list!  If I were to use 
llSetLinkPrimitiveParamsFast
, I'd have to use that list format!

I'm not sure why that's an issue. When a new texture is dropped into your object, just capture its UUID with llGetInventoryKey, then send it along to the slave scripts in the billboards for display.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4208 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...