Difference between revisions of "User:Void Singer/Rotations"
Void Singer (talk | contribs) m (typos) |
Void Singer (talk | contribs) |
||
Line 1: | Line 1: | ||
{{RightToc}} | |||
<div id="box"> | <div id="box"> | ||
== 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... | ||
* | |||
---- | |||
< | == Converting Degrees to Rotations (and back) == | ||
//-- use negative numbers in original variable, good for | * Convert Vector Degrees to a Rotation for ease of use | ||
vector | * Convert a Rotation to Vector Degrees for ease of reading | ||
vector | <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 | vector vDeg90 = <.0, .0, 90>; //-- left 90 degrees around the z-axis | ||
rotation | 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== | ||
llSetRot( llGetLocalRot() * | * 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( | llSetRot( vRot90z * llGetRot() );</lsl> | ||
* | ---- | ||
< | == Rotating an offset point to match objects position/rotation == | ||
//-- even after rotating your object this will give the point in relation to | * Do this to find where a point is in relation to an object (good for rezzors) | ||
vector | * 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> | ||
vector | |||
rotation | |||
---- | |||
== 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() + ( | llSetPrimitiveParams( [PRIM_POSITION, llGetPos() + (vPosOffset - vPosOffset * vRotArc) * llGetLocalRot(), | ||
PRIM_ROTATION, 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 ); | |||
llSetRot( llGetRot() / vgRotConvertedDegrees ); | 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 [http://jira.secondlife.com/browse/SVC-93 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> | |||
</div></div> | </div></div> | ||
<div id="box"> | <div id="box"> | ||
== Comments == | |||
<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.