Jump to content

llSetLinkTextureAnim breaks after resize


Edu Csak
 Share

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

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

Recommended Posts

Hello scripters!

I've got this texture and a script that allows to choose which frame (1-15) is to be applied on a prim.
I used llSetLinkTextureAnim to have it applied.
So far, so good.

I've also put a resizer script also on root prim and tested.
The menu popped up and on my fist selection of scale (0.1, 0.5... etc) was ok, worked pretty fine. It resized and the texture was ok after it.

BUT

If I ask to scale one more time, the texture animation "breaks" 

My question is: llSetLinkTextureAnim is the better method or the is another better way?
TYVM
 

Made a video: seeing is better than reading 😎 Watch how the script acts https://www.youtube.com/watch?v=xhrbdIYk3jE

 

integer CHAN= -99099;  
integer dialhandle;
key old_owner;
list Tchoose = ["RED","DEEP RED","ORANGE","LIGHT BROWN","BROWN","YELLOW","YELLOW LIGHT","LIME GREEN","GREEN","CYAN","BLUE","NAVY BLUE","PURPLE","PINK","GREY","BLACK"];
string Tmsg = "\nPlease choose ";
integer gMenuPosition;
float frame;
string desc;

Menu()
{
    llListenRemove(dialhandle);
    llSetTimerEvent(0.0);
    integer Last;
    list Buttons;
    integer All = llGetListLength(Tchoose);
    if(gMenuPosition >= 9)   //This is NOT the first menu page
    {
        Buttons += "<<";
        if((All - gMenuPosition) > 11)  // This is not the last page
        {
            Buttons += ">>";
        }
        else    // This IS the last page
        {
            Last = TRUE;
        }            
    }    
    else if (All > gMenuPosition+9) // This IS the first page
    {
        if((All - gMenuPosition) > 11)  // There are more pages to follow
        {
            Buttons += ">>";
        }
        else    // This IS the last page
        {
            Last = TRUE;
        }            
    }
    else    // This is the only menu page
    {
        Last = TRUE;
    }
    if (All > 0)
    {
        integer b;
        integer len = llGetListLength(Buttons);
        // This bizarre test does the important work ......        
        for(b = gMenuPosition + len + Last - 1 ; (len < 12)&&(b < All); ++b)
        {
            Buttons = Buttons + [llList2String(Tchoose,b)];
            len = llGetListLength(Buttons);
        }
    }
    dialhandle = llListen(CHAN,"",NULL_KEY,"");    
    llSetTimerEvent(10.0);
    llDialog(llGetOwner(),"\n"+Tmsg,Buttons,CHAN);
}
force_update() {
    desc=llList2String(llGetLinkPrimitiveParams(2, [ PRIM_DESC ]), 0);
    frame = llListFindList( Tchoose, [desc] );
    llSetLinkTextureAnim(2, ANIM_ON | SMOOTH, ALL_SIDES, 4, 4, frame, 1.0, 1.0 );
}
default
{
    changed(integer change)
    {
        if (change & (CHANGED_SCALE | CHANGED_TEXTURE | CHANGED_LINK | CHANGED_ALLOWED_DROP | CHANGED_SHAPE | CHANGED_COLOR | CHANGED_INVENTORY | CHANGED_TELEPORT | CHANGED_REGION_START | CHANGED_REGION |CHANGED_OWNER))
        { force_update(); }
    }
    on_rez(integer num) { 
        if(old_owner != llGetOwner()) { llResetScript(); }
        force_update();
        llListen(CHAN,"",NULL_KEY,"");
    }
    state_entry()
    {
        old_owner = llGetOwner();
        force_update();
        llListen(CHAN,"",NULL_KEY,"");
    }
	touch_start(integer num)
	{
		Menu();
	}
    listen(integer rCHAN, string name, key id, string msg)
    {
                if(llGetOwnerKey(id) != llGetOwner()) return; 
                if (msg==">>")
                {
                    llListenRemove(dialhandle);
                    llSetTimerEvent(0.0);
                    gMenuPosition += 10;
                    Menu();
                }
                else if (msg=="<<")
                {
                    llListenRemove(dialhandle);
                    llSetTimerEvent(0.0);
                    gMenuPosition -= 10;
                    Menu();
                }
                else if (msg!="CLOSE" && llStringLength(msg)!=0) {
                    frame = llListFindList( Tchoose, [msg] );
                    llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, msg]); 
                    llSetLinkTextureAnim(2, ANIM_ON | SMOOTH, ALL_SIDES, 4, 4, frame, 1.0, 1.0 ); //////////////// HERE SETS THE FRAME ON PRIM
                    llOwnerSay(msg+" applied");
                }
    }
}

 

0.jpg

Edited by Edu Csak
Inserted a link to video of the script in action
Link to comment
Share on other sites

