Jump to content

llSetLinkColor(6, <0.0, 1.0, 0.0>, ALL_SIDES) not working


mansoor50
 Share

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

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

Recommended Posts

I am rezzing 60 square tiles of .25m. the code is a bit long so i will simply write steps what i am doing.

the problem is that the color does not change till i 'Touch' the root prim the SECOND time.

 

1. the state entry takes the request to permit change_links

2. on_rez resets the script

3. touch_start calls a function named "create_col'. this fcn rezzes 10 tiles in a column. the function 'create_col is a loop that runs 10 times to llrezatroot. this is working fine

in order to create 6 columns, i call 'create_col' 6 times with different parameters giving me a total of 6 cols of 10 tiles each. all is good till this point.

the last line in the touch_start is the         llSetLinkColor(6, <0.0, 1.0, 0.0>, ALL_SIDES);    

4. run_time_permissions event sets a variable that is used in touch_start whether to rez or not

5. object_rez creates the links of all the tiles to the root prim.

what i notice is that the color does not change when the obj is touched the first time. if i touch it the second time, only then the tile color changes.

can anyone plz explain why this is happening?

thanks!!

Link to comment
Share on other sites

vector relativePosOffset = <.5, 0.0, 0.0>; // "Forward" and a little "above" this prim
vector relativeVel = <1.0, 0.0, 0.0>; // Traveling in this prim's "forward" direction at 1m/s
rotation relativeRot = <0.0,0.707107, 0.0, 0.707107>; //ZERO_ROTATION; // Rotated 90 degrees on the x-axis compared to this prim
integer startParam = 10;
string obj="chip";
vector myPos;
rotation myRot;
vector rezPos;
vector rezVel;
rotation rezRot;
integer mCol;
float vGap;
float hGap;
float mColtmp;
integer i;
integer works;
integer prims;
float size; //this is the size of the prim called 'chip'
create_col(integer mCol, float vGap, float hGap) {
	myPos = llGetPos();
	myRot = llGetRot();
	size=.25;
	rezPos = myPos+relativePosOffset*myRot;
	rezVel = relativeVel*myRot;
	rezRot = relativeRot*myRot;
	i=0;
	while (i<=9) {
		if (mCol==1){
			if (i==0) {
				relativePosOffset = <.5, 0.0, 0.0>;
			}
			else {
				relativePosOffset = <.5, 0.0, (float) i*(size+vGap)>;
			}
			rezPos = myPos+relativePosOffset*myRot;
			llRezAtRoot(obj, rezPos, rezVel, rezRot, startParam);
		}
		if (mCol>=2){
			mColtmp=(float)(mCol-1);
			if (i==0) {
				relativePosOffset = <.5, mColtmp*(size+hGap), 0.0>;
			}
			else {
				relativePosOffset = <.5, mColtmp*(size+hGap), (float) i*(size+vGap)>;
			}
			rezPos = myPos+relativePosOffset*myRot;
			llRezAtRoot(obj, rezPos, rezVel, rezRot, startParam);
		}
		i++;
	}
}
default
{
	state_entry()
	{
		llSay(0, "Hello, Avatar!");
		llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
	}
	on_rez(integer start_param)
	{
		llResetScript();
	}
	touch_start(integer total_number)
	{
		llSay(0,"touch start # of prims"+(string)llGetObjectPrimCount(llGetKey()));
		llSay(0,"works:"+(string) works);
		if (llGetObjectPrimCount(llGetKey())<=1)
		{
			if (works)
			{
				mCol=1;
				vGap=0.03;
				hGap=0.03;
				create_col(mCol, vGap, hGap);
			    mCol=2;
				create_col(mCol, vGap, hGap);
				mCol=3;
				create_col(mCol, vGap, hGap);
				mCol=4;
				create_col(mCol, vGap, hGap);
				mCol=5;
				create_col(mCol, vGap, hGap);
				mCol=6;
				create_col(mCol, vGap, hGap);
			}
				llSetLinkColor(6, <0.0, 1.0, 0.0>, ALL_SIDES);	
	
		}
	}
  	run_time_permissions(integer perm)
    {
        // Only bother rezzing the object if will be able to link it.
		if (perm & PERMISSION_CHANGE_LINKS){
				works = TRUE;
		}
		else {
			works = FALSE;
		}	
    }
    object_rez(key id)
    {
        // NOTE: under some conditions, this could fail to work.
        // This is the parent object.  Create a link to the newly-created child.
		llCreateLink(id, TRUE);
//		llSay(0,"id of rezzed child:"+(string) id);
    }
}

 

Link to comment
Share on other sites

