Jump to content

Getting the z orientation of an object at any arbitrary rotation


Phate Shepherd
 Share

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

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

Recommended Posts

I recall seeing this asked before, but I can't find it again. I'm trying to get just the z rotation of an object that is in any given orientation. Imagine a prim avatar that could be in any orientation, I want to be able to have a prim that always faces forward, ignoring the avatars tilt forward/back, or twist side to side.

I tried the obvious of:

vector rot = llRot2Euler(llGetRot());

rotation just_z = llEuler2Rot(<0 ,0, rot.z>);

But that only sort of works, and if I recall, that was one of the methods tried in the other post that I can't find. I'm figuring there is some llRot2Forward stuff involved, but I am just drawing a blank.

Link to comment
Share on other sites

FOr cases in which you have one rotation (the current rotation of the object) and you want to transform that rotation, keeping one of the axes the same (lets say, let z always be what it was) I've landed on swapping around cross products as being the most correct solution.

This will try and align the X-axis of the prim with the X-axis of the world, keeping the Z-axis unchanged:

default
{   state_entry()
    {   llSetTimerEvent(0.5);
    }
    timer()
    {   rotation rot = llGetRot();
        vector X = <1,0,0>; // we want to face forward.
        vector Z = <0,0,1>*rot; // Up stays constant.
        vector Y = Z%X; // so find left,
               X = Y%Z; // forward might actually be a bit up or down
        rotation rot2 = llAxes2Rot(X,Y,Z);
        llSetRot(rot2);
        // for demonstration, say what the angle was we changed by:
        float diff = llRot2Angle(rot2/rot);
        if(diff>0.01) llOwnerSay((string)(RAD_TO_DEG*diff));
    }
}

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

I had asked on Builders Brewery and after thinking nobody was around I posted here... and then Lucia and Xan offered their solutions too....

Xan

 vector pos = llGetPos();
 vector tgt = pos + <1, 0, 0> * llGetRot();
 rotation heading = llRotBetween(<1.0, 0.0, 0.0>, llVecNorm(<tgt.x - pos.x, tgt.y - pos.y, 0>));
 // I then used the heading to set the rotation of the child prim by subtracting the root rot:  heading / llGetRootRot()

Lucia

integer link = llGetLinkNumber();
vector r2f = llRot2Fwd(llGetRot());
llSetLinkPrimitiveParamsFast(link,[PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,llAtan2(r2f.y,r2f.x)>) / llList2Rot([llGetRootRotation(),ZERO_ROTATION],link < 2)]);

Now I'm off to see how Quistess's works. Thanks all!

Edited by Phate Shepherd
  • Thanks 1
Link to comment
Share on other sites

4 hours ago, Phate Shepherd said:

I had asked on Builders Brewery and after thinking nobody was around I post here... and then Lucia and Xan offered their solutions too....

Lucia

 vector pos = llGetPos();
 vector tgt = pos + <1, 0, 0> * llGetRot();
 rotation heading = llRotBetween(<1.0, 0.0, 0.0>, llVecNorm(<tgt.x - pos.x, tgt.y - pos.y, 0>));
 // I then used the heading to set the rotation of the child prim by subtracting the root rot:  heading / llGetRootRot()

Xan

integer link = llGetLinkNumber();
vector r2f = llRot2Fwd(llGetRot());
llSetLinkPrimitiveParamsFast(link,[PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,llAtan2(r2f.y,r2f.x)>) / llList2Rot([llGetRootRotation(),ZERO_ROTATION],link < 2)]);

Now I'm off to see how Quistess's works. Thanks all!

You have those names reversed, btw. 😉

Xan's was probably better. I pulled my example from an old test object I made and I think my reasoning for not using llRotBetween was due to bugs.

  • Haha 1
Link to comment
Share on other sites

1 hour ago, Lucia Nightfire said:

You have those names reversed, btw. 😉

Xan's was probably better. I pulled my example from an old test object I made and I think my reasoning for not using llRotBetween was due to bugs.

Ooops... thanks. Edited it.

I'm still playing around with it. My use case is a little odd and in the end it is a bit overkill to worry about... but hey, we like a challenge. Looking over everyones solutions, I started to mess around with yet another way to do what I want.

rotation    heading;
vector      t  = <1, 0,  0>;
vector      v1 = <1, 0,  0> * llGetRootRotation();
vector      v2 = <0, 0, -1> * llGetRootRotation();
        
if (llVecDist(<v2.x, v2.y, 0>, ZERO_VECTOR) < .1) heading = llRotBetween(t, <v1.x, v1.y, 0>);
else  heading = llRotBetween(t, <v2.x, v2.y, 0>);

Now I have to look at the jira to see if that will blow up.

Edited by Phate Shepherd
Inverted one vector for clarity
Link to comment
Share on other sites

9 minutes ago, Phate Shepherd said:

another way to do what I want

I'm still a bit in the dark as what it actually is you're trying to do. Trying a bunch of things and hammering on it until it "looks right" is fine in some cases, and I know I've done just that on occasion, but more often than not, it's more productive to figure out a technically exact definition of what you expect the result to be, perhaps working out some example inputs and expected outputs by hand, before throwing a bunch of different methods at it and seeing what sticks. When you have a specification laid out, it's a lot easier to go back and examine why function X didn't give output Y.

  • Like 2
Link to comment
Share on other sites

21 minutes ago, Quistess Alpha said:

I'm still a bit in the dark as what it actually is you're trying to do. Trying a bunch of things and hammering on it until it "looks right" is fine in some cases, and I know I've done just that on occasion, but more often than not, it's more productive to figure out a technically exact definition of what you expect the result to be, perhaps working out some example inputs and expected outputs by hand, before throwing a bunch of different methods at it and seeing what sticks. When you have a specification laid out, it's a lot easier to go back and examine why function X didn't give output Y.

I agree. The issue was I was having a really tough time putting into words exactly what I wanted it to do. When I tried on BB, I think I just created even more confusion. Seeing the various solutions helped me to grasp better how to go about it, but it still doesn't help with my limited math vocab to explain what I was going for. So it wasn't so much trying random things until it works, it was more about seeing different ways to approach the problem that I was then able to attack it.

In the end, I realized that what I wanted was a rotation that pointed in the same direction on the XY plane as the up vector if the object is tilted at all. If the object is not tilted, then I use the rotation of the forward vector on the XY plane. (Z is zeroed out in all rotated vectors used).

Edited by Phate Shepherd
  • Like 1
Link to comment
Share on other sites

3 minutes ago, Phate Shepherd said:

In the end, I realized that what I wanted was a rotation that pointed in the same direction on the XY plane as the up vector if the object is tilted at all. If the object is not tilted, then I use the rotation of the forward vector on the XY plane. (Z is zeroed out in all vectors used).

vector rot2Zdir(rotation r)
{   vector up = <0,0,1>*rot;
    if(up.z>0.99) // allow for a little error.
    {	vector fwd = <1,0,0>*rot;
     	fwd.z = 0;
     	return llVecNorm(fwd);
    }else
    {	up.z=0;
        return llVecNorm(up);
    }
}

  • Like 1
Link to comment
Share on other sites

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