Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Extract just the Z-axis component of a rotation

Jack Abraham
Lantern By Day
Join date: 11 Apr 2008
Posts: 113
12-27-2008 10:58
I'm trying to work out a way to extract just the Z-axis component of a rotation without converting to Euler notation and back. Unfortunately, I can't seem to wrap my head around quaternions. Can anybody help me out here?
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
12-27-2008 11:21
My guess is you don't want what you are asking:)
The Z-component is an Euler thing and that you don't want.
What is it for?
_____________________
From Studio Dora
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
12-27-2008 11:30
quaternions do not work that way.

use rot2eiler(euler2rot())
OR
use a ton of sine and cosine transformations, but noone knows how, wikipedia is complicated on that one
OR
create a vector, rotate it by the roration, and compare the rotated vector with the unrotated and do something with that.

see, it just gets worse.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-27-2008 11:42
I guess the real question is what you mean by the "z-axis component". Euler angles are very artificial and have very little to do with the actual physical rotation. They're just a way to GET to that rotation, not a construct that is physically meaningful.

Now if you want something like, "If I project the local x-axis onto the global xy-plane, where does it point relative to the gobal x-axis," then that is definitely answerable. It is pretty much the equivalent to "Which direction am I facing?" You don't have to know much about quaternions to answer the question, either:

CODE

// Returns a right-hand angle indicating the direction we are facing relative
// to the global x-axis, in radians.
float getFacing(rotation rot)
{
vector fwd = llRot2Fwd(rot);
if (1.0-fwd.z < 0.001)
{
// we're looking straight up, so do the intuitive thing and base
// the answer on which way our "down" is pointing (if we pitched down
// to horizontal, that's the direction we'd be facing).

vector down = -llRot2Up(rot);

return llAtan2(down.y, down.x);
} else
{
return llAtan2(fwd.y, fwd.x);
}
}

// Returns a right-hand angle indicating the direction we are facing relative
// to the global x-axis, in degrees.
float getFacingInDeg(rotation rot)
{
return llGetFacing(rot)*RAD_TO_DEG;
}
Jack Abraham
Lantern By Day
Join date: 11 Apr 2008
Posts: 113
12-27-2008 11:47
What I'm after is to take the avatar's rotation in mouselook, and rez an object facing in the same NSEW direction but level (FREX, a chair that's not tilted up or sideways, but has its seat facing toward the avatar in the horizontal plane).
Jack Abraham
Lantern By Day
Join date: 11 Apr 2008
Posts: 113
12-27-2008 11:50
Hewee, thanks; I think that's what I was asking for, but in my experience llAtan2 has the same problem llRot2Euler has, e.g. it's rather slow. I was trying to avoid the llRot2Euler transformations Ollj outlined for performance reasons, but looks like I'll have to have them.

Thanks all.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-27-2008 12:01
From: Jack Abraham
What I'm after is to take the avatar's rotation in mouselook, and rez an object facing in the same NSEW direction but level (FREX, a chair that's not tilted up or sideways, but has its seat facing toward the avatar in the horizontal plane).


Ah. Okay. That's a pretty similar problem. Notice how close it looks to the above:

CODE

// Returns a rotation for an orientation facing "in the same direction"
// horizontally as the argument, but with the local and global z axes aligned.
rotation getLeveledRot(rotation rot)
{
vector resultFwd;
vector resultLeft;

vector fwd = llRot2Fwd(rot);
if (1.0-fwd.z < 0.001)
{
// we're looking straight up, so do the intuitive thing and base
// the answer on which way our "down" is pointing (if we pitched down
// to horizontal, that's the direction we'd be facing).

vector left = llRot2Left(rot);
resultLeft = llVecNorm(<left.x, left.y, 0.0>);
resultFwd = <resultLeft.y, -resultLeft.x, 0.0>; // resultLeft % <0,0,1>
} else
{
resultFwd = llVecNorm(<fwd.x, fwd.y, 0.0>);
resultLeft = <-resultFwd.y, resultFwd.x, 0.0>; // <0,0,1> % resultFwd
}

return llAxes2Rot(resultFwd, resultLeft, <0.0, 0.0, 1.0>);
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
12-27-2008 12:04
From: Jack Abraham
Hewee, thanks; I think that's what I was asking for, but in my experience llAtan2 has the same problem llRot2Euler has, e.g. it's rather slow. I was trying to avoid the llRot2Euler transformations Ollj outlined for performance reasons, but looks like I'll have to have them.

Thanks all.

Oh. Okay. Then your answer simply becomes, "Compile to Mono, which performs mathematical operations very quickly (about as fast as you'll need for anything done in LSL)."