Jump to content
EnCore Mayne

String to Vector

Recommended Posts

i've got a dialog box accepting a user's vector notation input from a listen event. ie. user inputs: <5,0,0>. it's a string obviously so i'm casting that into a vector to put their input into another function's parameter further down the script. it doesn't seem to work. any reason?

listen(integer channel, string name, key id, string message)
    {
		llListenRemove(gListener);
        vector userinput = (vector)message;
		llOwnerSay( (string)userinput );//always results in 0.0000000
    }

 

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

Best test to see if message still contains the value that you want it to have.

Here's my test converting a string to a vector:

default
{
    state_entry()
    {
        string VEC = "<1,2,3>";
        vector V = (vector) VEC;
        llOwnerSay("Vector = "+(string)V);
    }
}

I consistently get:

    Object: Vector = <1.00000, 2.00000, 3.00000>

Or, when I use the value you used in your example, I get:

    Object: Vector = <5.00000, 0.00000, 0.00000>

So obviously, you can typecast from string to vector. The problem must be in your code. Most likely in the part that you don't show us (I can't blame you, I am usually reluctant to show others my code too) 

Edited by Fritigern Gothly

Share this post


Link to post
Share on other sites

There's something very odd here: an invalid string cast as a vector will result in ZERO_VECTOR, which outputs as <0.00000, 0.00000, 0.00000>. 0.000000 is what you get when you cast a zero float to a string.

  • Like 1

Share this post


Link to post
Share on other sites

Molly's got the best thought.  There are loads of ways to mis-type information into a text box or into local chat.  If it's coming in through a text box, llStringTrim will get rid of any bogus line return character that shows up if the user has hit ENTER before clicking the box's Submit button. 

