Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Stuck with a text fading script.

Hawkaron Deemster
Registered User
Join date: 11 Aug 2006
Posts: 3
08-16-2006 11:55
Because I am new to the scripting language used in SL, I wanted to start out making something simple. I decided to make a text color flashing from black to white, but I just can't make it repeat the flashing. It just starts fading from black to white, then it's all over.

To make this, I used the llSetTimerEvent function so that it executes a script that changes the color of the text by every 0.2 seconds. The code below is the one I have in the timer() state.

timer() {
if (textColor != <1,1,1>;) {
llSetText("Flash", textColor += <0.1, 0.1, 0.1>, 1.0);
}
else if (textColor != <0,0,0>;) {
llSetText("Flash", textColor -= <0.1,0.1,0.1>, 1.0);
}
}

I've defined the global variable textColor as a vector, and the value is <0,0,0>. What have I done wrong here?

Help would be appreciated, thanks in advanced.
Thili Playfair
Registered User
Join date: 18 Aug 2004
Posts: 2,417
08-16-2006 11:59
copy paste brackets hate me

CODE

default {
state_entry() {
llSetTimerEvent(5);
}
}
timer() {
llSetText("hello", <1,1,1>, 1);
state k;
}
}
state k
{
timer()
{
{
llSetText("hello", <0,0,0>, 1);
state default; // change to default.
}
}
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-16-2006 12:00
Comparisons to literal floating point values are often not a great idea (at least if the value was not explicitly set to the exact same literal you are checking for). You might instead test whether one of the components or the total length of the vector ('llVecMag()') is under a certain threshold (like 0.15 for example...).
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-16-2006 12:02
Oh. Another way if the text doesn't change would be to create a texture with frames that have varying transparencies (alpha values) and use 'llSetTextureAnim()' (see http://secondlife.com/badgeo/wakka.php?wakka=llSetTextureAnim). This would be smoother and relieve you of most of the logic design (try PING_PONG flag...).
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
08-16-2006 12:25
The advice to never directly compare a vector is a good one. Aside from that, your logic seems slightly wrong. I assume you're trying to fade from black through white and then back again? Here's what's happening with your script:

* You start out with the color set to 0
* In the timer, the color vector != white. So the first if() block executes, and moves the color up by 0.1
* Eventually, let's say you get to white. Now the if() check fails, because the color is white. So you drop into the else case, and that sets the color down by .1. So now the color is .9, .9, .9.

* The next time the timer runs, it runs the if check. Guess what, the color isn't white, because you decremented it the last time. So it goes back to the if() case, and moves it back up to white.

Try changing the increment/decrement to .5 or .25 instead of .1, and you should see what I'm saying. It'll go from black to grey to white, and then keep flipping between grey and white because it'll decrement it, and then increment it again without decrementing it all teh way down to black. Or put in llOwnerSays in the if and else blocks, saying something like "incrementing color, new color = XXX" and "decrementing color, new color = XXX", that way you'll be able to track what the script is doing.

I think you need to change the checking logic... once you've reached white, you want to keep decrementing until you reach black, but if your check is "is color != white", then all you'll get is one decrement before you get back to incrementing, so that check needs to be different. Maybe something like...

CODE

default
{
int incrementing = TRUE; // Since we start with black

state_entry()
{
// Whatever
}

timer()
{
if (incrementing)
{
// Increment color by 0.1
if (llVecMag(color - <1,1,1>) < 0.15)
{
// We are close enough to white... flip the flag so we start decrementing
incrementing = FALSE;
}
}
else
{
// Decrement color by 0.1
if (llVecMag(color - <0,0,0>) < 0.15)
{
// We are close enough to black... flip the flag so we start incrementing
incrementing = TRUE;
}
}
}


... Something like that might work better.
Hawkaron Deemster
Registered User
Join date: 11 Aug 2006
Posts: 3
08-16-2006 12:44
Thank you, Ziggy Pugg. Finally someone who came with a real solution. Now the problem is that I don't understand the function llVecMag(). What does it actually do and why do you subtract <1,1,1> from the color? Sorry, I started scripting yesterday and I only know few of the function.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
08-16-2006 13:23
You've seen the Wiki by now, hopefully, if not, go take a look at it. It'll tell you what every LSL function does. llVecMag gives you the magnitude of a vector.

Here's the problem - computers don't do floating point math very well, because they have limited precision. So if you did something like:

CODE
(1.0 / 3.0) * 3.0


... You'd expect to get 1.0 again, but you might end up with 0.9999999 (or some number of 9s). The computer doesn't understand 1/3rd, so 1.0 / 3.0 is 0.3333 (some number of 3s), and that multipled by 3.0 gives you something that's almost 1.0, but not exactly 1.0.

So, comparing floats is always a problem. Depending on what math you did to get there, your final value may not be exactly what you want it to be. So if you expect a variable to be 1.0, it could be 0.99999 or 1.00001 or anything in between. But that's basically 1.0, as far as you're concerned, within an error margin, right. So the way to compare floats is to say "If these two numbers are close enough, then I'll accept that they're equal", instead of "Is this number equal to that number". So:

CODE
if (f == 1.0)


Becomes:

CODE
if (llFabs(f - 1.0) < 0.001)


llFabs (I think that's the name of the function) gets you the absolute value of a floating point number. Basically, you don't know if f > 1.0 or f < 1.0, so using llFabs gets rid of the sign issue, and all you're left with is the real difference between f and 1.0, regardless of which is greater. And then you compare that against whatever your tolerance of error is. In this case, I decided that if they were within 0.001 of each other, I'd call it good.

With me so far? :) OK, so now you're dealing with vectors, which are basically 3 floats. llVecMag is the equivalent of llFabs. So llVecMag(color - <1,1,1>;) tells you "how far away" the color vector is from the <1,1,1> vector. The rest of it should be clear if it's made sense so far :)
Hawkaron Deemster
Registered User
Join date: 11 Aug 2006
Posts: 3
08-16-2006 13:34
Thank you for the really long and detailed explanation, Ziggy Puff. That explanation actually made me understand what that function does, because there were no detailed information about it in the wiki.