You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.
This shows you the differences between two versions of the page.
user:sei:roll_pitch_yaw [2015-07-31 09:59 SLT] sei created |
user:sei:roll_pitch_yaw [2017-08-17 08:30 SLT] (current) sei note the order applies to extrinsic rotations |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | Since this seems to be a FAQ, here is a function to return classic roll/pitch/yaw (as used by planes, for example). $lfn[llRot2Euler] can't be used because classic roll/pitch/yaw requires XYZ rotation order, and SL uses ZYX rotation order. | + | Since this seems to be a FAQ, here is a function to return classic roll/pitch/yaw (nautical angles). $lfn[llRot2Euler] can't be used because classic roll/pitch/yaw requires (extrinsic) XYZ rotation order, and SL uses ZYX rotation order. |
<code lsl2> | <code lsl2> | ||
vector Rot2EulerXYZ(rotation rot) | vector Rot2EulerXYZ(rotation rot) | ||
{ | { | ||
- | return <llAtan2(2*(rot.s*rot.x + rot.y*rot.z), 1 - 2*(rot.x*rot.x + rot.y*rot.y)), | + | return <llAtan2((rot.s*rot.x + rot.y*rot.z), 0.5 - (rot.x*rot.x + rot.y*rot.y)), |
llAsin (2*(rot.s*rot.y - rot.x*rot.z)), | llAsin (2*(rot.s*rot.y - rot.x*rot.z)), | ||
- | llAtan2(2*(rot.s*rot.z + rot.x*rot.y), 1 - 2*(rot.y*rot.y + rot.z*rot.z))>; | + | llAtan2((rot.s*rot.z + rot.x*rot.y), 0.5 - (rot.y*rot.y + rot.z*rot.z))>; |
} | } | ||
</code> | </code> | ||
- | It assumes SL avatar coordinate conventions (X=forward, Y=left, Z=up). The output vector has components output.x=roll, output.y=pitch, output.z=yaw. | + | It assumes SL avatar coordinate conventions (X=forward, Y=left, Z=up). Unlike LSL functions, it also assumes the input rotation is normalized. The //x// component of the returned vector is roll (bank), the //y// component is pitch (elevation), and the //z// component is yaw (heading). |
- | The following is another version, perhaps easier to remember but less precise (rotations are not normalized to save memory): | + | The following is another version, perhaps easier to remember and to inline but less precise (rotations are not normalized to save memory under Mono, but that doesn't change the result): |
<code lsl2> | <code lsl2> | ||
vector Rot2EulerXYZ(rotation rot) | vector Rot2EulerXYZ(rotation rot) | ||
Line 29: | Line 29: | ||
} | } | ||
</code> | </code> | ||
- | and one symmetrical to the alternative above (needs normalized rotations though): | + | and one symmetrical to the alternative above but also less precise (returns a normalized rotation): |
<code lsl2> | <code lsl2> | ||
rotation EulerXYZ2Rot(vector euler) | rotation EulerXYZ2Rot(vector euler) |