Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Canceling root prim rotation for child prim moves?

Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
07-30-2009 19:57
What is the best method for canceling root prim rotation for child prim moves?

Say you have a handful of prims, and a script in some of the child prims that moves those child prims in relation to the root of that linkset. For example, a sliding door in a door frame.

I get the script working well when the door is linked to the frame. I even get it working well when the frame is, in turn, linked to another prim, IF the new root prim is at the same rotation as the frame. I can compensate in the llSetPos commands to eliminate the X,Y,Z offset of the root from the frame.

But even though I am doing no rotation-based moves, if the new root prim is rotated, the movement of the door is clearly affected by that root prim's different rotation value.

SO... How do I cancel out the effect of the root prim's rotation on my linkset child prim moves? I suspect it is along the line of using llGetRootRotation, and then taking my llSetPos commands and multiplying or dividing the vectors for the X,Y,Z movement by the root prim's rotation quarternon value? But my eyes were crossing when I tried reading that section of the LSL Wiki on Rotation.

Not looking for a full script here. Just for understanding about how to cancel the effects of a root prim's rotation.
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
07-30-2009 20:44
This one has happened to all of us, the trouble is that you are hoping to understand something that doesn't actually make sense =)

When the child prim rotation stuff was written, someone made a typo/thinko that wasn't caught until too late to fix it nicely. There is a * in the sim code where there should have been a / … So, we have to add an extra / to the rotation to compensate.

Keep this JIRA under your pillow, it shows how to work around the bug.

https://jira.secondlife.com/browse/SVC-93
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
07-30-2009 22:24
Just one more addition, if there isn't any rotation to keep in sync too, the movement will work like:

llSetLinkPrimitiveParams(child, [PRIM_POSITION, (region_coordinates - llGetPos()) / llGetRot()]);

or in the child:

llSetPos(region_coordinates - llGetRootPosition() / llGetRootRotation());
Tali Rosca
Plywood Whisperer
Join date: 6 Feb 2007
Posts: 767
07-31-2009 08:08
That one is a huge factor in leading people to think that they simply do not understand rotations.
If they actually understand them and do the math correctly, it doesn't work!
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
07-31-2009 09:43
*sighs* Thank you. Unfortunately that JIRA and the LSL Wiki articles on Rotation where what was making my eyes cross. The sheer illogic of how it works, and the strange work-arounds, makes no sense.

And in the case of my door, I am not even TRYING to apply a rotation! I just want the door to move on its own local X-Axis when I command it to do so, regardless of weather the frame is linked to an oddly rotated root prim, or not.

If the root prim and the door frame share the same rotation values, it works. Rotate the root prim 30 degrees on Z, and my x-axis movement for the door prim gets rotated 30 degrees off the intended axis, pushing the door out the front of the frame.

Somewhere in all this, there has to be a way to say "Here is the rotation of my door prim, and here is the rotation of my root prim. If they are different, do NOT change the vectors of local prim movement by rotating my axis to match the root before applying the movement!".

There has to be a rational way to "subtract" the effect of the root prim's rotation difference from a llSetPos action.

So, from Viktoria's second post...

llSetPos(region_coordinates - llGetRootPosition() / llGetRootRotation());

I would use this, replacing "region_coordinates" with my intended local movement vector?
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
07-31-2009 16:00
if you're moving the child in relation to it's own axis you don't need to cancel the roots rotation. use llGetLocal* in the child prim and apply that to your offset.

eg (in the child )
llSetPos( llGetLocalPos() + offset * llGetLocalRot() );

were offset = the child local direction and distance to move (say 1m +x ie < 1, 0, 0 >;)
llSetPos will work in local mode when used in a child prim.

the only time you'd need to cancel the roots rotation, is when you are doing the calculation from a different prim than the one being moved (in which case you need to know the childs rot and the roots rot anyway, so it's often easier to just do it from the child that's moving...)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
07-31-2009 16:53
The problem that I am trying to crack is that the doors need to adjust for any changes to the dimensions of the frame. Not just scaling the whole linkset from the corner, but doing an edit linked parts to make the frame taller, or wider, or even deeper; and the doors re-scale and move to the correct positions in the adjusted frame. So I do need to reference the position of a child prim (the frame) from another child prim (each door) and base the movement of the door on the position of the frame. The code I have worked out so far works fine if the frame is the root. If the frame is not the root, it detects this and it works fine if the root is another prim that has the same rotation values as the frame, regardless of where in linking distance the root is. But rotate the root, and its rotation screws up the calculations...

In trying to figure it out at first, I made a simplified version of the script, which simply moved the door prim to the same coordinates as the frame, figuring it would be trivial from there to offset the prim left or right on its own axis. I was wrong. In practice, the offset uses the root prim's rotation for the movement vector, even though I am issuing NO commands that include a rotation component!

I suppose I could first move it to the center of the frame, and THEN do the command you suggest:

llSetPos( llGetLocalPos() + offset * llGetLocalRot() );

