User:Void Singer/Rotations
Common Rotation Tasks Simplified
These are a few simplifications of common rotation tasks for those (like me) who get a bit glassy eyed and overwhelmed reading the 'official' version...
Converting Degrees to Rotations (and back)
- Convert Vector Degrees to a Rotation for ease of use
- Convert a Rotation to Vector Degrees for ease of reading
<lsl> //-- Degrees to Radians to a Rotation vector vDeg90z = <0.0, 0.0, 90.0>; Rotation vRot90z = llEuler2Rot( vDeg90z * DEG_TO_RAD );
//-- to convert back
vector vDegReadable = llRot2Euler( vRot90z ) * RAD_TO_DEG;
//-- note: some functions (like target omega) take or return Vectors in Radians //-- to convert those to Vector Degrees or a rotation, use the following
vector vDegReadable = vRadReturn * RAD_TO_DEG; rotation vRotUsable = llEuler2Rot( vRadReturn );</lsl>
Reversing a Rotations Direction
- same as counter-clockwise (CCW) vs clockwise (CW) as viewed from the positive end of the axis
- same as left turn vs right turn as viewed as if standing in the axis w/ head at positive end
<lsl> //-- 3 ways to reverse rotation
//-- use negative numbers in original variable, good for rotations that won't change
vector vDegLeft90 = <.0, .0, 90.0>; //-- CCW 90 degrees around z-axis vector vDegcRight90 = <.0, .0, -90.0>; //-- CW 90 degrees around z-axis
//-- or
vector vDegLeft90 = <.0, .0, 90.0> * -1; //-- CW 90 degrees around z-axis
//-- use Zero rotation Flipping, good for inline statements [ALWAYS remember to use parentheses]
vector vDeg90 = <.0, .0, 90>; //-- left 90 degrees around the z-axis rotation vRot90 = llEuler2Rot( vRot90 * DEG_TO_RAD ); //-- still left vRot90 = (ZERO_ROTATION / vRot90); //-- reverses the rotation direction each time called
//-- use quaternion inversion, good for rotations that will reverse dynamically
vector vDeg90 = <.0, .0, 90>; //-- left 90 degrees around the z-axis rotation vRot90 = llEuler2Rot( vRot90 * DEG_TO_RAD ); //-- still left vRot90.s *= -1; //-- reverses the rotation direction each time called</lsl>
Rotating in Global or Local axis
- Global axis is the Region: East(+X), West(-X). North(+Y). South(-Y), Up(+Z), Down(-Z).
- Local axis is the Object, Front-Side(+X), Back-Side(-X), Left-Side(+Y), Right-Side(-Y), Top(+Z), Bottom(-Z) [imagine writing on a cardboard box]
- Note: in LSL functions, forward = +X, left = +Y. Hence the only semi-intuitive direction names based on axis.
<lsl> //-- to rotate around the global axis (think stationary carousel) llSetRot( llGetLocalRot() * vRot90z );
//-- to rotate around the local axis (think spinning tilted top) just reverse the order
llSetRot( vRot90z * llGetRot() );</lsl>
Rotating an offset point to match objects position/rotation
- Do this to find where a point is in relation to an object (good for rezzors)
- Imagine a ball at the end of an invisible stick attached to a box
<lsl>vector vPosOffset = <2.0, .0, .0>; //-- two meters from object "top"
//-- even after rotating your object this will give the point in relation to the object's new rotation
vector vPosCurrentOffset = llGetPos() + vPosOffset * llGetLocalRot();</lsl>
Rotate an objects POSITION around a given offset point
- same idea as the Moon orbiting the Earth
<lsl>vector vPosOffset = <.0, .0, 1.0>; //-- the point we are rotating around in relation to our object vector vDegArc = <.0, .0, 60.0>; //-- how far around the circle to travel each move rotation vRotArc = llEuler2Rot( vDegArc * DEG_TO_RAD ); rotation vRotTrack; //-- optional, only used in method 2
//-- Method 1: Always keep same face toward the point //-- notice you have to move AND rotate, or else the new //-- position becomes a diagonal line instead of a circle
llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vPosOffset - vPosOffset * vRotArc) * llGetLocalRot(),
PRIM_ROTATION, vRotArc * llGetLocalRot()] );
//-- Method 2: Track Rotation around the point //-- object itself does not rotate, only it's position around the point
llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vPosOffset - vPosOffset * vRotArc) * vRotTrack ); vRotTrack = vRotArc * vRotTrack;</lsl>
Warnings:
- Do NOT use division to reverse rotation direction
- llSetPrimitiveParams & llSetRot do not work correctly for rotations in child prims.
- see jira article SVC-93 for details & a workaround if you need to use them in a child prim.
<lsl> //-- This only has the desired effect in global rotations,
//-- I STRONGLY suggest using one of the other methods regardless, to avoid confusion
llSetRot( llGetRot() / vgRotConvertedDegrees );
//-- this presumably works too, but again, I STRONGLY urge the alternative methods.
vector vPosReverseRotatedPoint = vPosOffsetPoint / vRot90z;
//-- this function works correctly in a child prims
llSetLocalRot( vgRotConvertedDegrees * llGetLocalRot() );
//-- these work incorrectly in child prims
llSetRot( vRot90z * llGetLocalRot() ); llSetPrimitiveParams( [PRIM_ROTATION, vRot90z * llGetLocalRot()] );
//-- presumably this works incorrectly as well
llSetLinkPrimitiveParams( 2, [PRIM_ROTATION, vRot90z * llGetLocalRot()] );</lsl>
Comments
Feel free to leave me a note on my User Talk page.