Aside from the color change, I am a little surprised that this script actually links the newly-rezzed times together. Each time the create_col function is triggered, it has to rez a stack of tiles, and yet the object _rez event cannot be executed until the touch_start event is complete.  You cannot jump in and out of an event. So, all of the calls to the object_rez event must be queued and then executed sequentially in order to create all of the various links in your final object. I'm a little surprised that they actually execute in the proper order -- actually surprised that it links them at all.  I'll have to think about this overnight.  If I can understand why this works, then maybe I will have a clue about your original question.

EDIT:  Aha! The answer is that the tiles are not linked together by the time the llSetLinkColor command is executed the first time, so it doesn't work. The tiles are not linked until the large stack of queued object_rez events are finished. Then, if you click the object a second time, all of the create_col function calls are ignored but the llSetLinkColor command can finally be executed.  So, it doesn't answer my question about why the system allows you to link the tiles like this, but it does answer your question about why you need to click it a second time. :)

EDIT YET AGAIN: Actually, I do see why it works. Since your routine rezzes all of the tiles in their proper places, it doesn't really make any difference whether they are linked in the proper order. (Unless the order is important to you.) They will eventually all be linked together to create the whole. It would be interesting to know whether the links are all numbered the same way if you run the script a dozen times in a row.  It would also be interesting to find out how long an event queue you can create before a script like this fails.  As I said, I am surprised that it works at all, but now I'm curious about whether it will still work for, say, 80 or 100 tiles or more.

Edited by Rolig Loon
  • Like 1
Link to comment
Share on other sites

Well, I am also a little perplexed, but Roolig explained very well, why it does not work.

If you use

    changed(integer change)
    {
        if (change & CHANGED_LINK) //note that it's & and not &&... it's bitwise!
        {
            llOwnerSay("The number of links have changed.");
        }
    } 

You clearly will notice, how long it takes before the updates have finished. Now, in the change event you could use a combination of a Boolean bReady and a counter and then execute commands to change color etc. And you will have to get right right link number in order to color the correct one - you just color link number 6 at anytime - one way to solve this, is to name the titles in question "ColorMe#x" when creating them and then in the change event using iterations through the linkset and examine llGetLinkName()

  • Like 1
Link to comment
Share on other sites

3 hours ago, Rolig Loon said:

EDIT YET AGAIN: Actually, I do see why it works. Since your routine rezzes all of the tiles in their proper places, it doesn't really make any difference whether they are linked in the proper order. (Unless the order is important to you.) They will eventually all be linked together to create the whole. It would be interesting to know whether the links are all numbered the same way if you run the script a dozen times in a row.  It would also be interesting to find out how long an event queue you can create before a script like this fails.  As I said, I am surprised that it works at all, but now I'm curious about whether it will still work for, say, 80 or 100 tiles or more.

I was actually rezzing 70. but the number linked were only 64. so that means the max limit is 64?

i read ur reply a few times to try and understand. In effect, you are saying that the llsetlinkcolor command is issued before the event queue is completed.

Therefore, the question then would be how to delay the setlinkcolor  till the queue is completed.

And how can we find out if there is stuff in the queue??

And i really appreciate your detailed reply. THANKS!!

Link to comment
Share on other sites

1 hour ago, Rachel1206 said:

Well, I am also a little perplexed, but Roolig explained very well, why it does not work.

If you use

    changed(integer change)
    {
        if (change & CHANGED_LINK) //note that it's & and not &&... it's bitwise!
        {
            llOwnerSay("The number of links have changed.");
        }
    } 

You clearly will notice, how long it takes before the updates have finished. Now, in the change event you could use a combination of a Boolean bReady and a counter and then execute commands to change color etc. And you will have to get right right link number in order to color the correct one - you just color link number 6 at anytime - one way to solve this, is to name the titles in question "ColorMe#x" when creating them and then in the change event using iterations through the linkset and examine llGetLinkName()

 

aha......i need to read up on the change event and see what it means/does....but thank u for pointing me in the right direction

Link to comment
Share on other sites

Rachel is suggesting the changed event as a way to monitor progress of the linking operations.  It's not causing anything to happen, just watching.

I was half asleep as I was typing things last night, so I may not have been quite as coherent as I should have been.  Let me try to boil it down to basics:

An LSL script cannot jump out of an event and back in again.  Once it starts an event, it stays in it until everything has finished. So, your touch_start event, with all of its included calls to the create_col function, has to finish before anything else happens.  Therefore, all of those tiles will be rezzed long before the object_rez event can fire even one time.  They are scheduled to run, but held in an event queue. When the touch_start event has finally finished, that event queue can finally start to execute, so the object_rez event cascades through it, one link at a time.

