Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

llSetLinkPrimitiveParams question

Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
06-19-2008 12:34
Can anyone advise me on this function? I want to be able to toggle some properties of most (but not all) child prims in a linkset. One way to do it would be to use llMessageLinked to send them messages, but it feels as if there should be a way to do it without putting separate scripts in 30-odd prims. However, none of the relevant constants fit the bill.

Ideally, I'd like to name all the prims I want to affect "Target" and tell llSetLinkPrimitiveParams to change the parameters of all prims in the linkset thus named.. can I do that, and, if so, how? Or is there another way?
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
06-19-2008 12:42
We have a: llSetLinkPrimitiveParams(integer linknumber, list rules) function that may be what you are looking for.
See: http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSetLinkPrimitiveParams
_____________________
From Studio Dora
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
06-19-2008 12:48
In order to change the params of a linked prim using llSetLinkPrimitiveParams() you need to provide the linknumber of the prim you want to change. So naming the child-prim differently won't do it.

If you want to use the name of the prim, llLinkedMessage is the way to go...

This is the way I do it...
(not tested, might need some syntax-checking)

CODE


// Receiver prim

// Receiver prim

string gPrimName;

default{
state_entry(){
gPrimName = llGetObjectName();
}

link_message(integer sender, integer num, string str, key id){

// split the string sent into two pieces

list temp = llParseString2List(string, ["^"], []);

string prim = llList2String(temp, 0); // Name of the target prim
string cmd = llList2String(temp, 1); // Command, you want to issue

if(prim == gPrimName || prim == "ALL"){
if(cmd == "SET_COLOR"){
// do stuff here
}
}
}
}

**************************

// Sender-Prim

default{

touch_start(integer num){
llMessageLinked(LINK_SET, 0, "TARGET_PRIM1^SET_COLOR", NULL_KEY);
}
}



So you name the receiver prim «TARGET_PRIM1» and then send it a string like «TARGET_PRIM1^MY_COMMAND» where «MY_COMMAND» is anything you want to scan for in the receiving prim.

Hope you get the idea... :)
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
06-19-2008 13:56
Thanks, Haruki..that's working fine for me. I just wondered if there was a more economical solution than having 30-odd identical scripts in individual prims, but I guess not unless I redesign the build so I can send the one llSetLinkPrimitiveParams message to LINK_ALL_OTHERS or LINK_ALL_CHILDREN.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-19-2008 14:13
Certainly you can do that. Do something like this:

CODE

string TARGET_PRIM_NAME = "Target";
changeAllTargetPrims(list primParams)
{
integer i;
for (i = llGetNumberOfPrims(); i > 0; ++i) // <- Bad! (Near-)Infinite loop. Fixed below.
{
if (llGetLinkName(i) == TARGET_PRIM_NAME)
{
llSetLinkPrimitiveParams(i, primParams);
}
}
}


And of course if you want to change each target prim differently you can do that too. You have the link number, name, and description of the prim to work with in deciding what action to take.
Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434
06-19-2008 15:24
Damn Hewee...

Once again it is time to put that print out onto my bookshelf...

Thanks!
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
06-19-2008 15:55
Thank you both.. that is so helpful.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-19-2008 16:03
OOPS! Small issue. I incremented 'i' instead of decrementing. Fixed version here:

CODE

string TARGET_PRIM_NAME = "Target";
changeAllTargetPrims(list primParams)
{
integer i;
for (i = llGetNumberOfPrims(); i > 0; --i)
{
if (llGetLinkName(i) == TARGET_PRIM_NAME)
{
llSetLinkPrimitiveParams(i, primParams);
}
}
}
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
06-20-2008 00:22
A further question, if I may; what happens if I use llGetLocalPos() inside llSetLinkPrimitiveParams()? Does it return the position, relative to the root prim, of the linked prim I want to affect or the prim that is sending the message? I want, you see, to move the link prims around and would like to use llGetLocalPos() to calculate my start positions.
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
06-20-2008 01:44
I think llGetLocalPos() should do exactly what you want (set positions relative to the root). The one to be wary of is llGetLocalRot() because llSet[Link]PrimitiveParams() doesn't handle this so well.

You may need to do something like this: llSetLinkPrimitiveParams(i, [PRIM_ROTATION] + [llGetLocalPos() / llGetRootRotation()])
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-20-2008 01:48
You can't use llGetLocalPos() "inside" llSetLinkPrimitiveParams(). You'd be using it inside your function or event handler, and the RESULT could be used as some kind of parameter to llSetLinkPrimitiveParams(), but using one function in an expression that happens to contribute to the parameter list of another function you are calling does not change anything about its results.

Calling llGetLocalPos() from your script would return the results for the prim the script is in. If you want to get the position of a child prim, you might try llGetObjectDetails() with that prim's key instead (I'm not sure if that would return local or global values; you'll have to test and convert if necessary). That, or simply remember the locations inside your script since you are controlling their positions from there anyway, right?
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
06-20-2008 08:19
When I do this, I generally don't test for equality, but for a substring match. That is, if the target prim name contains some string, then do the action. This allows you to create more complex actions more simply.
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
06-20-2008 09:03
From: Innula Zenovka
... 30-odd identical scripts in individual prims...
I know only "most" of the linked prims will be updating each pass--more than 15, but less than 30, I guess. But llSetLinkPrimitiveParams delays the script 0.2 sec per call, so worst case, to do 30-odd linked prims in a loop would take 6-odd seconds. If that's cool, great; if it has to be faster, there's the ugly choice of still scripting all those prims so they llSetPrimitiveParams locally and in parallel, or stuffing a bunch of slave llSetLinkPrimitiveParams scripts in the one scripted prim and task them, round-robin.
_____________________
Archived for Your Protection
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
06-20-2008 09:58
From: Hewee Zetkin
r simply remember the locations inside your script since you are controlling their positions from there anyway, right?


Not sure I understand.. I want to move all the prims the same distance and rotation; essentially, when I press a button, a door opens and a bunch of prims slide out and resize themselves. at the moment, I'm doing this by putting this script in each of the prims that slide out, and it does what I want:

vector MyPos;
rotation Rot;
integer toggle;
default
{
on_rez(integer start_params)
{
llResetScript();
}
state_entry()
{
MyPos = llGetLocalPos();
Rot = llGetLocalRot();
}

link_message(integer sender_num, integer toggle, string str, key id)
{
if (toggle < 0)//wait for door to open,go to new position,give everything time to arrive, grow
{
llSleep(0.3);
llSetPos(MyPos + <0.00000, -2.40642, 2.95822> );
llSetLocalRot(Rot);
llSleep(0.2);
llSetPrimitiveParams([PRIM_SIZE, <3.0, 3.0, 0.198352>]);

}
if (toggle > 0)//shrink, wait, go to closed position
{
llSetPrimitiveParams([PRIM_SIZE, <0.393463, 2.597336, 0.198352>]);
llSleep(0.5);
llSetPos(MyPos);
llSetLocalRot(Rot);
}
}


}

I'd like to make that happen using llSetLinkPrimitiveParams if I can. As it happens, the delay of which Qie warns would be a reasonably cool effect, I think, but thanks for pointing that out -- it might be too long.