carley Greymoon Posted September 30, 2017 Posted September 30, 2017 (edited) hi, i'm making a texture change HUD. the code i used was: default { state_entry() { llListen (-xxxxx,"","",""); } listen(integer channel, string name, key id, string msg) { llSetTexture(msg,ALL_SIDES); } that worked perfect. you wore or rezzed the object, click on the HUD, enter the UUID and all the parts changed very fast and reliable. trouble was anyone else using the same HUD could change the texture on your object as well. so to make it owner specific i added if (llGetOwnerKey(id) == llGetOwner()) making it: default { state_entry() { llListen (-xxxxxx"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ llSetTexture(msg,ALL_SIDES); } } } that technically works but it is very glitchy, sometimes the linkset goes randomly transparent, other times just some parts get the texture. reapplying the same texture does nothing, using a different texture makes everything change again but wit the same randomness and unreliable. only after 4 or 5 tries does it finally work right. it's maddening. i'm guessing it is lag and that when the desired texture finally gets into the cache it works. can it be that adding the get owner key and comparing it causes too much lag and it makes the scripts fail randomly? this script goes into an object with about 90 prims. in other words there is 90 iterations of the script firing at once. is that the problem and is there a better way of doing it? i'm new to scripting and have just cobbled together code i've found here and on other sites. thank you for any help. Edited September 30, 2017 by carley Greymoon
Fluffy Sharkfin Posted September 30, 2017 Posted September 30, 2017 3 hours ago, carley Greymoon said: this script goes into an object with about 90 prims. in other words there is 90 iterations of the script firing at once. Rather than having a script in every prim in your linkset try using a single script in the root with llSetLinkTexture(LINK_SET, msg, ALL_SIDES);
Nova Convair Posted September 30, 2017 Posted September 30, 2017 (edited) 1st - you need only one script - see Fluffy's post 2nd - the script doesn't check if it receives an uuid (ok, not that important here ) if (llGetOwnerKey(id) == llGetOwner()){ key uuid = (key)msg; if (uuid) { llSetLinkTexture(LINK_SET,msg,ALL_SIDES); } } 3rd - if you encounter update problems - means the textures are changed but you don't see the result - it helps to change another thing on the object. For example set an invisible hovertext (with llSetText) Edited September 30, 2017 by Nova Convair
carley Greymoon Posted September 30, 2017 Author Posted September 30, 2017 (edited) i don't think i can use setlink. imagine an avatar, it is one mesh( 1 linkset) but has 3 sections, the head, torso and lower with 3 different textures. separating the sections into their own object, then i could apply the texture to the whole thing with SetLink but then each section would have to be worn separately, meaning a person would have to use 3 attachment points. so that's why i put a script in each part, in essence i grouped them by using different listening channels for each section. before i added the owner check it work really well, no issues at all. Nova, i had no idea it should check if it did indeed receive a UUID but it sounds logical that it should, thank you for pointing that out and providing an example snippet. i will try to insert that bit. i'm not sure what you mean by number 3. i myself can change other things to get it to update eventually but i can't ask that of users, although i'm sure i'm not understanding what you mean. Edited September 30, 2017 by carley Greymoon
Klytyna Posted September 30, 2017 Posted September 30, 2017 1 hour ago, carley Greymoon said: i don't think i can use setlink. imagine an avatar, it is one mesh( 1 linkset) but has 3 sections, the head, torso and lower with 3 different textures. separating the sections into their own object, then i could apply the texture to the whole thing with SetLink but then each section would have to be worn separately, meaning a person would have to use 3 attachment points. 6 hours ago, Fluffy Sharkfin said: llSetLinkTexture(LINK_SET, msg, ALL_SIDES); Look at the command again... The example given is using wildcard parameters... LINK_SET means all prims in the link, ALL_SIDES means all faces on the prim. You CAN use llSetLinkTexture, just specify WHICH prim in the linkset and which faces on the prim in each use of the command. So, for say a mesh body that's 1 'prim' with 3 faces each with a different texture, your single script would have 3 uses of llSetLinkTexture, each applying a different image to a different 'face' of the 'prim'.
Xiija Posted September 30, 2017 Posted September 30, 2017 if the main problem was people using the same channel in their HUDs ... chan = 0x80000000 | (integer)("0x"+(string)llGetOwner()); // unique channel based on owners UUID llListen (chan,"","",""); ( now each HUD has a unique channel )
Fluffy Sharkfin Posted September 30, 2017 Posted September 30, 2017 12 minutes ago, Klytyna said: So, for say a mesh body that's 1 'prim' with 3 faces each with a different texture, your single script would have 3 uses of llSetLinkTexture, each applying a different image to a different 'face' of the 'prim'. Unfortunately that's not going to work if they want to apply different textures to different parts of the linkset since we can't use lists of integers to specify link numbers in llSetLink commands (which is a real shame). Personally I'd suggest using a for loop with llSetLinkPrimitiveParamsFast() and a list of link numbers for each part of the object (head, torso and lower), it may take marginally longer to set the texture for all the children of a linkset but it's still preferable to having 90+ running scripts with listens. You can pass all three textures in a single message as a comma separated value and apply each texture to different parts of the linkset. list head = []; // link numbers for head list torso = []; // link numbers for torso list lower = []; // link numbers for lower setTexture(list link_numbers, key texture) { integer i; for (i=0; i < llGetListLength(link_numbers); i++) llSetLinkPrimitiveParamsFast(llList2Integer(link_numbers,i), [PRIM_TEXTURE, ALL_SIDES, texture, <1,1,0>, <0,0,0>, 0.0]); } default { state_entry() { llListen (-xxxxxx,"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(head,llList2Key(textures,0)); setTexture(torso,llList2Key(textures,1)); setTexture(lower,llList2Key(textures,2)); } } } Of course you'd need to fill in all the link numbers for each list at the start of the script, but a simple way to do that would be to rez the object, tint each of the sections a separate color then drop in a script which will check the color of each object in the linkset and compile the link numbers into 3 lists based on those colors and spit those lists out into chat. Then you can copy and paste those into the start of the script above.
carley Greymoon Posted October 1, 2017 Author Posted October 1, 2017 wow thanks for all the help and suggestions. i'm going to try both ways just so i can know more than one way of doing it. i had no idea you could automatically find link numbers by color. thanks to everyone for taking the time to help:)
Fluffy Sharkfin Posted October 1, 2017 Posted October 1, 2017 (edited) 46 minutes ago, carley Greymoon said: wow thanks for all the help and suggestions. i'm going to try both ways just so i can know more than one way of doing it. i had no idea you could automatically find link numbers by color. thanks to everyone for taking the time to help:) Well, it's not automatic but you can do it with a simple script like so... default { state_entry() { integer i; vector color; list head = []; list torso = []; list lower = []; for (i=1; i<=llGetNumberOfPrims(); i++) { color = llList2Vector(llGetLinkPrimitiveParams(i,[PRIM_COLOR,0]),0); if (color == <1,0,0>) head = head + [i]; else if (color == <0,1,0>) torso = torso + [i]; else if (color == <0,0,1>) lower = lower + [i]; } llOwnerSay("\nlist head = ["+llList2CSV(head)+"];\nlist torso = ["+llList2CSV(torso)+"];\nlist lower = ["+llList2CSV(lower)+"];"); } } ... just tint the different sections red, green and blue and then drop the above script in and it will output the lists of link numbers for each section complete with formatting so you can just copy and paste, replacing the first three lines of the other script. Edited October 1, 2017 by Fluffy Sharkfin
carley Greymoon Posted October 1, 2017 Author Posted October 1, 2017 1 hour ago, Fluffy Sharkfin said: Well, it's not automatic but you can do it with a simple script like so... default { state_entry() { integer i; vector color; list head = []; list torso = []; list lower = []; for (i=1; i<=llGetNumberOfPrims(); i++) { color = llList2Vector(llGetLinkPrimitiveParams(i,[PRIM_COLOR,0]),0); if (color == <1,0,0>) head = head + [i]; else if (color == <0,1,0>) torso = torso + [i]; else if (color == <0,0,1>) lower = lower + [i]; } llOwnerSay("\nlist head = ["+llList2CSV(head)+"];\nlist torso = ["+llList2CSV(torso)+"];\nlist lower = ["+llList2CSV(lower)+"];"); } } ... just tint the different sections red, green and blue and then drop the above script in and it will output the lists of link numbers for each section complete with formatting so you can just copy and paste, replacing the first three lines of the other script. hi fluffy, i tried the script but the only output i got in chat was list head = []; list torso = []; list lower = []; no face numbers.
carley Greymoon Posted October 1, 2017 Author Posted October 1, 2017 as a test i tried on a 3 prim link set as well, i get the same result.
Rolig Loon Posted October 1, 2017 Posted October 1, 2017 (edited) Are you actually coloring those test prims Red (<1,0,0>), Green (<0,1,0>) and Blue (<0,0,1>), not just some random reddish, greenish, bluish colors? As written, that little script will be looking for pure hues. Edited October 1, 2017 by Rolig Loon
carley Greymoon Posted October 1, 2017 Author Posted October 1, 2017 26 minutes ago, Rolig Loon said: Are you actually coloring those test prims Red (<1,0,0>), Green (<0,1,0>) and Blue (<0,0,1>), not just some random reddish, greenish, bluish colors? As written, that little script will be looking for pure hues. hi rolig, yes that was the problem. in the color picker i was using "rgb" with the values of 100, 0 ,0 and so on instead of "lsl". thanks for that:) i'm going to try the mesh now:) i'll be back a bit later with hopefully some good news:)
Fluffy Sharkfin Posted October 1, 2017 Posted October 1, 2017 Yes, sorry I probably should have mentioned that you need to use the exact color values as the script ignores any members of the linkset which aren't tinted the correct colors.
carley Greymoon Posted October 1, 2017 Author Posted October 1, 2017 hi Fluffy, no worries, i'm just grateful for the help. i got it all set up and the scripts, the sender and receiver are communicating but the texture is not being set, instead it just turns gray. could it be the texture UUID is not getting passed onto the receiver script?
Rolig Loon Posted October 1, 2017 Posted October 1, 2017 I hate to ask another "Is it plugged in?" question, but since I can't see your finished script to be sure ..... Did you actually include the texture UUIDs in your script somewhere?
carley Greymoon Posted October 2, 2017 Author Posted October 2, 2017 hi Rolig, the texture UUID is input by the user via a text box. this is the code of the sender script default { state_entry() { llListen(-xxxxxx,"","",""); } touch_start(integer total_number) { llTextBox(llDetectedKey(0)," \n Enter a texture UUID",-xxxxxx); } listen(integer channel, string name, key id, string msg) { llRegionSay(-12345,msg); } } and this is the code of the receiver script provided by fluffy(much thanks), i modified it to split it into one script for each section, so the user would have one button per section so they could apply textures independently. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ list lower = [50, 51, 52, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93]; setTexture(list link_numbers, key texture) { integer i; for (i=0; i < llGetListLength(link_numbers); i++) llSetLinkPrimitiveParamsFast(llList2Integer(link_numbers,i), [PRIM_TEXTURE, ALL_SIDES, texture, <1,1,0>, <0,0,0>, 0.0]); } default { state_entry() { llListen(-xxxxxx,"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(lower,llList2Key(textures,2)); } } }
Nova Convair Posted October 2, 2017 Posted October 2, 2017 This doesn't work: listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(lower,llList2Key(textures,2)); } } msg is a string the list you compose out of msg consists of strings llList2Key only works if the list has stored a key it does not convert a string to a key you need to use: setTexture(lower,(key)llList2String(textures,2));
carley Greymoon Posted October 2, 2017 Author Posted October 2, 2017 (edited) 1 hour ago, Nova Convair said: This doesn't work: listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(lower,llList2Key(textures,2)); } } msg is a string the list you compose out of msg consists of strings llList2Key only works if the list has stored a key it does not convert a string to a key you need to use: setTexture(lower,(key)llList2String(textures,2)); hi Nova, i just tried that and i still get the same result, the lower section just turns gray. when open the edit panel it show a gray texture in the texture window same as before. this is the script with your change: list lower = [50, 51, 52, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93]; setTexture(list link_numbers, key texture) { integer i; for (i=0; i < llGetListLength(link_numbers); i++) llSetLinkPrimitiveParamsFast(llList2Integer(link_numbers,i), [PRIM_TEXTURE, ALL_SIDES, texture, <1,1,0>, <0,0,0>, 0.0]); } default { state_entry() { llListen(-xxxxxx,"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(lower,(key)llList2String(textures,2)); } } } ----------------------------------------------------------------------- this starting to get weird. i'm wracking my brain to think of something i might be overlooking and not including here but i can't think of anything. i'm sorry to be such a pain. i get the feeling once it is figured out why it's not working i'm going to feel bad for having overlooked mentioning some thing. Edited October 2, 2017 by carley Greymoon
carley Greymoon Posted October 2, 2017 Author Posted October 2, 2017 (edited) i just tried the script again as a whole and the only part that gets the texture set is the head section, wich is also the root prim. list head = [1]; list torso = [42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134]; list lower = [50, 51, 52, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93]; setTexture(list link_numbers, key texture) { integer i; for (i=0; i < llGetListLength(link_numbers); i++) llSetLinkPrimitiveParamsFast(llList2Integer(link_numbers,i), [PRIM_TEXTURE, ALL_SIDES, texture, <1,1,0>, <0,0,0>, 0.0]); } default { state_entry() { llListen (-xxxxxx,"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list textures = llCSV2List(msg); setTexture(head,llList2Key(textures,0)); setTexture(torso,llList2Key(textures,1)); setTexture(lower,llList2Key(textures,2)); } } } i also tried it with llList2String, same result, only the head section gets the texture set. Edited October 2, 2017 by carley Greymoon
Fluffy Sharkfin Posted October 2, 2017 Posted October 2, 2017 1 hour ago, Nova Convair said: llList2Key only works if the list has stored a key it does not convert a string to a key From the wiki Quote If the type of the element at index in src is not a key it is typecast to a key. If it cannot be typecast null string is returned. carley, the reason the script isn't working as you have it now is it was written to work with three texture UUIDs, if you're passing a single UUID to it then you simply need to change setTexture(lower,(key)llList2String(textures,2)); to setTexture(lower,(key)llList2String(textures,0)); But, that would defeat the purpose of separating the message into a list of UUIDs since there's only one. The idea is to handle changing all the textures of the linkset using a single script rather than using multiple scripts for each texture.
Fluffy Sharkfin Posted October 2, 2017 Posted October 2, 2017 (edited) Okay since you're sending texture UUIDs one at a time rather than all three at once, try this... Sender Script (based on the script you currently have) default { state_entry() { llListen(-54321,"","",""); } touch_start(integer total_number) { llTextBox(llDetectedKey(0)," \n Enter a bodypart and texture UUID",-54321); } listen(integer channel, string name, key id, string msg) { llRegionSay(-12345,msg); } } Receiver Script (based on the script I posted earlier) list head = [1,2,3]; list torso = [4,5,6]; list lower = [7,8,9]; setTexture(list link_numbers, key texture) { integer i; for (i=0; i < llGetListLength(link_numbers); i++) llSetLinkPrimitiveParamsFast(llList2Integer(link_numbers,i), [PRIM_TEXTURE, ALL_SIDES, texture, <1,1,0>, <0,0,0>, 0.0]); } default { state_entry() { llListen (-12345,"","",""); } listen(integer channel, string name, key id, string msg) { if (llGetOwnerKey(id) == llGetOwner()){ list data = llCSV2List(msg); string bodypart = llList2String(data,0); key texture = llList2Key(data,1); if (bodypart == "head") setTexture(head,texture); else if (bodypart == "torso") setTexture(torso,texture); else if (bodypart == "lower") setTexture(lower,texture); } } } In order for it to work you need to specify both which bodypart you wish to apply the texture to and the texture UUID as a CSV. For example: Quote head,89556747-24cb-43ed-920b-47caed15465f will texture the head with the default plywood texture. It's not the most elegant solution to selecting which bodypart to texture, personally I'd go with a HUD or at least an llDialog menu rather than having to type the bodypart name into the text box, but at least you can test it and see it working. Edited October 2, 2017 by Fluffy Sharkfin typo
carley Greymoon Posted October 2, 2017 Author Posted October 2, 2017 oh wow, Thank you so much Fluffy:) it's working now as separate scripts. one for each section. 3 sections each with their own buttons. which is just fine with me, it serves my purpose. but i don't understand how all 3 could work with one script. the user can input 3 UUIDs into one text box? i know you must be right, i just don't get how the script could know which UUID belongs to what section. lets say the torso texture UUID is 111-1111-1111-111 and the lower is 222-2222-222. how could the script know texture 111-1111-111 belongs to list torso = [42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134];? in any case i thank you profusely:) and everyone else as well.
Fluffy Sharkfin Posted October 2, 2017 Posted October 2, 2017 7 minutes ago, carley Greymoon said: oh wow, Thank you so much Fluffy:) it's working now as separate scripts. one for each section. 3 sections each with their own buttons. which is just fine with me, it serves my purpose. but i don't understand how all 3 could work with one script. the user can input 3 UUIDs into one text box? i know you must be right, i just don't get how the script could know which UUID belongs to what section. lets say the torso texture UUID is 111-1111-1111-111 and the lower is 222-2222-222. how could the script know texture 111-1111-111 belongs to list torso = [42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134];? in any case i thank you profusely:) and everyone else as well. in the original script that I posted earlier the textures are meant to be sent in a certain order (head, torso, lower), the script simply assumes that's the order in which the three UUIDs have been sent and applies them to the corresponding bodyparts. As for the new script, since you're sending them one at a time you have to specify which bodypart it applies the texture to and include that information in the message (i.e. "torso,111-1111-1111-111" or "lower,222-2222-222"). As I suggested earlier you could include an llDialog command to open a menu with three buttons (head, torso, lower) then when the user presses one the script automatically opens the text input window to allow them to input the texture UUID. That way they don't have to type in the name of the bodypart they can just select it from the menu, but having separate buttons for each section works just as well (although you can also do that using a single script rather than three separate ones if you put the script in the root object and use llDetectedLinkNumber() in the touch event). Anyway, I'm glad it's working for you now!
carley Greymoon Posted October 2, 2017 Author Posted October 2, 2017 ahhh ok i get it. and the llDialog method sounds very cool I learned a lot from this thread. Thanks again, without people like you, Rolig and Nova life would be much harder. 13 minutes ago, Fluffy Sharkfin said: in the original script that I posted earlier the textures are meant to be sent in a certain order (head, torso, lower), the script simply assumes that's the order in which the three UUIDs have been sent and applies them to the corresponding bodyparts. As for the new script, since you're sending them one at a time you have to specify which bodypart it applies the texture to and include that information in the message (i.e. "torso,111-1111-1111-111" or "lower,222-2222-222"). As I suggested earlier you could include an llDialog command to open a menu with three buttons (head, torso, lower) then when the user presses one the script automatically opens the text input window to allow them to input the texture UUID. That way they don't have to type in the name of the bodypart they can just select it from the menu, but having separate buttons for each section works just as well (although you can also do that using a single script rather than three separate ones if you put the script in the root object and use llDetectedLinkNumber() in the touch event). Anyway, I'm glad it's working for you now!
Recommended Posts
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