But I don't really understand why the * llGetLocalRot() is even necessary. That is, most likely, the crux of my failure to understand this. I am not asking to rotate the prim at all, so why do I need that * llGetLocalRot() in the command?

*Heads in-world to experiment some more with adding apparently arbitrary rotation cancelers to the code...*
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
08-01-2009 06:15
Ugh... I tried again last night, for several hours... It was like watching a drunken square dance. The doors kept going ANYWHERE but where I wanted them to. The closest I got, was one variation where when linked to a turned root prim, it looked like the doors got to the right position when open, but required a two-step process to get there - first moving the prim for the door to the same coordinates as the frame, and then moving the prim for the door to the open position; But the closed position was still off on a strange angle, while allowing the doors to auto-close put them in the correct position???

I'm going to start all over again with some very simple practice pieces - no frame scaling, constants for values that will later be variables, no auto-close... and see if I can make any sense of this mess at all.

If anyone sees me babbling incoherently in the corner of a sandbox, you'll know why...
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
08-01-2009 16:01
mkay I think I see the issue, and a novel way to solve it... mostly.

we'll take the case of a sliding glass door, with with two glass panes that each cover 50% of the frame. on will move, the other will not if I understand correctly you want to a) resize/move the frame and have that information passed to the glass panes, so that they resize/move to match, and b) have that information update to allow the panes to move the correct amount in relation to the frame.

for this example, the frame may be rotated to to any odd angle, and may or may not be linked to a larger structure.

as a build trick, the moving glass pane will be aligned to the exact same rotation as the frame. in our case we'll use a hollowed cube, and the moving pane will be flattened along the z axis, and will cover half of the x axis on the -x side at closed.

from the frame prim we already know what the glass prims rotation should be (they match) and we can tell what the size should be (because it will be a percentage of our frame size), and it's position (because it'll be relative to our center, minus half the moving panes size)

we also know that the open position will be that same percentage, but plus the offset from our frame center on the x axis.

since we can calculate all the information for the pane, from the frame, we only need to get information for the frame... in this case, size, position, and rotation.

llGetScale will tell us our size linked or not

llGetLocalPos will get our position... either relative to the root, if linked, or region if not (just for safety)

llGetLocalRot will get our rotation, again safely relative to region or root.

the reasoning for getting pos/rot relative to the nearest frame of reference is to only have to deal with one level of coordinate frames, instead of two possible ones which would have to be handled differently. in this case it will treat root local frame as being the same as region local. (if I didn't make sense, just go with it, it works)

for the frame assume a hollow of 90% and a prim size of x=2m, y=1m, (z doesn't really matter, it'll probably be small)

gBooOpen = FALSE;

frameRot = llGetLocalRot();
frameSize = llGetScale();
framePos = llGetLocalPos();
paneRot = frameRot;
paneSize = frameSize * 0.9;
panePosLocal = < 0.5 * paneSize, 0.0, 0.0 > * frameRot;
gBooOpen = !gBooOpen;
panePosLocalNext = panePosLocal * (-gBooOpen | 1); //trick to get -1 or +1 from a boolean switch
PanePosRelativeNext = framePos - panePosLocalNext;

llSetLinkPrimitiveParams(
paneLinkNumber,
[PRIM_ROTATION, paneRot,
PRIM_SCALE, paneSize,
PRIM_POSITION, PanePosRelativeNext] );

or all together...

CODE

llSetLinkPrimitiveParams(
paneLinkNumber,
[PRIM_ROTATION, llGetLocalRot(),
PRIM_SCALE, llGetScale() * 0.9,
PRIM_POSITION, llGetLocalPos() -
(< 0.5 * llGetScale() * 0.9, 0.0, 0.0 > * llGetLocalRot()) *
(-(gBooOpen = !gBooOpen) | 1)] );


as for why the muliplication by the rotation is needed? it takes the region direction of the offset, and rotates it to match the local facing of the prim. if you take a plain cube, and rotate it 90deg clockwise from the top, it's +x axis now faces south. if you want a point that's 1m forward from that face, you take < 1, 0, 0 > which would be 1m +x when it's not rotated, and multiply it by the current rotation to swing that point around, and then add it to the position of the prim and you'll find the position is 1m south, but perfectly 1m along the prims +x axis.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
08-02-2009 07:05
Void, Thank you very much for taking the time to think on this and give me such a useful and informative reply. I'm going in-world now to see if what you posted can help me to improve on the solution I finally managed to reach on my own yesterday mid-afternoon. I hadn't checked back in the forums between then and now, as I had company over in RL right after I hit on my solution. But I think your method may point the way to an improvement, as mine still ended up making the move of the door to the frame's location a two-step process - first to get the door to the frame's exact center, and then to move the door relative to itself to the closed position. From there, operation between open and closed only took a single action, using info worked up from the earlier discussions.

I'll post a simplified version of the final script here in a bit, so others can also learn and benefit from the discussion.
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
VonGklugelstein Alter
Bedah Profeshinal Tekstur
Join date: 22 Dec 2007
Posts: 808
08-14-2009 10:29
... n/m
_____________________