Jump to content

Reading and Setting link position and rotation


Innula Zenovka
 Share

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

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

Recommended Posts

I'm still reeling from the discovery that all the examples of how to do this seem to have been mangled while being archived.

Anyway, I'm at my wits' end.   I've looked out some scripts I have used in the past to read and set link primitive params using PRIM_ROT_LOCAL, and, while they certainly worked with the stuff I made, I can't get them to work now with something I'm making -- possibly because there's something I didn't need to correct for in the previous builds but I do now, like an oddly aligned root prim or some such.

What I'm using to read the parameters into lists is:

 

integer max;
integer i;
default
{
    state_entry()
    {
      // llSay(0, "Hello, Avatar!");
    }

    touch_start(integer total_number)
    {
       max = llGetNumberOfPrims();
       llOwnerSay((string)max);
       i=2;
       vector r = llGetRootPosition();
       do{
           list l = llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_ROT_LOCAL]);
           vector v = (llList2Vector(l,0)-r)/llGetRootRotation();
           rotation rot = llList2Rot(l,1);
           llOwnerSay((string)i+","+(string)v+","+(string)rot+",");
        }
        while(++i<=max);
    }
}

That, I think, is giving me the offset from the root prim, corrected for the root rotation.

Then I'm trying to set the positions with variations on the theme of 

 

    touch_start(integer total_number)
    {
       toggle=!toggle;
       if(toggle){
           my_list=a;
        }
        else {
          my_list=b;
        }
        integer max=llGetListLength(my_list);
        while(max--){
            if(max%3==0){
            integer i = llList2Integer(my_list,max);
      // vector vPosLcl = (llList2Vector( llGetLinkPrimitiveParams( i, [PRIM_POSITION] ), 0 ) - llGetPos()) / llGetRot();

rotation vRotLcl = llList2Rot( llGetLinkPrimitiveParams( i, [PRIM_ROT_LOCAL] ), 0 );
//-- Sets on PRIM_POS are local to the next highest frame of reference //-- that means child relative to root, and root relative to region.
llSetLinkPrimitiveParamsFast( i, [PRIM_POSITION, llList2Vector(my_list,1),PRIM_ROT_LOCAL,llList2Rot(my_list,2)] );
//-- local pos + (local offset * local rot) == local relative change in position
                
            }                     
        }
    }

 

and it's going all over the place.   It's a flat-screen TV,  swivelling round on a table, so it doesn't get much change to move out of position (though I think it is) but the rotations of the component prims are clearly off.  I've tried multiplying and dividing by every permutation of llGetRootRotation() and vRotLcl I can think of, but either I've read it wrong in the first place or there's something I'm missing when I'm setting stuff.

Can anyone please show where I'm going wrong?

 

Link to comment
Share on other sites

Assuming that I understand correctly, you want to rotate all the child prims around the root, i.e. relatively to it. So, just do it! :P

In other words, have a rotation and apply it. For example:

rotation swivel = llEuler2Rot(<0.0, 0.0, PI/4.0>); // 45° on Z axis

And then:

integer i = (my_list != []); // Faster llGetListLength()
while (i >= 3)
{
    i -= 3;
    llSetLinkPrimitiveParamsFast(llList2Integer(my_list, i),
                                [PRIM_POSITION, llList2Vector(my_list, i + 1) * swivel,
                                PRIM_ROT_LOCAL, swivel * llList2Rot(my_list, i + 2)]);
}


That should do it.

 

Link to comment
Share on other sites

I can't wait until PRIM_POS_LOCAL gets done (it's being worked on YAY)

the formula for local position of a child is

vPosChild = (region_child_pos - region_root_pos) / root_rot

to rotate that around the root, simply multply the result but the rotation you want to add to it. multiply the rotation by the child local rot if you want to keep the same side facing the root.

if you want to rotate around an arbitrary position, subtract the root relative offset to that point from the childs local position before multiplying, and then add if back in after.

Link to comment
Share on other sites

Thanks, both.   I'm rotating round an arbitrary point -- what was the root of the TV set before I linked it to the rest of the build -- and that's where I'm going wrong, I see, and why my original formular worked for my stuff but not for this.

Let me try to understand what I need to do, though, in setting the new position.  I think I've got the two offsets read correctly -- that is, I know the prim's offset from the root in the old position and in the position it's going to.

So I subtract the old offset from the new one (I think) -- and then what what do I do?  

I've got the old PRIM_ROT_LOCAL and the new one.   I can read PRIM_ROTATION and llGetRootRotation and so on, of course, but I'm really not sure where I go to from here.   

The actual build is, as I said, a TV set that started off as a free-standing unit.   It's now part of a larger build, and the idea is that it should swivel round through 180 degrees on what used to be its vertical axis so you can watch TV from the bed or a  couch on the other side of the room.   

Link to comment
Share on other sites


Void Singer wrote:

((local_pos_child - local_pos_old_root) * rotation) + local_pos_old_root

Thanks.  What, though, does "rotation" represent there?    At the moment I know the old and new values for PRIM_ROT_LOCAL and I can read various values at run-time.   Which do I need?  Or should I have recorded/calculated something else?    

Sorry to be so obtuse but I'm a bit unclear what I'm doing, maybe because the position values I've recorded are (PRIM_POSITION - llGetRootPosition())/llGetRootRotation(), and I'm now not quite sure if that's what I should have done.

 

 

Link to comment
Share on other sites

rotation in that formula would be the arc-segment to move..... for instance, if you wanted it to be 10deg more around the pivot point, you'd use a rotation that described 10deg off of zero rotation in your desired direction/axis....

or in other words, the arc of the circle between the old position and the new, centered on your old root prim... basically how wide a slice of pie to cut.

Link to comment
Share on other sites

I think I see.   I don't actually want to move the component elements at all relative to the old root, just swivel everything through 180 degrees.   So, does this mean I use the new local position relative to the new root prim (which I've already read and recorded), subtract their positions relative to the root prim of the TV set when it was a freestanding unit at ZERO_ROTATION (so nothing to subject in the case of the old root prim, now a child prim in the new build), multiply that by 180 degrees, and then add back in the numbers I've just subtracted?

That is, the one piece of the puzzle I'm missing at the moment is the positions of the TV set prims relative to the root prim of the TV set when it was just a TV set rather than something linked to larger build?

 

Link to comment
Share on other sites

ok, I've read that twice now, and I'm still officially confused.

C^|B <-- A|vD

A = actual root region position {regionPosA}
B = swivel point (orbit center, locally offset from A).{precalculated, (regionPosB - regionPosA) / regionRotA}
C = orbiting child prim current local position. {(regionPosC - regionPosA) / regionRotA}
D = orbiting child prim local position after rotation (required for llSetLinkPrimitiveParams)
rotArc = llEuler2Rot( <0.0, 0.0, 180> * DEG_TO_RAD ); //-- 180deg orbit

D = (C - B) * rotArc + B

if the same side of C should be facing B when moved to position D, also use:
localRotD = rotArc * localRotC;

if you use a smaller rotation, like 90 for rotArc, the position of D would be on the opposite side of B from A (it'd' be a straight line reading D,B,A) and you could apply the same formula twice to get from the above displayed C to D.

 

Link to comment
Share on other sites

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