# Continuing Rotation Confusion

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

## Recommended Posts

Hi all.

Rotations are still doing my head in and more help is needed.

I'm trying to create an artificial horizon prim which stays horizontal for a boat which heels from side to side. I've read through the rotations page on the wiki and from that and help given here previously I had thought I could get it worked out but no such luck so far.

My thought is to use a timer script in the child prim, which has its orientation identical to the root prim, firstly to determine the global rotation using llGetRootRotation() and then pull out the rotation between the root prim at any angle of heel and its vertical equivalent using: llRotBetween( llRot2Up( llGetRootRotation()), < 0.0, 0.0, 1.0>  ) then apply that to the child prim with llSetRot to offset the root prim's heel angle. So far, with the linkset orientated to 0,0,0, the child prim takes the root's angle but adds to it instead of subtracting - so if the root heels 10deg the child rotates a further 10 deg instead of -10 deg. How to I combine the quaternion values to achieve a negative rotation rather than add to it? I've gone through trying division instead of multiplication and also changing the order of vectors to be calculated. I've also swapped minus signs in and out.

What's worse is when I rotate the linkset in the horizontal plane without any heel the childprim also rotates in the horizontal plane but by a different factor.

I am obviously not understanding something fundamental. Help!

Here's what I've been playing with to test it. There are lots of OwnerSays to try seeing if I can understand from the reported values what I need to do but a solution still eludes me.

```vector eulbow = <0.0, 0.0, 0.0>;

default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
llSetTimerEvent(5.0);
}

touch_start(integer total_number)
{
//        llOwnerSay("Local Rot2Up is: " + (string)llRot2Up(llGetLocalRot()));
//        llOwnerSay("Rot2Up is: " + (string)llRot2Up(llGetRot()));
}

timer()
{
rotation quat = llEuler2Rot(eulbow);
rotation RR = llGetRootRotation()*llRotBetween( llRot2Up( llGetRootRotation()), < 0.0, 0.0, 1.0>  );
llOwnerSay ("RR: "+(string)RR);
llOwnerSay ("RotBetween: "+(string)llRotBetween( <0.0, 0.0, 1.0>, llRot2Up(llGetRootRotation())));
llOwnerSay ("llGetRootRotation(): "+(string)llGetRootRotation());
llOwnerSay("GetRot: " + (string)llGetRot());

llSetRot(RR);
}
}```

Thanks for any assistance.

Carbon

##### Share on other sites

How about letting llLookAt, which works in both physical and non-physical prims, do the heavy lifting?

`default{    state_entry()    {        llSetTimerEvent(1.0);    }        timer(){        llLookAt(llGetPos()+<0.0,0.0,1.0>,1.0,0.1);    }}`

ETA  if you want to calculate it, I think this is how to do it:

`default{    state_entry()    {      llSetTimerEvent(1.0);    }        timer(){       vector vPos=llGetPos();       vector vTarget=llGetPos()+<1.0,0.0,0.0>*llGetRot();       llSetRot( llRotBetween(<1,0,0>,llVecNorm(<vTarget.x - vPos.x,vTarget.y - vPos.y,0>)));    }}`

##### Share on other sites

Thanks Innula.

I'm afraid those suggestions don't do what I'm after. I guess my description isn't clear. When I tried it on a test boat the first option turned the boat to face east and using the l/r keys wouldn't move it in any other direction, and the second option allowed only slight l/r movement and made the child prim rotate around its z axis in steps.

What I'm trying for is whatever the rotation around the x axis of the root prim (boat hull) as it heels, I want the child prim to rotate an equivalent amount around its x axis in the opposite direction so that its z axis remains pointing vertically - just like an artificial horizon guage in an aircraft.

You have however drawn my attention to other functions that I hadn't got around to considering so I will soldier on and pull some more hair out trying to get a solution.

Carbon

##### Share on other sites

something like this?...this should negate any rotaions made by the root, keeping your

horizon prim level?

put this in the root:.... child prim number is 2....

after you have rotated, get the new rotation and send the negative rotation to the child

rotation rot = llGetRot() ;
llSetLinkPrimitiveParamsFast( 2 , [PRIM_ROT_LOCAL, ZERO_ROTATION / rot ]);

ther is a page on rotaions here

http://wiki.secondlife.com/wiki/Rotation

##### Share on other sites

Thanks, Xiija.

That's certainly a lot closer to the solution I'm after. The child prim stays horizontal as required, but unfortunately it also seems to want to rotate to face 0,0,0 all the time, regardless of which direction the boat is facing. I'm hoping to get it to stay pointing towards the boat's bow but it's certainly a large advance on any of my previous attempts, so I'll go wrestle some more with the variables.

And yes, I've been at the Wiki page on rotations for what seems like an eternity now trying to understand it all.

Carbon