It's a bit laborious, but it's a good idea to anticipate all those possible typos. In addition to using llStringTrim, you might consider adding a function to verify whether the input really IS a vector (like the one in the wiki at http://wiki.secondlife.com/wiki/Category:LSL_Vector#Example ).  

  • Like 1

Share this post


Link to post
Share on other sites

KT is on the right track -- whatever it's hearing, it's not a vector.

Try llOwnerSay(message) as well as llOwnerSay((string)V), and see what the message actually is.

Share this post


Link to post
Share on other sites

If there's a way to end up with a float value (0.0000) after explicitly casting a string to vector, it eludes me, so I suspect the report is... incomplete.

Playing around with this, it's interesting how much garbage a string-to-vector cast will accept after vector-like text, and yet basically none before.

Share this post


Link to post
Share on other sites
1 hour ago, Qie Niangao said:

If there's a way to end up with a float value (0.0000) after explicitly casting a string to vector, it eludes me, so I suspect the report is... incomplete.

Playing around with this, it's interesting how much garbage a string-to-vector cast will accept after vector-like text, and yet basically none before.

Vectors can be split into their individual floats by appending the axis to the variable name. 
For example:

vector var = <1.0, 2.0, 3.0>;
llOwnerSay("X = " + (string)var.x + ", Y = " + (string)var.y + ", Z = " + (string)var.z);

This works for quaternions too, which would use axes x, y, and z, plus an additional axis s

rotation var = <1.0, 2.0, 3.0, 4.0>;
llOwnerSay("X = " + (string)var.x + ", Y = " + (string)var.y + ", Z = " + (string)var.z+ ", S = " + (string)var.s);

Is that what you meant, Qie?

Share this post


Link to post
Share on other sites

okay, yes, the reported result 0.0000000 was in error. i posted after a mammothly frustrating attack on this project and walked away. still, as reported, the inputted vector text isn't making it to where i need it.

i've retested afresh with llOwnerSay in the listen event and the vector seems to be correct. i don't know what i did to get that right. i've been fiddling with a bunch of variables. but the result of when <10,0,0> gets cast from within the listen event
[CODE: vector userinput = (vector)message; ] is:

CHAT:
userinput is: <10.00000, 0.00000, 0.00000>
message is: <10,0,0>

BUT, when i need the vector to be passed into a run_time_permissions event on sitting i get all zeros <0.00000, 0.00000, 0.00000>.

i've obviously considered something wrong. i'm no expert, hence my quest into the forum of such.

the structure of the code, yes i'm kinda hesitant to reveal the full idea, mostly to prevent the embarrassment it might cause me, is:

state_entry()
changed():avatar sits, sends permissions request
touch_start():brings up text dialog for vector input
listen():where i test for what was input
run_time_permissions():rez object at input vector offset, animate avatar

that may be giving away more than what i wanted so you'll all have to kneel and swear a secret oath. there's still more functions to be added and i'm sure i'll be asking for more advise as it breaks and folds before my eyes. much obliged for your attention and helps.

Share this post


Link to post
Share on other sites
Posted (edited)
2 hours ago, Qie Niangao said:

Playing around with this, it's interesting how much garbage a string-to-vector cast will accept after vector-like text, and yet basically none before.

yes is one of the peculiarities of implementation

LSL will trim leading whitespace on integer and float casts before the 1st character, but not on vectors and rotations. "<" works  " <" does not

when casting string to float or integer then LSL stops at the first trailing non-valid character which includes whitespace

so for example a vector string with a leading space like  "<2, 1,0>" before the "1" will cast correctly. Whereas a string with a trailing space after the "1" like "<2,1 ,0>" will not 

Edited by Mollymews
r

Share this post


Link to post
Share on other sites

EnCore, a suggestion

whenever I ask a user to input a vector either in a text box or on a channel commandline then I have then type the 3 values with space to seperate the values. Like

/1 5 0 0

/99  1.5 2.6 3.0

is a lot less complicated and faster for users rather than having them type: /1 <1.5,2.6,3.0>

then parse the 3 values into a list using whitespace as the delimiter. So if they type more than one space anywhere then it will be ok. Should be list length == 3

once in 3-element list then convert this list to vector

  • Like 2

Share this post


Link to post
Share on other sites

Are you declaring a new local version of the vector in the listen event (vector userinput = (vector)message;) that overrides a global version that's used the run_time_permissions event?

  • Like 2

Share this post


Link to post
Share on other sites

Looking forward, you may find this function from the LSL wiki useful for checking than an input string is actually a valid vector: http://wiki.secondlife.com/wiki/Vector#Useful_Snippets.

integer IsVector(string s)
{
    list split = llParseString2List(s, [" "], ["<", ">", ","]);
    if(llGetListLength(split) != 7)//we must check the list length, or the next test won't work properly.
        return FALSE;
    return !((string)((vector)s) == (string)((vector)((string)llListInsertList(split, ["-"], 5))));
    //it works by trying to flip the sign on the Z element of the vector,
    //if it works or breaks the vector then the values won't match.
    //if the vector was already broken then the sign flip will have no affect and the values will match
    //we cast back to string so we can catch negative zero which allows for support of ZERO_VECTOR
}//Strife Onizuka

This will let you distinguish between a zero vector that's been input deliberately and one that's the result of of the failed typecasting of an invalid string.

Share this post


Link to post
Share on other sites

I never expect that people can enter a vector.

    listen(integer chan, string name, key id, string msg) {
        list vec1 = llParseString2List(msg,["<",">"," ",",","/"],[]);
        llOwnerSay(msg);
        llOwnerSay(llDumpList2String(vec1,"|"));
        vector vec2;
        vec2.x = (float)llList2String(vec1,0);
        vec2.y = (float)llList2String(vec1,1);
        vec2.z = (float)llList2String(vec1,2);
        llOwnerSay((string)vec2);
    }

With that you can enter a vector, with or without <> with or without spaces at the wrong places or just 3 numbers separated by space, comma or slash

  • Like 3

Share this post


Link to post
Share on other sites
13 hours ago, EnCore Mayne said:

state_entry()
changed():avatar sits, sends permissions request
touch_start():brings up text dialog for vector input
listen():where i test for what was input
run_time_permissions():rez object at input vector offset, animate avatar

that may be giving away more than what i wanted

Don't worry, what you described could still be literally anything, so your idea is still safe with you.

But if you can't get any help through this thread, you could send me a private message through the forum with the code. I won't share or judge. 

Share this post


Link to post
Share on other sites
On 7/3/2020 at 8:04 PM, KT Kingsley said:

Are you declaring a new local version of the vector in the listen event (vector userinput = (vector)message;) that overrides a global version that's used the run_time_permissions event?

no. i have it as a global vector without any parameter. ie. vector userinput;

further to the problem solving i'm doing, i just tested the userinput at the changed() event (when the avatar sits) and the userinput from the llTextBox() dialog input doesn't make it there or to the run_time_permissions() event. hmmmm....

Share this post


Link to post
Share on other sites
Posted (edited)
15 hours ago, EnCore Mayne said:

no. i have it as a global vector without any parameter. ie. vector userinput;

further to the problem solving i'm doing, i just tested the userinput at the changed() event (when the avatar sits) and the userinput from the llTextBox() dialog input doesn't make it there or to the run_time_permissions() event. hmmmm....

Are you 100% sure you don't have a global and local variable with the same name?

string input = "Not much, how about you?";

default
{
    state_entry()
    {
        string input = "What's updog?";
        llOwnerSay(input);
    }

    touch_start(integer n)
    {
        llOwnerSay(input);
    }
}

The local variable in state_entry will "hide" the global variable. If you try the above script inworld, it says different things in state_entry vs touch_start.

Edit: Wow I'm tired. You literally answered this question... My bad. Still, that's basically the only thing that could be happening. If you successfully save the input to a global variable, it WILL be available in the next event, unless you override it again before using/outputting it.

Edit2: I've seen the script now, it was exactly what @KT Kingsley and I were guessing.

Edited by Wulfie Reanimator
  • Thanks 1

Share this post


Link to post
Share on other sites
14 hours ago, EnCore Mayne said:

i just tested the userinput at the changed() event (when the avatar sits) and the userinput from the () dialog input doesn't make it there or to the run_time_permissions() event.

That doesn't sound like you are aware how the event handlers are used.

That's a standard textbox call:

handle = llListen(textboxchan, "", avataruuid, "");
llSetTimerEvent(30);
llTextBox(avataruuid, "enter something", textboxchan);

You can put that wherever you want - it depends on how you want to trigger the textbox. changed or run_time_permissions or touch is fine for that.

However the answer you receive always in the listen event. There you close the listen and stop the timer and proceed with processing the answer.

And you need a timer event in case the user just closes the textbox without entering something. The script will wait forever then (and never close the listen). So after 30 sec. you close the listen and stop the timer.

 

 

Share this post


Link to post
Share on other sites
2 hours ago, Nova Convair said:

That doesn't sound like you are aware how the event handlers are used.

that's just the beginning of my ignorance, Nova. my level of comprehension for all things scripting, aside from the gems i always receive in this forum, is matched by the level of readability of the wiki. sometimes i think the mystical art of scripting is being overtly obscured by the priestly class who document its features so we common folk bow to their wisdom and power. i do thank you for applying some much needed scripting logic to my obviously low level abilities. humbly yours....

Share this post


Link to post
Share on other sites
1 hour ago, EnCore Mayne said:

sometimes i think the mystical art of scripting is being overtly obscured by the priestly class who document its features so we common folk bow to their wisdom and power.

Yes, the wiki is not helpful to learn how to script. It's a reference from scripters to scripters. And they have their own language.
The wiki is very helpful once you master scripting - until then it sometimes gives more questions than answers. And the examples never describe the special case you are looking for. 🤓

  • Like 1

Share this post


Link to post
Share on other sites
18 minutes ago, Nova Convair said:

Yes, the wiki is not helpful to learn how to script. It's a reference from scripters to scripters. And they have their own language.
The wiki is very helpful once you master scripting - until then it sometimes gives more questions than answers. And the examples never describe the special case you are looking for. 🤓

In its mild defense, however, I should point out that the wiki is not intended as a teaching tool.  It's a technical manual, written in language that is intended for reasonably experienced scripters. That makes it a bit intimidating for beginners, but quite useful for its intended audience.  The layout of each entry is standardized, so it should be clear what sorts of arguments each function takes and what sort of output you should expect from it.  Notes describe the function's limitations and highlight particular situations in which it may yield unexpected results.  The examples are not meant to be exhaustive, but to illustrate very simple applications.  

There's no way that I can hold all the details about every LSL function in my head.  As I script, I keep the wiki open so that I can double check the order and type of arguments a function expects, and so I have a quick reference when I am debugging.  I have my own folders full of script examples and snippets that have worked for me in the past or that I have copied from this forum or from fellow scripters. Some of those have found their way into the wiki, but most are bits of code that only make sense because I know the context in which I developed them. I suspect that most scripters make their own collections like mine.

All of this begs the question of where a new LSL scripter can turn as she tries to figure out the language.  The wiki is a good tool, but only if you already understand the basic state/event structure of LSL and have developed a feel for how execution flows in a script.  The wiki does include a handful of tutorials and a spotty collection of examples, but even those assume that the beginner is familiar with core concepts like variables, values, data types, and -- above all else -- logic. 

No matter what coding language you use, the heart of scripting is logic. The details of syntax, punctuation, and all of the confusing brackets are important, but they are like spelling in any human language.  Logic is not in the wiki, except by example. The only way I know to learn is to start with a very simple script like "Hello, avatar!" and play with it, making small additions and subtractions to see what happens.  If you get too ambitious and take on a challenge that you're not ready for, back up and take more baby steps. Take a Builders Brewery course, or find a scripting friend who is willing to look over your shoulder until you're ready to take the training wheels off. Don't expect to learn the hard stuff in LSL from the wiki, any more than you can expect to learn another language -- like French or Thai -- by reading a dictionary.

  • Like 2

Share this post


Link to post
Share on other sites

The other major benefit to the wiki is it shows small and concise examples. The biggest problem I see new scripters encountering is a large script that they are struggling to understand or debug, and few of them know how to take a small area from a script and build it into a test harness to investigate it easily. The wiki snippets are a perfect example of how to investigate a function in a manageable chunk.

 

  • Like 1

Share this post


Link to post
Share on other sites

situation solved:

as Wulfie observed from reading the full code, i DID have a local / global conflict. all fixed. now i'll see if i can mess it up with checking/verifying input. much thanks to everyone.

  • Like 2

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...