Without more study I'm not sure what's going wrong here, but it appears you're not really animated the texture but just using that function to set one "frame" from the texture, so I'd try llOffsetTexture() to see if it works the way you intended llSetTextureAnim() to work.

Because you actually know the texture's UUID, you could instead use PRIM_TEXTURE in a call to llSetLinkPrimitiveParamsFast() to get the same effect, and you already use that function in one of the places you're offsetting the texture frame.

Just in passing (I don't think it matters), is SMOOTH really relevant to your use of llSetTextureAnim()? You're doing a single cel (frame-based) anim here, unless I'm missing the whole idea.

  • Like 2
Link to comment
Share on other sites

Exactly.  I wouldn't use llSetTextureAnim for an application like this that is not animating anything.  Just use llOffsetTexture and be done with it. The only mild complication is that your texture doesn't have nice, clean boundaries between frames, so I would suggest doing a little cleanup with Photoshop first.

  • Like 1
Link to comment
Share on other sites

Thank you Qie & Rolig,

I ain't no programmer and it's hard to ask wiki when you've got no clue what to search for xD 
Took a look on llOffsetTexture but wiki isn't clear about child prims (yes, the prim is a child one)
So I'd better use llSetLinkPrimitiveParamsFast [ PRIM_TEXTURE, integer face, string texture, vector repeats, vector offsets, float rotation_in_radians ], right? 
Now I've got to understand this cuz have no idea what it means
• float    u    –    horizontal (x) offset in the interval [-1.0, 1.0]    
• float    v    –    vertical (y) offset in the interval [-1.0, 1.0]    
I'll do more researchs (really wish wiki is noobie-wise) ;) 

Thank you Qie & Rolig

Link to comment
Share on other sites

I decided to dredge up an ancient script I used back when Materials were just starting to roll out, and I used llSetTextureAnim() because it correctly offset the normal- and specularmaps -- which you may need to do if you're using those, too, with PRIM_NORMAL and PRIM_SPECULAR in llSetLinkPrimitiveParamsFast() -- and I'll just drop it here in case it's useful:

integer NUMBER_FACE = 0;
integer NUMBER_LINK = LINK_THIS;
string NUMBER_TEXTURE = "f16e2a6b-39b7-a4c9-0904-7b5ef84b56ad";
integer COLUMNS = 4;
integer ROWS = 4;

integer numberShowing;


default
{
    state_entry()
    {
        // Set texture section showing by default
        // This first is optional to get around an old viewer bug that may be obsolete
        llSetLinkPrimitiveParamsFast(NUMBER_LINK,
            [ PRIM_TEXTURE, NUMBER_FACE, NUMBER_TEXTURE
            , <1.0/COLUMNS, 1.0/ROWS, 0.0>    // repeats
            , <(1-COLUMNS)*(0.5/COLUMNS), (ROWS-1)*(0.5/ROWS), 0.0>    // offsets
            , 0.0   // rotation in radians
            ]);
        llSetTextureAnim(FALSE, NUMBER_FACE, COLUMNS, ROWS,
            0.0, 0.0, 0.0);
    }
    on_rez(integer start_param)
    {
        llResetScript();
    }
    touch_start(integer total_number)
    {
        numberShowing = ++numberShowing % (ROWS*COLUMNS);
        llSetTextureAnim(ANIM_ON, NUMBER_FACE, COLUMNS, ROWS,
            (float)numberShowing, 0.0, 0.0);
    }
}

I notice I used 0.0 for the length and rate arguments to llSetTextureAnim, but I don't know if that matters -- I was really just intending to show a sample of PRIM_TEXTURE for choosing a frame in a 4x4 texture.

  • Like 1
Link to comment
Share on other sites

10 hours ago, Edu Csak said:

Now I've got to understand this cuz have no idea what it means
• float    u    –    horizontal (x) offset in the interval [-1.0, 1.0]    
• float    v    –    vertical (y) offset in the interval [-1.0, 1.0]

These are just "offsets" relative to the size of the texture itself, think of it like a percentage.

A texture, by default, is at 0.0 (or 0%) offset for both X(left/right) and Y(down/up) directions.

If you were to set the values to 0.5 (50%) and 0.0, you would see that the texture is shifted halfway to the side, so that the "edge" of the texture is in the center.

1.0 means 100% to the left/down. -1.0 means 100% to the right/up.

You can experiment with this by selecting an object you own while in Edit Mode and going into the Texture tab. There will be settings called "Horizontal offset" and "Vertical offset."

Link to comment
Share on other sites

An advantage of using a single texture with offsets for displays (numerical in this case) is that the entire texture is loaded in the viewer of nearby avatars, and thus a change  (numerical in this case) is fast even for bandwidth constrained clients or on heavily loaded servers. 

Link to comment
Share on other sites

  • 2 months later...

Well, if nothing else, you could add one more test to your listen event:

else if (message == "CLOSE")
{
     // Do stuff that you want to do for cleanup, including ..
     llSetLinkPrimitiveParamsFast(2,[PRIM_TEXTURE,iFace,strTexture,vScale,vOffset, 0.0]);
}

where you supply the important values for the name of the texture, the scale, and the offsets to the specific frame you are interested in.

Link to comment
Share on other sites

On 11/30/2019 at 4:50 PM, Edu Csak said:

 

0.jpg

Sorry, still cant figure it out how it really works. Wiki's descriptions make me feel illiterate, literally LOL

wiki says:

for scale:

• float u horizontal (x) scale in the interval [-100.0, 100.0]  
• float v vertical (y) scale in the interval [-100.0, 100.0]

and for offset:

• float u horizontal (x) offset in the interval [-1.0, 1.0]  
• float v vertical (y) offset in the interval [-1.0, 1.0]

But still have no idea how to show just "lime green 7" or "pink 4" on prim 
Sorry again bothering, but wiki makes no sense bout explaining clearly the mechanism for self-learners non professional scripters ;)
Kudos for you all for the patience

