Difference between revisions of "User:Void Singer/Rotations"

From Second Life Wiki
Jump to navigation Jump to search
m (typos)
Line 1: Line 1:
{{RightToc}}
<div id="box">
<div id="box">
<h2> Common Rotation Tasks Simplified </h2>
== Common Rotation Tasks Simplified ==
<div style="padding: 0.5em">
<div style="padding: 0.5em">
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...
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...
* forward rotation vs reverse rotation
 
** same as counter-clockwise vs clockwise (viewed from the positive end of the axis)
 
** same as left turn vs right turn (viewed as if standing in the axis w/ head at positive end)
----
<pre> //-- 2 ways to reverse rotation
== Converting Degrees to Rotations (and back) ==
  //-- use negative numbers in original variable, good for rotation that won't change
* Convert Vector Degrees to a Rotation for ease of use
vector   vgVecLeftRotation = <.0, .0, 90.0>; //-- left 90 degrees around z-axis
* Convert a Rotation to Vector Degrees for ease of reading
vector   vgVecRightRotation = <.0, .0, -90.0>; //-- right 90 degrees around z-axis
<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( vDeg90z * 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
  //-- use quaternion inversion, good for rotations that will reverse dynamically
vector  vgVecDegreesRotation = <.0, .0, 90>; //-- left 90 degrees around the z-axis
vector  vDeg90 = <.0, .0, 90>; //-- left 90 degrees around the z-axis
rotation vgRotConvertedDegrees = llEuler2Rot( vgVecDegreeRotation * DEG_TO_RAD ); //-- still left
rotation vRot90 = llEuler2Rot( vRot90 * DEG_TO_RAD ); //-- still left
vgRotConvertedDegrees.s *= -1; //-- reverses the rotation direction each time called</pre>
vRot90.s *= -1; //-- reverses the rotation direction each time called</lsl>
* rotating in global axis vs local
 
** Global axis is the world, up, down, north, east, south, west
 
** Local axis is the object, top, bottom, left-side, right-side, front-side, back-side.. imagine writing on a cardboard box
----
<pre> //-- to rotate around the global axis (think stationary carousel)
== Rotating in Global or Local axis==
llSetRot( llGetLocalRot() * vgRotConvertedDegrees );
* 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
  //-- to rotate around the local axis (think spinning tilted top) just reverse the order
llSetRot( vgRotConvertedDegrees * llGetRot() );</pre>
llSetRot( vRot90z * llGetRot() );</lsl>
* roatating a given point to match objects position/rotation
 
** Do this to find where a point is in relation to an object (good for rezzors)
 
** for instance if you want to know the point 1m from the top of an object, and 2m right..
----
<pre>vector vVecOffset = <2.0, .0, 1.0>;
== Rotating an offset point to match objects position/rotation ==
  //-- even after rotating your object this will give the point in relation to it's new rotation
* Do this to find where a point is in relation to an object (good for rezzors)
vector vVecCurrentOffset = llGetPos() + vVecOffset * llGetLocalRot();</pre>
* Imagine a ball at the end of an invisible stick attached to a box
* rotatating an objects POSITION around a given offset point
<lsl>vector vPosOffset = <2.0, .0, .0>; //-- two meters from object "top"
** same idea as planets orbiting the sun
  //-- even after rotating your object this will give the point in relation to the object's new rotation
<pre>vector vVecOffset = <.0, .0, 1.0>; //-- the point we are rotating around in relation to our object
vector vPosCurrentOffset = llGetPos() + vPosOffset * llGetLocalRot();</lsl>
vector  vgVecArc = <.0, .0, 60.0>; //-- how far around the circle to travel each move
 
rotation vgRotArc = llEuler2Rot( vgVecArc * DEG_TO_RAD );
 
----
== 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
  //-- notice you have to move AND rotate, or else the new
  //-- position becomes a diagonal line instead of a circle
  //-- position becomes a diagonal line instead of a circle
llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vVecOffset - vVecOffset * vRotArc) * llGetLocalRot(),
llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vPosOffset - vPosOffset * vRotArc) * llGetLocalRot(),
                       PRIM_ROTATION, vRotArc * llGetLocalRot] );</pre>
                       PRIM_ROTATION, vRotArc * llGetLocalRot()] );
* Warnings:
 
** do NOT use rotation division to reverse direction
//-- Method 2: Track Rotation around the point
** llSetPrimitiveParams & llSetRot do not work correctly for rotations in child prims
//-- object itself does not rotate, only it's position around the point
  //-- this might work in some cases, but fails in most, so don't use it!
llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vPosOffset - vPosOffset * vRotArc) * vRotTrack );
  llSetRot( llGetRot() / vgRotConvertedDegrees  );
vRotTrack = vRotArc * vRotTrack;</lsl>
  //-- this works in a child prim
 
llSetLocalRot( vgRotConvertedDegrees  * llGetLocalRot() );
 
  //-- these work incorrectly in child prims
----
llSetRot( vgRotConvertedDegrees * llGetLocalRot() );
== Warnings: ==
llSetPrimitiveParams( [PRIM_ROTATION, vgRotConvertedDegrees * llGetLocalRot()] );
* Do NOT use division to reverse rotation direction
  //-- presumably this works incorrectly as well
* llSetPrimitiveParams & llSetRot do not work correctly for rotations in child prims.
llSetLinkPrimitiveParams( 2, [PRIM_ROTATION, vgRotConvertedDegrees * llGetLocalRot()] );
** see jira article [http://jira.secondlife.com/browse/SVC-93 SVC-93] for details & a workaround if you need to use them in a child prim.
  //-- see jira article [http://jira.secondlife.com/browse/SVC-93 SVC-93] for details + a workaround if you need to use llSetPrimitiveParams
<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>
</div></div>
</div></div>


<div id="box">
<div id="box">
 
== Comments ==
<h2> Comments </h2>
<div style="padding: 0.5em">
<div style="padding: 0.5em">
Feel free to leave me a note on my [[User_talk:Void_Singer|User Talk]] page.
Feel free to leave me a note on my [[User_talk:Void_Singer|User Talk]] page.
</div></div>
</div></div>

Revision as of 21:08, 31 March 2009

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( vDeg90z * 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.