My big question last night was about how long the event queue can be -- that is, how many of those potential object_rez events can stack up before the script runs out of room for any more.  It sounds like the answer is 64.  My second question is whether that stack executes in the same order as the tiles were rezzed.  The answer there is that I suspect it doesn't, but Rachel's test can tell you.  Armed with that information, you can use her strategies to be sure that the llSetLinkColor command colors the correct links.

So, how can you handle more than 64 links? You can do it the laborious way, by having the touch_start event rez one tile. Let the object_rez event link it and then rez the next tile from there.  Each successive tile is rezzed in an object_rez event as the last tile was linked.  When the final tile is finished, then you execute the llSetLinkColor command. If you are smart, you take steps to prevent the user from clicking the object again until that entire sequence has finished, so it doesn't get confused.  That's the general plan I would follow. It avoids ever building an event queue, because each tile cannot be rezzed until the previous one has been linked. So it also guarantees that they link in the proper order.  It will take a while, but you have already discovered that.  After all, each rezzing operation stalls the script by 0.2 seconds.  At least this way, it won;t be bumping into itself.

Link to comment
Share on other sites

The event queue length was 64 when I tested it a long time ago. As you confirms it's still 64.

The logical error is:

You execute rez commands in a loop and expect that the on_rez event is executed everytime.

That assuption is wrong. Scripts do NO multitasking. As long as you execute the loop NO other event is triggered.

You start create_col in the touch start event and while it runs no other event is triggered but the events are queued up.
Then the other create_col calls do the same stuff.
When the touch_start event is finished the script is free to run other events and there are max 64 on_rez events in the queue.

You need a completely different logic.

No loops! The 1st rez will trigger the on_rez event and in the on_rez event you will execute the next rez which will trigger the on_rez event again. So you need a global variable and a counter to find an end point here.

Link to comment
Share on other sites

2 hours ago, Nova Convair said:

 

You need a completely different logic.

No loops! The 1st rez will trigger the on_rez event and in the on_rez event you will execute the next rez which will trigger the on_rez event again. So you need a global variable and a counter to find an end point here.

so the first rez occurs in touch start and the remaining in the on_rez event?

Link to comment
Share on other sites

48 minutes ago, mansoor50 said:

so the first rez occurs in touch start and the remaining in the on_rez event?

Yes, exactly as I described in my final paragraph.

 

3 hours ago, Rolig Loon said:

So, how can you handle more than 64 links? You can do it the laborious way, by having the touch_start event rez one tile. Let the object_rez event link it and then rez the next tile from there.  Each successive tile is rezzed in an object_rez event as the last tile was linked.  When the final tile is finished, then you execute the llSetLinkColor command. If you are smart, you take steps to prevent the user from clicking the object again until that entire sequence has finished, so it doesn't get confused.  That's the general plan I would follow. It avoids ever building an event queue, because each tile cannot be rezzed until the previous one has been linked. So it also guarantees that they link in the proper order.  It will take a while, but you have already discovered that.  After all, each rezzing operation stalls the script by 0.2 seconds.  At least this way, it won;t be bumping into itself.

 

Link to comment
Share on other sites

11 hours ago, Rolig Loon said:

Yes, exactly as I described in my final paragraph.

 

 

it worked very nicely. I have rezzed 70 prims, and all got linked too....thank you EVERYONE for their help.  

Rolig ... thanks..:)

My next practice is to find the link numbers so i can play with the individual prims. 

Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

Maybe name each prim as it is linked? Link_1, Link_2, Link_3, Link_4, .....

Hi.

my script which  is rezzing/linking is in the root prim.

so doing the llsetobjectname simply changes the name of the root prim not the child prims.

wd it be correct to assume that the object_rez (key id) gives the KEY of the prim being linked?

if that is true....is there a function that i can refer to a prim using its id/key?

its odd that to get the link number u have to put a script inside the rezzed prim..:(

Link to comment
Share on other sites

I observed that the last linked prim is always #2 and the rest gets new numbers, but I didn't make tests for verification.
You have the uuid of the last rezzed prim (you get it in object_rez) and can compare it with the links in the linkset with llGetLinkKey in a loop.
Start at 2 so it's a hit in the 1st try if it's  at link position 2.

 

Link to comment
Share on other sites

9 minutes ago, Nova Convair said:

I observed that the last linked prim is always #2 and the rest gets new numbers, but I didn't make tests for verification.
You have the uuid of the last rezzed prim (you get it in object_rez) and can compare it with the links in the linkset with llGetLinkKey in a loop.
Start at 2 so it's a hit in the 1st try if it's  at link position 2.

 

thank u!!!!! and i declare myself officially stupid.. this was so obvious...THANKS!!

Link to comment
Share on other sites

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