Link to comment
Share on other sites

12 minutes ago, Edu Csak said:

for scale:

• float u horizontal (x) scale in the interval [-100.0, 100.0]  
• float v vertical (y) scale in the interval [-100.0, 100.0]

If you do nothing at all to the scale of your image, the scale factor is <1.0,1.0,1.0>  .  (The Z-component doesn;t matter, because your image is two-dimensional, but a vector has to have a Z)  If you want to make the image larger in its X or Y direction, you make u or v smaller.  So an image that is <0.5, 0.5, 1.0> has twice the area of the original. To make the image smaller, make u or v bigger than 1.0.  If you use a negative number instead of a positive one, you will flip that axis end for end, and will create a reversed image.  Think of u and v as ways of expressing how many times the whole image repeats across the face you are applying it to.

21 minutes ago, Edu Csak said:
• float u horizontal (x) offset in the interval [-1.0, 1.0]  
• float v vertical (y) offset in the interval [-1.0, 1.0]

These offsets express how much to move the entire image left/right or up/down, to center a specific part of the image on a face.  Same deal as with scale.  If you do nothing at all, the offset vector is <0.0,0.0,0.0> or ZERO_VECTOR.  If you want to make the center of the image half a face width to the right, make u = 0.5, and so forth.

You can experiment with the scale and offset values by just putting your image on a prim face and playing with the numbers in the Texture tab of the Edit function in your viewer.  It's duplicating manually what the LSL functions are doing in a script.  If nothing else, you can simply copy those numbers from the editor directly into your script when you need u and v values.

  • Like 1
Link to comment
Share on other sites

Thank you very much @Rolig Loon but I give up. I feel myself very stupid not figuring out a formula to have it done. Playing randomly with offset values is testing my patience to its highest level LOL (I've tried, I swear) ;) 
Tried working round your suggestion using prim_texture under llSetLinkPrimitiveParamsFast but I've only managed to make it work with
llSetLinkTextureAnim(side, ANIM_ON | LOOP, face, gFrameY, gFrameX, 3, 1, 0); (3 = number of image slice I wanna use)
Once again, thank you! But its way more advanced for my expertise 😘 

Link to comment
Share on other sites

OK..... Here's your image applied to the face of a square prim:

16b013bba303d7c30661f306e43f778d.png

Look at the values in the Texture panel from my editor.  Horizonal and vertical scale are both 1.0, so no change in default repeats.  The offsets are zero too, so the image is centered on the face.  Now look at this:

764c9cafcf5d5a49c5593f5de0cb192b.png

There are five repeats horizontally in your image, so setting the horizontal scale factor to 0.2 makes only 1/5 of the whole horizontal range appear on the face.  There are three vertical repeats in your images, so setting the vertical scale to 0.33 makes only 1/3 of the vertical range appear.   Now, I have shifted the vertical offset DOWN by 0.33 so the image is centered on the bottom row in your image.  I left the horizontal offset at zero, so I am looking at the center of that bottom row >>> Frame13. Mess with it yourself.  Then just copy those numbers into your script.  Easy peasy.

BTW, it would look cleaner if your original image had been made a little cleaner, with frames that are all exactly the same size and shape, but this isn;lt bad.

Edited by Rolig Loon
Link to comment
Share on other sites

By the way, if you don't feel up to scripting some sort of "formula" to put the right frame on your prim's face, you don't have to.  As I said in that last post, all you need to do is grab the numbers that you get by playing manually with your editor.  Drop them into a list in your script and then write a bunch of if tests that say, "If you are asked to display Frame 6, use these parameters ...." and so on.  No calculation involved.  Just read the preset offsets from your list.  It's not as elegant and compact as a formula, but it's more foolproof.

  • Like 1
Link to comment
Share on other sites

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