User:Void Singer/Rotations

From Second Life Wiki
Jump to navigation Jump to search

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.