Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Relative Movement in Linked Set

Geoffrey Steinbeck
Registered User
Join date: 1 Oct 2005
Posts: 29
12-23-2006 12:47
Here's hoping someone can help. I think I've bitten off more than I can chew this time :(

Let's say I have a cylinder as my primary prim, and a bunch of child prims that appear to be attached to the central cylinder. I am trying to write a script that allows the user to adjust the size of the cylinder, on both the x and y planes, and to have the child prims move with the resize - so that they appear to be in the same place, even though the primary prim has changed shape/size.

Referring to the script in my child prims, here's what I am currently doing.
In State_entry, I send a message to the primary prim which then returns it's size to me.
I then use llGetLocalPos() to obtain the offset of the child prim.
I then calculate an "offset multiplier" by dividing the current offset by the primary prim size.

When the primary prim reports a size change to the child prim, I multiply my "offset multiplier" by the new size of the primary prim to establish a new local position for my child prim.

This kinda works. But you don't have to size up/down much before the child prims no longer appear to be attached to the cylinder. Size up a few notches, and the child prims are just floating away from and no longer attached to the cylinder.

Anyone know how I can fix this? Anyone out there actually understand what I'm asking? Would be really greatful for any help. I've been tearing my hair out for .. an embarrassing amount of time over this! And, I just know there's some simple formula that I just don't know that's going to be the answer to all my woes..well, here's hoping!

Yours hopefully!
Geoff.
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
12-23-2006 14:09
I'd approach this problem by creating a custom function that would return the bounding box of a single prim in a link set. once you have that bounding box of the individual prim, you can then use those numbers to calculate where the "edge" of the prim is relative to the other prims so that the 2ndary prims can move to be flush with the main prim.


for basic prims with no cuts/twists this would be as simple as using the prim's center + half the size of each axis to get bounding points. (example, a 1x0.5x2 cube at point <0,0,0> would have a bounding box of <-.5,-.25,-1> for the lower corner and <.5,.25,1> for the upper corner.

For more complex prims, you'd have to write a more robust function that would take into account how far the cut(s)/dimple(s) are (most complex part to calculate), as well as any skews (usually doubles the length along each axis).
_____________________
My SLExchange shop

Typos are forgiven; desecrating the english language with reckless abandon and necrophilic acts is not.


The function is working perfectly fine. It's just not working the way you wanted it to work.
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
12-23-2006 15:51
Are you trying to rescale the entire object at once? Scaling the child prims as well?

The script on this page may help: http://www.lslwiki.com/lslwiki/wakka.php?wakka=llSetScale
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
12-23-2006 16:45
You may be pushing the link distance if the child prims don't intersect the parent prim. Or... you may not be storing the original pos that goes with your original scale. Here's a simple set of scripts that might help:
root prim:
CODE
integer QUERY_ORIG_SCALE = 1123;
integer QUERY_CUR_SCALE = 1124;
integer ORIG_SCALE = 1125;
integer CUR_SCALE = 1126;

vector original_scale;

default
{
state_entry()
{
original_scale = llGetScale();
}

touch_start(integer total_number)
{
llSetScale(original_scale); // reset to start
}

changed(integer change)
{
if (change & CHANGED_SCALE)
{
llMessageLinked(LINK_ALL_OTHERS, CUR_SCALE, (string)llGetScale(), "");
}
}

link_message(integer sender, integer num, string str, key id)
{
if (num == QUERY_ORIG_SCALE)
llMessageLinked(sender, ORIG_SCALE, (string)original_scale, "");

if (num == QUERY_CUR_SCALE)
llMessageLinked(sender, CUR_SCALE, (string)llGetScale(), "");
}
}
child prim:
CODE

integer QUERY_ORIG_SCALE = 1123;
integer QUERY_CUR_SCALE = 1124;
integer ORIG_SCALE = 1125;
integer CUR_SCALE = 1126;

vector original_pos;
vector original_scale;

default
{
state_entry()
{
original_pos = llGetLocalPos();
llMessageLinked(LINK_ROOT, QUERY_ORIG_SCALE, "", "");
}

touch_start(integer total_number)
{
llSetPos(original_pos);
}

link_message(integer sender, integer num, string str, key id)
{
if (num == ORIG_SCALE)
original_scale = (vector)str;

if (num == CUR_SCALE && original_scale != ZERO_VECTOR)
{
vector vnew = original_pos;
vector newscale = (vector)str;

vnew.x = vnew.x * newscale.x / original_scale.x;
vnew.y = vnew.y * newscale.y / original_scale.y;
vnew.z = vnew.z * newscale.z / original_scale.z;

llSetPos(vnew);
}
}
}


I multiply by the new scale and then divide by the original scale to minimize underflow problems with dividing first. It doesn't handle root prim rotations, that's not possible with the changed() event, you'll have to do that with a timer or something.
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
12-23-2006 17:23
From: Boss Spectre
It doesn't handle root prim rotations, that's not possible with the changed() event, you'll have to do that with a timer or something.
Use a llRotTarget with a small error and trigger on not_at_rot_target().
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
12-23-2006 17:51
great idea! Thanks.
Geoffrey Steinbeck
Registered User
Join date: 1 Oct 2005
Posts: 29
12-24-2006 06:34
Thanks to you all for your responses.

Seifert - I can't believe I didn't see that example script in the Wiki. That's got me as close to what I wanted as I have been so far. The problem is when I distort the scaling, for example, when I just want to make the parent prim (cylinder) wider.

I modified the scripts in the Wiki so that they would only rescale/position on the "y" axis, and sure enough, the parts start to pop-out away from the cylinder.

What I need to figure out, is a way to compensate for the distortion, so that all child prims still stay (at least roughly) in position, regardless of how the scaling of the cylinder is distorted between x and y. This is where the math is simply beyond me :(

Geoff.
Boss Spectre
Registered User
Join date: 5 Sep 2005
Posts: 229
12-24-2006 08:34
Did you try the example I posted above? It seems to me that does what you describe, the child prims are moved in relation to the relative scale of the root prim. Stretch it in y, the prims just move on y, etc. You can remove the line "vnew.z = vnew.z * newscale.z / original_scale.z;" if you don't want it to move on Z. The distance of child prims does not "accumulate" with each change, if you click the root prim it returns to its original size, and the child prims go back where they were.

Do you want the child prims to scale themselves as well?
Geoffrey Steinbeck
Registered User
Join date: 1 Oct 2005
Posts: 29
12-24-2006 10:54
Yes Boss ;)

Maybe I could show you in world what is happening .. Might be easier to understand if you see it. I'll drop you an IM later and see if you are on.

Once again, I really appreciate the help :)

Geoff.
Geoffrey Steinbeck
Registered User
Join date: 1 Oct 2005
Posts: 29
12-24-2006 11:22
Actually Boss, having looked at this again, I think it will do what I need it to do. My testing was over-extreme .. For the actual practicle appliance of what I'm trying to do, the changes in size are a lot smaller, and the child prims do remain near enough to where they should be.

I will want to have the child prims scale themselves as well, although I *think* I can figure that bit out ;)

Once again, many thanks for everyone's help. I'm a quiet guy and rarely resort to posting to forums to resolve a problem. It's truely fantastic to get such a great response!

Thank you all and have a super Christmas!!!!

Geoff.